OpenCV๋ ์ปดํจํฐ ๋น์ ํ๋ก์ ํธ๋ฅผ ์ํด ์ค๊ณ๋ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์
๋๋ค. ๊ทธ๋
๋ ๋ฒ์จ 20์ด์ฏค ๋์ด์. ๋๋ ๋ํ์์ ๊ทธ๊ฒ์ ์ฌ์ฉํ๊ณ C++ ๋ฐ Python ํ๋ก์ ํธ์๋ ์ฌ์ ํ ์ฌ์ฉํ๊ณ ์์ต๋๋ค. ์๋ํ๋ฉด ํด๋น ์ธ์ด์ ๋ํ ์ข์ ์ง์์ด ์๊ธฐ ๋๋ฌธ์
๋๋ค.
ํ์ง๋ง Go๋ฅผ ๋ฐฐ์ฐ๊ณ ์ฌ์ฉํ๊ธฐ ์์ํ๋ฉด์ OpenCV๋ฅผ ์ฌ์ฉํ์ฌ ์ด ์ธ์ด๋ฅผ ์ฌ์ฉํ ์ ์๋์ง์ ๊ด์ฌ์ด ์๊ฒผ์ต๋๋ค. ๋น์์๋ ์ด๋ฏธ ํตํฉ์ ๋ํ ์์ ์ ํํ ๋ฆฌ์ผ์ด ์์์ง๋ง ๋๋ฌด ๋ณต์กํด ๋ณด์์ต๋๋ค. ์กฐ๊ธ ํ์ ์ ๋ The Hybrid Group ํ์ด ๋ง๋ ๋ํผ๋ฅผ ๋ฐ๊ฒฌํ์ต๋๋ค. ์ด ๊ธฐ์ฌ์์๋ Haar Cascades๋ฅผ ์ฌ์ฉํ์ฌ ๊ฐ๋จํ ์ผ๊ตด ์ธ์ ์์คํ
์ ๊ฐ๋ฐํ์ฌ GoCV๋ฅผ ์์ํ๋ ๋ฐฉ๋ฒ์ ๋ณด์ฌ ๋๋ฆฌ๊ฒ ์ต๋๋ค.
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค. ์ค๊ธฐ ์ฝ์ค
"์ฒ์๋ถํฐ Python ๊ฐ๋ฐ์" .์๋ฆผ: "Habr"์ ๋ชจ๋ ๋ ์๋ฅผ ์ํ - "Habr" ํ๋ก๋ชจ์ ์ฝ๋๋ฅผ ์ฌ์ฉํ์ฌ Skillbox ๊ณผ์ ์ ๋ฑ๋กํ ๋ 10 ๋ฃจ๋ธ ํ ์ธ.
ํ์ํ ๊ฒ :
- ๊ฐ๋ค;
- OpenCV(์๋ ์ค์น ํ๋ก๊ทธ๋จ ๋งํฌ);
- ์น ๋๋ ์ผ๋ฐ ๋น๋์ค ์นด๋ฉ๋ผ.
์ค์น
- Linux :
gocv.io/getting-started/linux - ๋งฅ OS :
gocv.io/getting-started/macos - ์๋์ฐ :
gocv.io/getting-started/windows
์๋ฅผ ๋ค์ด 1
์ฒซ ๋ฒ์งธ ์์์๋ ์นด๋ฉ๋ผ ๋น๋์ค ์คํธ๋ฆผ์ ํ์ํ๋ ์ฐฝ์ ์ฌ๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ๋ง๋ค์ด ๋ณด๊ฒ ์ต๋๋ค.
๋จผ์ ์์ ์ ํ์ํ ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ๊ฐ์ ธ์์ผ ํฉ๋๋ค.
์์
(
"ํต๋๋ฌด"
โgocv.io/x/gocvโ
)
๊ทธ๋ฐ ๋ค์ VideoCaptureDevice ํจ์๋ฅผ ์ฌ์ฉํ์ฌ VideoCapture ๊ฐ์ฒด๋ฅผ ์์ฑํด์ผ ํฉ๋๋ค. ํ์๋ฅผ ์ฌ์ฉํ๋ฉด ์นด๋ฉ๋ผ๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋์ค ์คํธ๋ฆผ์ ์บก์ฒํ ์ ์์ต๋๋ค. ์ด ํจ์๋ ์ ์๋ฅผ ๋งค๊ฐ๋ณ์๋ก ์ฌ์ฉํฉ๋๋ค(์ฅ์น ID๋ฅผ ๋ํ๋).
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil { log.Fatalf(โerror opening web cam: %vโ, err)
}
defer webcam.Close()
์ด์ n์ฐจ์ ํ๋ ฌ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์นด๋ฉ๋ผ์์ ์ฝ์ ์ด๋ฏธ์ง๋ฅผ ์ ์ฅํฉ๋๋ค.
img := gocv.NewMat()
defer img.Close()
๋น๋์ค ์คํธ๋ฆผ์ ํ์ํ๋ ค๋ฉด ์ฐฝ์ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ด๋ NewWindow ๊ธฐ๋ฅ์ ์ฌ์ฉํ์ฌ ์ํํ ์ ์์ต๋๋ค.
window := gocv.NewWindow(โwebcamwindowโ)
defer window.Close()
์ด์ ๊ฐ์ฅ ํฅ๋ฏธ๋ก์ด ๋ถ๋ถ์ผ๋ก ๋์ด ๊ฐ์๋ค.
๋น๋์ค๋ ์ด๋ฏธ์ง ํ๋ ์์ ์ฐ์ ์คํธ๋ฆผ์ด๋ฏ๋ก ์นด๋ฉ๋ผ์ ๋น๋์ค ์คํธ๋ฆผ์ ๋์์ด ์ฝ์ผ๋ ค๋ฉด ๋ฌดํ ๋ฃจํ๋ฅผ ๋ง๋ค์ด์ผ ํฉ๋๋ค. ์ด๋ ๊ฒ ํ๋ ค๋ฉด VideoCapture ์ ํ์ Read ๋ฉ์๋๊ฐ ํ์ํฉ๋๋ค. VideoCapture์ ํ๋ ์์ ์ฑ๊ณต์ ์ผ๋ก ์ฝ์๋์ง ์ฌ๋ถ๋ฅผ ๋ํ๋ด๋ ๋ถ์ธ ๊ฐ์ ๋ฐํํ๋ Mat ์ ํ(์์์ ๋ง๋ ํ๋ ฌ)์ ์์ํฉ๋๋ค.
for {
if ok := webcam.Read(&img); !ok || img.Empty( {
log.Println(โUnable to read from the webcamโ) continue
}
.
.
.
}
์ด์ ์์ฑ๋ ์ฐฝ์ ํ๋ ์์ ํ์ํด์ผ ํฉ๋๋ค. ๋ค์ ํ๋ ์์ผ๋ก ์ด๋ํ๊ธฐ ์ํ ์ผ์ ์ ์ง๋ 50ms์ ๋๋ค.
window.IMShow(img)
window.WaitKey(50)
์ ํ๋ฆฌ์ผ์ด์ ์ ์คํํ๋ฉด ์นด๋ฉ๋ผ์ ๋น๋์ค ์คํธ๋ฆผ์ด ํฌํจ๋ ์ฐฝ์ด ์ด๋ฆฝ๋๋ค.
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 ์บ์ค์ผ์ด๋๋ Haar ์จ์ด๋ธ๋ฆฟ ๊ธฐ์ ์ ์ฌ์ฉํ์ฌ ํ๋ จ๋ ์บ์ค์ผ์ด๋ ๋ถ๋ฅ๊ธฐ์ ๋๋ค. ํน์ ํน์ง์ ๊ฐ์งํ๊ธฐ ์ํด ์ด๋ฏธ์ง์ ํฝ์ ์ ๋ถ์ํฉ๋๋ค. Haar Cascades์ ๋ํด ๋ ์์ธํ ์์๋ณด๋ ค๋ฉด ์๋ ๋งํฌ๋ฅผ ํด๋ฆญํ์ธ์.
์ด๋ฏธ ํ์ต๋ ์บ์ค์ผ์ด๋ ๋ค์ด๋ก๋
์ด๋ฅผ ์ํํ๋ ค๋ฉด ๋ถ๋ฅ์๋ฅผ ์์ฑํ๊ณ ์ด๋ฏธ ํ๋ จ๋ ํ์ผ์ ์ ๊ณตํด์ผ ํฉ๋๋ค(๋งํฌ๋ ์์ ์ ๊ณต๋จ). ์ฐ๋ฆฌ ํ๋ก๊ทธ๋จ์ด ์๋ ๋๋ ํ ๋ฆฌ์ ์ด๋ฏธ pencv_haarcascade_frontalface_default.xml ํ์ผ์ ์ ๋ก๋ํ์ต๋๋ค.
harrcascade := โopencv_haarcascade_frontalface_default.xmlโclassifier := gocv.NewCascadeClassifier()classifier.Load(harrcascade)
defer classifier.Close()
์ด๋ฏธ์ง์์ ์ผ๊ตด์ ๊ฐ์งํ๋ ค๋ฉด ๋ค์ ๋ฐฉ๋ฒ์ ์ฌ์ฉํด์ผ ํฉ๋๋ค.
for _, r := range rects {
fmt.Println(โdetectedโ, r)
gocv.Rectangle(&img, r, color, 2)
}
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๋ฅผ ๊ฒฐํฉํ์ฌ ์๋กญ๊ณ ๋ฉ์ง ๊ฒ๋ค์ ๋ง๋ค ๊ณํ์ ๋๋ค.
๊ด์ฌ์์ผ์๋ฉด ํ๊ฐ ๋ถํ๋๋ฆฝ๋๋ค
๊ธฐ์ฌ๋ฅผ ์ฝ์ด์ฃผ์ ์ ๊ฐ์ฌํฉ๋๋ค!
Skillbox๋ ๋ค์์ ๊ถ์ฅํฉ๋๋ค.
- XNUMX๋ ์ค์ต ์ฝ์ค
"์ ๋ PRO ์น ๊ฐ๋ฐ์์ ๋๋ค" .- ๊ต์ก์ฉ ์จ๋ผ์ธ ๊ณผ์
"์ง์ ์๋ฐ ๊ฐ๋ฐ์" .- ์ค๊ธฐ ์ฝ์ค
"0์์ PRO๋ก์ PHP ๊ฐ๋ฐ์" .
์ถ์ฒ : habr.com