|
| 1 | +package examples |
| 2 | + |
| 3 | +import ( |
| 4 | + "fmt" |
| 5 | + "image" |
| 6 | + "image/color" |
| 7 | + "io" |
| 8 | + "log" |
| 9 | + |
| 10 | + ffmpeg "github.com/u2takey/ffmpeg-go" |
| 11 | + "gocv.io/x/gocv" |
| 12 | +) |
| 13 | + |
| 14 | +func readProcess(infileName string, writer io.WriteCloser) <-chan error { |
| 15 | + log.Println("Starting ffmpeg process1") |
| 16 | + done := make(chan error) |
| 17 | + go func() { |
| 18 | + err := ffmpeg.Input(infileName). |
| 19 | + Output("pipe:", |
| 20 | + ffmpeg.KwArgs{ |
| 21 | + "format": "rawvideo", "pix_fmt": "rgb24", |
| 22 | + }). |
| 23 | + WithOutput(writer). |
| 24 | + Run() |
| 25 | + log.Println("ffmpeg process1 done") |
| 26 | + _ = writer.Close() |
| 27 | + done <- err |
| 28 | + close(done) |
| 29 | + }() |
| 30 | + return done |
| 31 | +} |
| 32 | + |
| 33 | +func openCvProcess(xmlFile string, reader io.ReadCloser, w, h int) { |
| 34 | + // open display window |
| 35 | + window := gocv.NewWindow("Face Detect") |
| 36 | + defer window.Close() |
| 37 | + |
| 38 | + // color for the rect when faces detected |
| 39 | + blue := color.RGBA{0, 0, 255, 0} |
| 40 | + |
| 41 | + classifier := gocv.NewCascadeClassifier() |
| 42 | + defer classifier.Close() |
| 43 | + |
| 44 | + if !classifier.Load(xmlFile) { |
| 45 | + fmt.Printf("Error reading cascade file: %v\n", xmlFile) |
| 46 | + return |
| 47 | + } |
| 48 | + |
| 49 | + frameSize := w * h * 3 |
| 50 | + buf := make([]byte, frameSize, frameSize) |
| 51 | + for { |
| 52 | + n, err := io.ReadFull(reader, buf) |
| 53 | + if n == 0 || err == io.EOF { |
| 54 | + return |
| 55 | + } else if n != frameSize || err != nil { |
| 56 | + panic(fmt.Sprintf("read error: %d, %s", n, err)) |
| 57 | + } |
| 58 | + img, err := gocv.NewMatFromBytes(h, w, gocv.MatTypeCV8UC3, buf) |
| 59 | + if err != nil { |
| 60 | + fmt.Println("decode fail", err) |
| 61 | + } |
| 62 | + if img.Empty() { |
| 63 | + continue |
| 64 | + } |
| 65 | + |
| 66 | + // detect faces |
| 67 | + rects := classifier.DetectMultiScale(img) |
| 68 | + fmt.Printf("found %d faces\n", len(rects)) |
| 69 | + |
| 70 | + // draw a rectangle around each face on the original image, |
| 71 | + // along with text identifing as "Human" |
| 72 | + for _, r := range rects { |
| 73 | + gocv.Rectangle(&img, r, blue, 3) |
| 74 | + |
| 75 | + size := gocv.GetTextSize("Human", gocv.FontHersheyPlain, 1.2, 2) |
| 76 | + pt := image.Pt(r.Min.X+(r.Min.X/2)-(size.X/2), r.Min.Y-2) |
| 77 | + gocv.PutText(&img, "Human", pt, gocv.FontHersheyPlain, 1.2, blue, 2) |
| 78 | + } |
| 79 | + |
| 80 | + // show the image in the window, and wait 1 millisecond |
| 81 | + window.IMShow(img) |
| 82 | + if window.WaitKey(10) >= 0 { |
| 83 | + break |
| 84 | + } |
| 85 | + } |
| 86 | + return |
| 87 | +} |
| 88 | + |
| 89 | +func ExampleFaceDetection(inputFile, xmlFile string) { |
| 90 | + w, h := getVideoSize(inputFile) |
| 91 | + log.Println(w, h) |
| 92 | + |
| 93 | + pr1, pw1 := io.Pipe() |
| 94 | + done1 := readProcess(inputFile, pw1) |
| 95 | + openCvProcess(xmlFile, pr1, w, h) |
| 96 | + err := <-done1 |
| 97 | + if err != nil { |
| 98 | + panic(err) |
| 99 | + } |
| 100 | + log.Println("Done") |
| 101 | +} |
0 commit comments