You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

152 lines
3.8 KiB

  1. package main
  2. import (
  3. "image/color"
  4. "io"
  5. "log"
  6. "os"
  7. "time"
  8. pigo "github.com/esimov/pigo/core"
  9. "github.com/fogleman/gg"
  10. "github.com/unixpickle/ffmpego"
  11. )
  12. var f *os.File
  13. var dc *gg.Context
  14. func videoFileFacetest(withOutput bool) {
  15. cascadeFile, err := os.ReadFile("./cascade/facefinder")
  16. if err != nil {
  17. log.Fatalf("Error reading the cascade file: %v", err)
  18. }
  19. vr, _ := ffmpego.NewVideoReaderResampled("face2.mp4", 30)
  20. e := os.Remove("cropped.mp4")
  21. if os.IsNotExist(e) {
  22. // handle the case where the file doesn't exist
  23. }
  24. vf, _ := ffmpego.NewVideoWriter("cropped.mp4", vr.VideoInfo().Width, vr.VideoInfo().Height, 1)
  25. var vw *ffmpego.VideoWriter
  26. if withOutput {
  27. e := os.Remove("output.mp4")
  28. if os.IsNotExist(e) {
  29. // handle the case where the file doesn't exist
  30. }
  31. vw, _ = ffmpego.NewVideoWriter("output.mp4", vr.VideoInfo().Width, vr.VideoInfo().Height, 30)
  32. }
  33. i := 0
  34. start := time.Now()
  35. for {
  36. i++
  37. frame, err := vr.ReadFrame()
  38. if err == io.EOF {
  39. break
  40. }
  41. pixels := pigo.RgbToGrayscale(frame)
  42. cols, rows := frame.Bounds().Max.X, frame.Bounds().Max.Y
  43. cParams := pigo.CascadeParams{
  44. MinSize: rows / 18,
  45. MaxSize: rows,
  46. ShiftFactor: 0.1,
  47. ScaleFactor: 1.5,
  48. ImageParams: pigo.ImageParams{
  49. Pixels: pixels,
  50. Rows: rows,
  51. Cols: cols,
  52. Dim: cols,
  53. },
  54. }
  55. pigoFunc := pigo.NewPigo()
  56. classifier, err := pigoFunc.Unpack(cascadeFile)
  57. if err != nil {
  58. log.Fatalf("Error reading the cascade file: %s", err)
  59. }
  60. angle := 0.0 // cascade rotation angle. 0.0 is 0 radians and 1.0 is 2*pi radians
  61. // Run the classifier over the obtained leaf nodes and return the detection results.
  62. // The result contains quadruplets representing the row, column, scale and detection score.
  63. dets := classifier.RunCascade(cParams, angle)
  64. // // Calculate the intersection over union (IoU) of two clusters.
  65. // print(len(dets))
  66. // print("_")
  67. // println(len(dets2))
  68. var qTresh float32
  69. qTresh = 6.5
  70. var qTresh2 float32
  71. qTresh2 = 10.0
  72. goodQ := []pigo.Detection{}
  73. for i := range dets {
  74. if dets[i].Q > qTresh {
  75. goodQ = append(goodQ, dets[i])
  76. }
  77. }
  78. if len(goodQ) > 0 {
  79. dets2 := classifier.ClusterDetections(goodQ, 0.1)
  80. if len(dets2) > 0 {
  81. foundFace := false
  82. if withOutput {
  83. dc = gg.NewContext(cols, rows)
  84. dc.DrawImage(frame, 0, 0)
  85. }
  86. for i := 0; i < len(dets2); i++ {
  87. if dets2[i].Q > qTresh2 {
  88. println("we got a winner here")
  89. foundFace = true
  90. //do somethng here
  91. //send cropped face to server
  92. // rgba := frame.(*image.RGBA)
  93. // cropped := rgba.SubImage(image.Rect(dets2[i].Col-dets2[i].Scale/2, dets2[i].Row-dets2[i].Scale/2, dets2[i].Scale, dets2[i].Scale))
  94. // file, _ := os.Create(fmt.Sprintf(" %d.jpg", i))
  95. // png.Encode(file, cropped)
  96. // cropped := imaging.Crop(frame, image.Rect(dets2[i].Col-dets2[i].Scale/2, dets2[i].Row-dets2[i].Scale/2, dets2[i].Scale, dets2[i].Scale))
  97. // dc = gg.NewContext(cropped.Rect.Dx(), cropped.Rect.Dy())
  98. // dc.DrawImage(cropped, 0, 0)
  99. // vf.WriteFrame(dc.Image())
  100. dc.SetMask(dc.AsMask())
  101. if withOutput {
  102. dc.DrawRectangle(
  103. float64(dets2[i].Col-dets2[i].Scale/2),
  104. float64(dets2[i].Row-dets2[i].Scale/2),
  105. float64(dets2[i].Scale),
  106. float64(dets2[i].Scale),
  107. )
  108. dc.SetLineWidth(float64(rows / 43))
  109. dc.SetStrokeStyle(gg.NewSolidPattern(color.RGBA{R: 255, G: 0, B: 0, A: 255}))
  110. dc.Stroke()
  111. dc.InvertMask()
  112. }
  113. }
  114. }
  115. if withOutput && foundFace {
  116. vw.WriteFrame(dc.Image())
  117. }
  118. }
  119. }
  120. log.Printf("Loop took %s", time.Since(start))
  121. }
  122. elapsed := time.Since(start)
  123. log.Printf("Loop took %s", elapsed)
  124. vr.Close()
  125. vf.Close()
  126. if withOutput {
  127. vw.Close()
  128. }
  129. return
  130. }
  131. func main() {
  132. videoFileFacetest(true)
  133. }