Budowa systemu rozpoznawania twarzy w oparciu o Golang i OpenCV
OpenCV to biblioteka przeznaczona do projektów wizji komputerowej. Ma już około 20 lat. Używałem go na studiach i nadal używam go w moich projektach C++ i Python, ponieważ zapewnia dobrą obsługę tych języków.
Kiedy jednak zacząłem uczyć się i używać Go, zainteresowałem się tym, czy OpenCV można wykorzystać do pracy z tym językiem. Już wtedy istniały przykłady i tutoriale dotyczące integracji, ale wydawało mi się, że były one zbyt skomplikowane. Nieco później natrafiłam na wrapper stworzony przez zespół The Hybrid Group. W tym artykule pokażę Ci, jak rozpocząć pracę z GoCV, opracowując prosty system rozpoznawania twarzy za pomocą Haar Cascades.
Przypomnienie:dla wszystkich czytelników „Habr” - rabat w wysokości 10 000 rubli przy zapisywaniu się na dowolny kurs Skillbox przy użyciu kodu promocyjnego „Habr”.
W pierwszym przykładzie spróbujemy stworzyć aplikację otwierającą okno pokazujące strumień wideo z kamery.
Najpierw musisz zaimportować biblioteki potrzebne do pracy.
import(
"dziennik"
„gocv.io/x/gocv”
)
Następnie musisz utworzyć obiekt VideoCapture za pomocą funkcji VideoCaptureDevice. Ta ostatnia umożliwia przechwytywanie strumienia wideo za pomocą kamery. Funkcja wykorzystuje jako parametr liczbę całkowitą (reprezentuje identyfikator urządzenia).
webcam, err := gocv.VideoCaptureDevice(0)
if err != nil { log.Fatalf(“error opening web cam: %v”, err)
}
defer webcam.Close()
Teraz musimy stworzyć n-wymiarową macierz. Będzie przechowywać obrazy odczytane z aparatu.
img := gocv.NewMat()
defer img.Close()
Aby wyświetlić strumień wideo, należy utworzyć okno - można to zrobić za pomocą funkcji NewWindow.
Ponieważ wideo jest ciągłym strumieniem klatek obrazu, będziemy musieli utworzyć nieskończoną pętlę, aby w nieskończoność odczytywać strumień wideo kamery. Do tego potrzebna jest metoda Read typu VideoCapture. Będzie oczekiwać typu Mat (macierzy, którą stworzyliśmy powyżej) i zwróci wartość logiczną wskazującą, czy klatka z VideoCapture została pomyślnie odczytana, czy nie.
for {
if ok := webcam.Read(&img); !ok || img.Empty( {
log.Println(“Unable to read from the webcam”) continue
}
.
.
.
}
Teraz musisz wyświetlić ramkę w utworzonym oknie. Pauza na przejście do następnej klatki wynosi 50 ms.
okno.IMShow(img)
okno.WaitKey(50)
Po uruchomieniu aplikacji otworzy się okno ze strumieniem wideo z kamery.
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)
}
}
Przykład 2
W tym przykładzie skorzystajmy z poprzedniego przykładu i zbudujmy system rozpoznawania twarzy w oparciu o Haar Cascades.
Kaskady Haara to klasyfikatory kaskadowe szkolone przy użyciu techniki falkowej Haara. Analizują piksele na obrazie, aby wykryć określone cechy. Aby dowiedzieć się więcej o Haar Cascades, kliknij poniższe linki.
Pobierz już przeszkolone kaskady może tu być. W bieżącym przykładzie kaskady zostaną użyte do identyfikacji twarzy osoby od przodu.
Aby to zrobić należy stworzyć klasyfikator i zasilić go już przeszkolonym plikiem (link podany jest powyżej). Wgrałem już plik pencv_haarcascade_frontalface_default.xml do katalogu w którym znajduje się nasz program.
Aby wykryć twarze na obrazie, należy zastosować metodę WykryjMultiScale. Ta funkcja pobiera klatkę (typu Mat) właśnie odczytaną ze strumienia wideo kamery i zwraca tablicę typu Rectangle. Rozmiar tablicy reprezentuje liczbę ścian, które klasyfikator był w stanie wykryć w ramce. Następnie, aby mieć pewność, że zobaczymy, co zostało znalezione, przejrzyjmy listę prostokątów i wypiszmy na konsoli obiekt Rectangle, tworząc obramowanie wokół wykrytego prostokąta. Można to zrobić za pomocą funkcji Rectangle. Przyjmie Matę odczytaną przez kamerę, obiekt Rectangle zwrócony metodą DetectMultiScale, kolor i grubość obramowania.
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)
}
}
I... tak, wszystko się udało! Mamy teraz prosty system rozpoznawania twarzy napisany w Go. Wkrótce planuję kontynuować te eksperymenty i tworzyć nowe fajne rzeczy, łącząc Go i OpenCV.
Jeżeli jesteś zainteresowany proszę o ocenę serwer WWW gRPC, który napisałem w Pythonie i OpenCV. Przesyła strumieniowo dane w momencie wykrycia twarzy. Jest to podstawa do tworzenia różnych klientów w różnych językach programowania. Będą mogli połączyć się z serwerem i odczytać z niego dane.