ื‘ื ื™ื™ืช ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Golang ื•-OpenCV

ื‘ื ื™ื™ืช ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Golang ื•-OpenCV
OpenCV ื”ื™ื ืกืคืจื™ื™ื” ื”ืžื™ื•ืขื“ืช ืœืคืจื•ื™ืงื˜ื™ื ืฉืœ ืจืื™ื™ื” ืžืžื•ื—ืฉื‘ืช. ื”ื™ื ื›ื‘ืจ ื‘ืช 20 ื‘ืขืจืš. ื”ืฉืชืžืฉืชื™ ื‘ื• ื‘ืงื•ืœื’' ื•ืขื“ื™ื™ืŸ ืžืฉืชืžืฉ ื‘ื• ืขื‘ื•ืจ ืคืจื•ื™ืงื˜ื™ C++ ื•-Python ืฉืœื™ ื›ื™ ื™ืฉ ืœื• ืชืžื™ื›ื” ื˜ื•ื‘ื” ื‘ืฉืคื•ืช ืืœื•.

ืื‘ืœ ื›ืฉื”ืชื—ืœืชื™ ืœืœืžื•ื“ ื•ืœื”ืฉืชืžืฉ ื‘-Go, ื”ืชื—ืœืชื™ ืœื”ืชืขื ื™ื™ืŸ ืื ื ื™ืชืŸ ืœื”ืฉืชืžืฉ ื‘-OpenCV ื›ื“ื™ ืœืขื‘ื•ื“ ืขื ื”ืฉืคื” ื”ื–ื•. ื‘ืื•ืชื” ืชืงื•ืคื” ื›ื‘ืจ ื”ื™ื• ื“ื•ื’ืžืื•ืช ื•ื”ื“ืจื›ื•ืช ืขืœ ืื™ื ื˜ื’ืจืฆื™ื”, ืื‘ืœ ื ืจืื” ืœื™ ืฉื”ืŸ ืžืกื•ื‘ื›ื•ืช ืžื“ื™. ืงืฆืช ืžืื•ื—ืจ ื™ื•ืชืจ, ื ืชืงืœืชื™ ื‘ืขื˜ื™ืคื” ืฉื ื•ืฆืจื” ืขืœ ื™ื“ื™ ืฆื•ื•ืช The Hybrid Group. ื‘ืžืืžืจ ื–ื”, ืื ื™ ืืจืื” ืœืš ื›ื™ืฆื“ ืœื”ืชื—ื™ืœ ืขื GoCV ืขืœ ื™ื“ื™ ืคื™ืชื•ื— ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ืคืฉื•ื˜ื” ืขื Haar Cascades.

Skillbox ืžืžืœื™ืฆื”: ืงื•ืจืก ืžืขืฉื™ "ืžืคืชื— Python ืžืืคืก".

ืื ื• ืžื–ื›ื™ืจื™ื: ืœื›ืœ ืงื•ืจืื™ Habr - ื”ื ื—ื” ืฉืœ 10 ืจื•ื‘ืœ ื‘ืขืช ื”ืจืฉืžื” ืœื›ืœ ืงื•ืจืก Skillbox ื‘ืืžืฆืขื•ืช ืงื•ื“ ื”ื”ื˜ื‘ื” ืฉืœ Habr.

ืžื” ื ื“ืจืฉ:

  • ืœืœื›ืช;
  • OpenCV (ืงื™ืฉื•ืจื™ ื”ืชืงื ื” ืœืžื˜ื”);
  • ืื™ื ื˜ืจื ื˜ ืื• ืžืฆืœืžืช ื•ื™ื“ืื• ืจื’ื™ืœื”.

ื”ืชืงื ื”

ื“ื•ื’ืžื 1

ื‘ื“ื•ื’ืžื” ื”ืจืืฉื•ื ื”, ื ื ืกื” ืœื™ืฆื•ืจ ืืคืœื™ืงืฆื™ื” ืฉืคื•ืชื—ืช ื—ืœื•ืŸ ื”ืžืฆื™ื’ ื–ืจื ื•ื™ื“ืื• ืฉืœ ืžืฆืœืžื”.

ืจืืฉื™ืช ืขืœื™ืš ืœื™ื™ื‘ื ืืช ื”ืกืคืจื™ื•ืช ื”ื“ืจื•ืฉื•ืช ืœืขื‘ื•ื“ื”.

ื™ื™ื‘ื•ื โ€‹โ€‹(
"ืขึตืฅ"
"gocv.io/x/gocv"
)

ืœืื—ืจ ืžื›ืŸ, ืขืœื™ืš ืœื™ืฆื•ืจ ืื•ื‘ื™ื™ืงื˜ VideoCapture ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” VideoCaptureDevice. ื–ื” ื”ืื—ืจื•ืŸ ืžืืคืฉืจ ืœืฆืœื ื–ืจื ื•ื™ื“ืื• ื‘ืืžืฆืขื•ืช ืžืฆืœืžื”. ื”ืคื•ื ืงืฆื™ื” ืžืฉืชืžืฉืช ื‘ืžืกืคืจ ืฉืœื ื›ืคืจืžื˜ืจ (ื”ื™ื ืžื™ื™ืฆื’ืช ืืช ืžื–ื”ื” ื”ืžื›ืฉื™ืจ).

webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {    log.Fatalf(โ€œerror opening web cam: %vโ€, err)
}
defer webcam.Close()

ื›ืขืช ืขืœื™ื ื• ืœื™ืฆื•ืจ ืžื˜ืจื™ืฆื” โ€‹โ€‹ื -ืžืžื“ื™ืช. ื–ื” ื™ืื—ืกืŸ ืชืžื•ื ื•ืช ืฉื ืงืจืื• ืžื”ืžืฆืœืžื”.

img := gocv.NewMat()
defer img.Close()

ื›ื“ื™ ืœื”ืฆื™ื’ ื–ืจื ื•ื™ื“ืื•, ืขืœื™ืš ืœื™ืฆื•ืจ ื—ืœื•ืŸ - ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” NewWindow.

window := gocv.NewWindow(โ€œwebcamwindowโ€)
defer window.Close()

ื›ืขืช ื ืขื‘ื•ืจ ืœื—ืœืง ื”ืžืขื ื™ื™ืŸ ื‘ื™ื•ืชืจ.

ืžื›ื™ื•ื•ืŸ ืฉื•ื•ื™ื“ืื• ื”ื•ื ื–ืจื ืจืฆื™ืฃ ืฉืœ ืžืกื’ืจื•ืช ืชืžื•ื ื”, ื ืฆื˜ืจืš ืœื™ืฆื•ืจ ืœื•ืœืื” ืื™ื ืกื•ืคื™ืช ื›ื“ื™ ืœืงืจื•ื ืœืœื ืกื•ืฃ ืืช ื–ืจื ื”ื•ื•ื™ื“ืื• ืฉืœ ื”ืžืฆืœืžื”. ืœืฉื ื›ืš, ืืชื” ืฆืจื™ืš ืืช ืฉื™ื˜ืช ื”ืงืจื™ืื” ืžืกื•ื’ VideoCapture. ื”ื•ื ื™ืฆืคื” ืœืกื•ื’ Mat (ื”ืžื˜ืจื™ืงืก ืฉื™ืฆืจื ื• ืœืžืขืœื”), ืฉื™ื—ื–ื™ืจ ืขืจืš ื‘ื•ืœื™ืื ื™ ื”ืžืฆื™ื™ืŸ ืื ื”ืžืกื’ืจืช ืžื”-VideoCapture ื ืงืจืื” ื‘ื”ืฆืœื—ื” ืื• ืœื.

for {     
        if ok := webcam.Read(&img); !ok || img.Empty( {
        log.Println(โ€œUnable to read from the webcamโ€)    continue
     }
.
.
.
}

ื›ืขืช ืขืœื™ืš ืœื”ืฆื™ื’ ืืช ื”ืžืกื’ืจืช ื‘ื—ืœื•ืŸ ืฉื ื•ืฆืจ. ื”ื”ืฉื”ื™ื” ืœืžืขื‘ืจ ืœืคืจื™ื™ื ื”ื‘ื ื”ื™ื 50 ืืœืคื™ื•ืช ื”ืฉื ื™ื™ื”.

window.IMShow(img)
window.WaitKey(50)

ืœืื—ืจ ื”ืคืขืœืช ื”ืืคืœื™ืงืฆื™ื”, ื™ื™ืคืชื— ื—ืœื•ืŸ ืขื ื–ืจื ื•ื™ื“ืื• ืžื”ืžืฆืœืžื”.

ื‘ื ื™ื™ืช ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Golang ื•-OpenCV

package main
 
import (
"log"
 
"gocv.io/x/gocv"
)
 
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
    log.Fatalf("error opening device: %v", err)
}
defer webcam.Close()
 
img := gocv.NewMat()
defer img.Close()
 
window := gocv.NewWindow("webcamwindow")
defer window.Close()
 
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the webcam")
continue
}
 
window.IMShow(img)
window.WaitKey(50)
}
}

ื“ื•ื’ืžื 2

ื‘ื“ื•ื’ืžื” ื–ื•, ื‘ื•ืื• ื ืฉืชืžืฉ ื‘ื“ื•ื’ืžื” ื”ืงื•ื“ืžืช ื•ื ื‘ื ื” ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Haar Cascades.

ืืฉื“ื•ืช ื”ืืจ ื”ื ืžืกื•ื•ื’ื™ ืืฉื“ ืืฉืจ ืžืื•ืžื ื™ื ื‘ื˜ื›ื ื™ืงืช ื”-Haar wavelet. ื”ื ืžื ืชื—ื™ื ืืช ื”ืคื™ืงืกืœื™ื ื‘ืชืžื•ื ื” ื›ื“ื™ ืœื–ื”ื•ืช ืชื›ื•ื ื•ืช ืžืกื•ื™ืžื•ืช. ืœืžื™ื“ืข ื ื•ืกืฃ ืขืœ ื”-Haar Cascades, ืื ื ืขืงื•ื‘ ืื—ืจ ื”ืงื™ืฉื•ืจื™ื ืœืžื˜ื”.

ืžืกื’ืจืช ื–ื™ื”ื•ื™ ืื•ื‘ื™ื™ืงื˜ื™ื ืฉืœ Viola-Jones
ืžืกื•ื•ื’ื™ื ืžื“ื•ืจื’ื™ื
ืชื›ื•ื ื” ื“ืžื•ื™ืช ื”ืืจ

ื”ื•ืจื“ ืืฉื“ื™ื ืฉื›ื‘ืจ ืžืื•ืžื ื™ื ื–ื” ืืคืฉืจื™ ื›ืืŸ. ื‘ื“ื•ื’ืžื” ื”ื ื•ื›ื—ื™ืช, ืืฉื“ื™ื ื™ืฉืžืฉื• ืœื–ื™ื”ื•ื™ ืคื ื™ื• ืฉืœ ืื“ื ืžื”ื—ื–ื™ืช.

ืขืœ ืžื ืช ืœืขืฉื•ืช ื–ืืช, ืขืœื™ืš ืœื™ืฆื•ืจ ืžืกื•ื•ื’ ื•ืœื”ืื›ื™ืœ ืื•ืชื• ื‘ืงื•ื‘ืฅ ืฉื›ื‘ืจ ืžื™ื•ืžืŸ (ื”ืงื™ืฉื•ืจ ื ื™ืชืŸ ืœืžืขืœื”). ื›ื‘ืจ ื”ืขืœื™ืชื™ ืืช ื”ืงื•ื‘ืฅ pencv_haarcascade_frontalface_default.xml ืœืกืคืจื™ื™ื” ืฉื‘ื” ื ืžืฆืืช ื”ืชื•ื›ื ื™ืช ืฉืœื ื•.

harrcascade := โ€œopencv_haarcascade_frontalface_default.xmlโ€classifier := gocv.NewCascadeClassifier()classifier.Load(harrcascade)
defer classifier.Close()

ื›ื“ื™ ืœื–ื”ื•ืช ืคื ื™ื ื‘ืชืžื•ื ื”, ืขืœื™ืš ืœื”ืฉืชืžืฉ ื‘ืฉื™ื˜ื” DetectMultiScale. ืคื•ื ืงืฆื™ื” ื–ื• ืœื•ืงื—ืช ืžืกื’ืจืช (ืกื•ื’ Mat) ืฉื–ื” ืขืชื” ื ืงืจืื” ืžื–ืจื ื”ื•ื•ื™ื“ืื• ืฉืœ ื”ืžืฆืœืžื” ื•ืžื—ื–ื™ืจื” ืžืขืจืš ืžืกื•ื’ Rectangle. ื’ื•ื“ืœ ื”ืžืขืจืš ืžื™ื™ืฆื’ ืืช ืžืกืคืจ ื”ืคืจืฆื•ืคื™ื ืฉื”ืžืกื•ื•ื’ ื”ืฆืœื™ื— ืœื–ื”ื•ืช ื‘ืžืกื’ืจืช. ืœืื—ืจ ืžื›ืŸ, ื›ื“ื™ ืœื•ื•ื“ื ืฉืื ื• ืจื•ืื™ื ืžื” ื”ื•ื ืžืฆื, ื‘ื•ืื• ื ืขื‘ื•ืจ ื“ืจืš ืจืฉื™ืžืช ื”ืžืœื‘ื ื™ื ื•ื ื“ืคื™ืก ืืช ืื•ื‘ื™ื™ืงื˜ ื”-Retangle ืœืžืกื•ืฃ, ื•ื ื™ืฆื•ืจ ื’ื‘ื•ืœ ืกื‘ื™ื‘ ื”ืžืœื‘ืŸ ืฉื–ื•ื”ื”. ื ื™ืชืŸ ืœืขืฉื•ืช ื–ืืช ื‘ืืžืฆืขื•ืช ื”ืคื•ื ืงืฆื™ื” Rectangle. ื”ื•ื ื™ืงื‘ืœ ืืช ื”-Mat ื”ื ืงืจื ืขืœ ื™ื“ื™ ื”ืžืฆืœืžื”, ืืช ืื•ื‘ื™ื™ืงื˜ ื”-Retangle ืฉื”ื•ื—ื–ืจ ื‘ืฉื™ื˜ืช DetectMultiScale, ืืช ื”ืฆื‘ืข ื•ื”ืขื•ื‘ื™ ืฉืœ ื”ื’ื‘ื•ืœ.

for _, r := range rects {
fmt.Println(โ€œdetectedโ€, r)
gocv.Rectangle(&img, r, color, 2)
}

ื‘ื ื™ื™ืช ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Golang ื•-OpenCV

ื‘ื ื™ื™ืช ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ื”ืžื‘ื•ืกืกืช ืขืœ Golang ื•-OpenCV

package main
 
import (
"fmt"
"image/color"
"log"
 
"gocv.io/x/gocv"
)
 
func main() {
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil {
log.Fatalf("error opening web cam: %v", err)
}
defer webcam.Close()
 
img := gocv.NewMat()
defer img.Close()
 
window := gocv.NewWindow("webcamwindow")
defer window.Close()
 
harrcascade := "opencv_haarcascade_frontalface_default.xml"
classifier := gocv.NewCascadeClassifier()
classifier.Load(harrcascade)
defer classifier.Close()
 
color := color.RGBA{0, 255, 0, 0}
for {
if ok := webcam.Read(&img); !ok || img.Empty() {
log.Println("Unable to read from the device")
continue
}
 
rects := classifier.DetectMultiScale(img)
for _, r := range rects {
fmt.Println("detected", r)
gocv.Rectangle(&img, r, color, 3)
}
 
window.IMShow(img)
window.WaitKey(50)
}
}

ื•... ื›ืŸ ื”ื›ืœ ื”ืกืชื“ืจ! ื›ืขืช ื™ืฉ ืœื ื• ืžืขืจื›ืช ื–ื™ื”ื•ื™ ืคื ื™ื ืคืฉื•ื˜ื” ื›ืชื•ื‘ื” ื‘-Go. ื‘ืงืจื•ื‘ ืื ื™ ืžืชื›ื ืŸ ืœื”ืžืฉื™ืš ื‘ื ื™ืกื•ื™ื™ื ื”ืืœื” ื•ืœื™ืฆื•ืจ ื“ื‘ืจื™ื ืžื’ื ื™ื‘ื™ื ื—ื“ืฉื™ื ืขืœ ื™ื“ื™ ืฉื™ืœื•ื‘ ืฉืœ Go ื•-OpenCV.

ืื ืืชื” ืžืขื•ื ื™ื™ืŸ, ืื ื ื“ืจื’ ืฉืจืช ืื™ื ื˜ืจื ื˜ gRPC, ืฉื›ืชื‘ืชื™ ื‘-Python ื•ื‘-OpenCV. ื”ื•ื ืžื–ืจื™ื ื ืชื•ื ื™ื ื‘ืจื’ืข ืฉืžื–ื”ื™ื ืคื ื™ื. ื–ื”ื• ื”ื‘ืกื™ืก ืœื™ืฆื™ืจืช ืœืงื•ื—ื•ืช ืฉื•ื ื™ื ื‘ืฉืคื•ืช ืชื›ื ื•ืช ืฉื•ื ื•ืช. ื”ื ื™ื•ื›ืœื• ืœื”ืชื—ื‘ืจ ืœืฉืจืช ื•ืœืงืจื•ื ืžืžื ื• ื ืชื•ื ื™ื.

ืชื•ื“ื” ืฉืงืจืืช ืืช ื”ืžืืžืจ!

Skillbox ืžืžืœื™ืฆื”:

ืžืงื•ืจ: www.habr.com

ื”ื•ืกืคืช ืชื’ื•ื‘ื”