mirror of
https://github.com/Danile71/go-face-examples.git
synced 2025-09-26 19:51:22 +08:00
Init repo
This commit is contained in:
11
README.md
Normal file
11
README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# go-face examples
|
||||
|
||||
## Requirements
|
||||
|
||||
To compile face you need to have [go-face](github.com/Danile71/go-face) and [gocv](gocv.io/x/gocv)
|
||||
|
||||
### [face](face/)
|
||||
|
||||
### [plate](plate/)
|
||||
|
||||
### [tracking](tracking/)
|
2
face/.gitignore
vendored
Normal file
2
face/.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
/models/*dat
|
||||
face
|
11
face/README.md
Normal file
11
face/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# go-face examples
|
||||
|
||||
## Requirements
|
||||
|
||||
To compile face you need to have [go-face](github.com/Danile71/go-face) and [gocv](gocv.io/x/gocv)
|
||||
|
||||

|
||||
|
||||
1. cd models && ./download_models.sh
|
||||
2. go build -tags gocv
|
||||
3. ./face
|
9
face/go.mod
Normal file
9
face/go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module github.com/Danile71/go-face-examples/face
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Danile71/go-face v0.1.1
|
||||
github.com/Danile71/go-logger v0.1.2 // indirect
|
||||
gocv.io/x/gocv v0.28.0 // indirect
|
||||
)
|
9
face/go.sum
Normal file
9
face/go.sum
Normal file
@@ -0,0 +1,9 @@
|
||||
github.com/Danile71/go-face v0.1.1 h1:lNaSNTOIJQ7YoGxD/d2nkiBChvSaE0gvrxJC/DTXHt8=
|
||||
github.com/Danile71/go-face v0.1.1/go.mod h1:C83Krj1aVVsvlaIcyjn5hUZYYBIgX0BYvW6PMqzh1/Q=
|
||||
github.com/Danile71/go-logger v0.1.2 h1:7RdHu2QntvvGJvdVaekiVGDL3FhkeUFiG90OTtY8wQU=
|
||||
github.com/Danile71/go-logger v0.1.2/go.mod h1:saFCu/TU1L2Ypl48em66PQcFGy9lHz8lzn42bulF7W4=
|
||||
github.com/Kagami/go-face v0.0.0-20200825065730-3dd2d74dccfb/go.mod h1:9wdDJkRgo3SGTcFwbQ7elVIQhIr2bbBjecuY7VoqmPU=
|
||||
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
gocv.io/x/gocv v0.28.0 h1:hweRS9Js60YEZPZzjhU5I+0E2ngazquLlO78zwnrFvY=
|
||||
gocv.io/x/gocv v0.28.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
|
BIN
face/images/face.jpg
Normal file
BIN
face/images/face.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 8.1 KiB |
BIN
face/images/faces.jpg
Normal file
BIN
face/images/faces.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 90 KiB |
BIN
face/images/screen.jpg
Normal file
BIN
face/images/screen.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 228 KiB |
165
face/main.go
Normal file
165
face/main.go
Normal file
@@ -0,0 +1,165 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image"
|
||||
"image/color"
|
||||
|
||||
"github.com/Danile71/go-face"
|
||||
"github.com/Danile71/go-logger"
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
const (
|
||||
cnnModel = "models/mmod_human_face_detector.dat"
|
||||
|
||||
shapeModel = "models/shape_predictor_68_face_landmarks.dat" // "models/shape_predictor_5_face_landmarks.dat"
|
||||
descrModel = "models/dlib_face_recognition_resnet_model_v1.dat"
|
||||
ageModel = "models/dnn_age_predictor_v1.dat"
|
||||
genderModel = "models/dnn_gender_classifier_v1.dat"
|
||||
|
||||
faceImage = "images/face.jpg"
|
||||
facesImage = "images/faces.jpg"
|
||||
)
|
||||
|
||||
var (
|
||||
greenColor = color.RGBA{0, 255, 0, 255}
|
||||
redColor = color.RGBA{255, 0, 0, 255}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetLevel(logger.DEBUG)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// try to find him
|
||||
var descriptor face.Descriptor
|
||||
|
||||
// craete window
|
||||
w := gocv.NewWindow("example")
|
||||
defer w.Close()
|
||||
|
||||
// Init recognizer
|
||||
rec, err := face.NewRecognizer()
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
// close it
|
||||
defer rec.Close()
|
||||
|
||||
// Load shape model
|
||||
if err = rec.SetShapeModel(shapeModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Load description model
|
||||
if err = rec.SetDescriptorModel(descrModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Load age model
|
||||
if err = rec.SetAgeModel(ageModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Load gener model
|
||||
if err = rec.SetGenderModel(genderModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// Load CNN model
|
||||
if err = rec.SetCNNModel(cnnModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// load first image
|
||||
img1 := gocv.IMRead(faceImage, gocv.IMReadUnchanged)
|
||||
defer img1.Close()
|
||||
|
||||
// load second image
|
||||
img2 := gocv.IMRead(facesImage, gocv.IMReadUnchanged)
|
||||
defer img2.Close()
|
||||
|
||||
// copy bg to draw
|
||||
background := img2.Clone()
|
||||
defer background.Close()
|
||||
|
||||
// try detect faces
|
||||
faces, err := rec.DetectFromMatCNN(img1)
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, f := range faces {
|
||||
defer f.Close()
|
||||
|
||||
// get face description
|
||||
if err = rec.Recognize(&f); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
// predict face age
|
||||
rec.GetAge(&f)
|
||||
|
||||
// predict face gender
|
||||
rec.GetGender(&f)
|
||||
|
||||
// set descriptor
|
||||
descriptor = f.Descriptor
|
||||
|
||||
// draw rect
|
||||
gocv.Rectangle(&img1, f.Rectangle, greenColor, 2)
|
||||
|
||||
gocv.PutText(&img1, fmt.Sprintf("%s:%d y.o.", f.Gender, f.Age), image.Point{f.Rectangle.Min.X - 20, f.Rectangle.Min.Y - 5}, gocv.FontHersheyPlain, 1, redColor, 1)
|
||||
|
||||
}
|
||||
gocv.PutText(&img1, "press any key...", image.Point{0, img1.Cols() - 30}, gocv.FontHersheyPlain, 1, redColor, 1)
|
||||
|
||||
w.IMShow(img1)
|
||||
|
||||
fmt.Println("press any key to continue...")
|
||||
|
||||
for {
|
||||
if key := w.WaitKey(1000); key != -1 {
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
faces, err = rec.DetectFromMatCNN(img2)
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, f := range faces {
|
||||
defer f.Close()
|
||||
|
||||
if err = rec.Recognize(&f); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
rec.GetAge(&f)
|
||||
rec.GetGender(&f)
|
||||
gocv.Rectangle(&background, f.Rectangle, greenColor, 2)
|
||||
|
||||
gocv.PutText(&background, fmt.Sprintf("%s:%d y.o.", f.Gender, f.Age), image.Point{f.Rectangle.Min.X - 20, f.Rectangle.Min.Y - 5}, gocv.FontHersheyPlain, 1, redColor, 1)
|
||||
|
||||
dist := face.SquaredEuclideanDistance(f.Descriptor, descriptor)
|
||||
|
||||
c := redColor
|
||||
if dist < 0.1 {
|
||||
c = greenColor
|
||||
}
|
||||
|
||||
gocv.PutText(&background, fmt.Sprintf("%f", dist), image.Point{f.Rectangle.Min.X, f.Rectangle.Max.Y}, gocv.FontHersheyPlain, 1, c, 1)
|
||||
}
|
||||
|
||||
w.IMShow(background)
|
||||
|
||||
fmt.Println("press any key to exit...")
|
||||
|
||||
for {
|
||||
if key := w.WaitKey(1000); key != -1 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
31
face/models/download_models.sh
Executable file
31
face/models/download_models.sh
Executable file
@@ -0,0 +1,31 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ ! -f "shape_predictor_5_face_landmarks.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/shape_predictor_5_face_landmarks.dat.bz2
|
||||
bunzip2 shape_predictor_5_face_landmarks.dat.bz2
|
||||
fi
|
||||
|
||||
if [ ! -f "shape_predictor_68_face_landmarks.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/shape_predictor_68_face_landmarks.dat.bz2
|
||||
bunzip2 shape_predictor_68_face_landmarks.dat.bz2
|
||||
fi
|
||||
|
||||
if [ ! -f "dlib_face_recognition_resnet_model_v1.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/dlib_face_recognition_resnet_model_v1.dat.bz2
|
||||
bunzip2 dlib_face_recognition_resnet_model_v1.dat.bz2
|
||||
fi
|
||||
|
||||
if [ ! -f "mmod_human_face_detector.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/mmod_human_face_detector.dat.bz2
|
||||
bunzip2 mmod_human_face_detector.dat.bz2
|
||||
fi
|
||||
|
||||
if [ ! -f "dnn_age_predictor_v1.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/age-predictor/dnn_age_predictor_v1.dat.bz2
|
||||
bunzip2 dnn_age_predictor_v1.dat.bz2
|
||||
fi
|
||||
|
||||
if [ ! -f "dnn_gender_classifier_v1.dat" ]; then
|
||||
wget https://github.com/davisking/dlib-models/raw/master/gender-classifier/dnn_gender_classifier_v1.dat.bz2
|
||||
bunzip2 dnn_gender_classifier_v1.dat.bz2
|
||||
fi
|
1
plate/.gitignore
vendored
Normal file
1
plate/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
plate
|
11
plate/README.md
Normal file
11
plate/README.md
Normal file
@@ -0,0 +1,11 @@
|
||||
# go-face examples
|
||||
## Russian plate numbers
|
||||
|
||||
## Requirements
|
||||
|
||||
To compile face you need to have [go-face](github.com/Danile71/go-face) and [gocv](gocv.io/x/gocv)
|
||||
|
||||

|
||||
|
||||
1. go build -tags gocv
|
||||
2. ./plate
|
9
plate/go.mod
Normal file
9
plate/go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module github.com/Danile71/go-face-examples/plate
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Danile71/go-face v0.1.1
|
||||
github.com/Danile71/go-logger v0.1.2 // indirect
|
||||
gocv.io/x/gocv v0.28.0 // indirect
|
||||
)
|
9
plate/go.sum
Normal file
9
plate/go.sum
Normal file
@@ -0,0 +1,9 @@
|
||||
github.com/Danile71/go-face v0.1.1 h1:lNaSNTOIJQ7YoGxD/d2nkiBChvSaE0gvrxJC/DTXHt8=
|
||||
github.com/Danile71/go-face v0.1.1/go.mod h1:C83Krj1aVVsvlaIcyjn5hUZYYBIgX0BYvW6PMqzh1/Q=
|
||||
github.com/Danile71/go-logger v0.1.2 h1:7RdHu2QntvvGJvdVaekiVGDL3FhkeUFiG90OTtY8wQU=
|
||||
github.com/Danile71/go-logger v0.1.2/go.mod h1:saFCu/TU1L2Ypl48em66PQcFGy9lHz8lzn42bulF7W4=
|
||||
github.com/Kagami/go-face v0.0.0-20200825065730-3dd2d74dccfb/go.mod h1:9wdDJkRgo3SGTcFwbQ7elVIQhIr2bbBjecuY7VoqmPU=
|
||||
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
gocv.io/x/gocv v0.28.0 h1:hweRS9Js60YEZPZzjhU5I+0E2ngazquLlO78zwnrFvY=
|
||||
gocv.io/x/gocv v0.28.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
|
BIN
plate/images/numbers.jpg
Normal file
BIN
plate/images/numbers.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 440 KiB |
BIN
plate/images/screen.jpg
Normal file
BIN
plate/images/screen.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 198 KiB |
71
plate/main.go
Normal file
71
plate/main.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"github.com/Danile71/go-face"
|
||||
"github.com/Danile71/go-logger"
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
const (
|
||||
cnnModel = "models/mmod_plate_detector.dat"
|
||||
|
||||
plateImage = "images/numbers.jpg"
|
||||
)
|
||||
|
||||
var (
|
||||
greenColor = color.RGBA{0, 255, 0, 255}
|
||||
redColor = color.RGBA{255, 0, 0, 255}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetLevel(logger.DEBUG)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// create window
|
||||
w := gocv.NewWindow("example")
|
||||
defer w.Close()
|
||||
|
||||
// Init recognizer
|
||||
rec, err := face.NewRecognizer()
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
// close it
|
||||
defer rec.Close()
|
||||
|
||||
// Load CNN model
|
||||
if err = rec.SetCNNModel(cnnModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
// load first image
|
||||
img := gocv.IMRead(plateImage, gocv.IMReadUnchanged)
|
||||
defer img.Close()
|
||||
|
||||
// try detect plates
|
||||
plates, err := rec.DetectFromMatCNN(img)
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range plates {
|
||||
defer p.Close()
|
||||
|
||||
// draw rect
|
||||
gocv.Rectangle(&img, p.Rectangle, greenColor, 2)
|
||||
}
|
||||
|
||||
w.IMShow(img)
|
||||
|
||||
fmt.Println("press any key to exit...")
|
||||
|
||||
for {
|
||||
if key := w.WaitKey(1000); key != -1 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
BIN
plate/models/mmod_plate_detector.dat
Normal file
BIN
plate/models/mmod_plate_detector.dat
Normal file
Binary file not shown.
1
tracking/.gitignore
vendored
Normal file
1
tracking/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
tracking
|
13
tracking/README.md
Normal file
13
tracking/README.md
Normal file
@@ -0,0 +1,13 @@
|
||||
# go-face examples
|
||||
## Russian plate numbers
|
||||
|
||||
## Requirements
|
||||
|
||||
To compile face you need to have [go-face](github.com/Danile71/go-face) and [gocv](gocv.io/x/gocv)
|
||||
|
||||

|
||||
[youtube](https://youtu.be/JFRfxLJ9CIM)
|
||||
|
||||
|
||||
1. go build -tags gocv
|
||||
2. ./plate
|
9
tracking/go.mod
Normal file
9
tracking/go.mod
Normal file
@@ -0,0 +1,9 @@
|
||||
module github.com/Danile71/go-face-examples/tracking
|
||||
|
||||
go 1.16
|
||||
|
||||
require (
|
||||
github.com/Danile71/go-face v0.1.1
|
||||
github.com/Danile71/go-logger v0.1.2 // indirect
|
||||
gocv.io/x/gocv v0.28.0 // indirect
|
||||
)
|
9
tracking/go.sum
Normal file
9
tracking/go.sum
Normal file
@@ -0,0 +1,9 @@
|
||||
github.com/Danile71/go-face v0.1.1 h1:lNaSNTOIJQ7YoGxD/d2nkiBChvSaE0gvrxJC/DTXHt8=
|
||||
github.com/Danile71/go-face v0.1.1/go.mod h1:C83Krj1aVVsvlaIcyjn5hUZYYBIgX0BYvW6PMqzh1/Q=
|
||||
github.com/Danile71/go-logger v0.1.2 h1:7RdHu2QntvvGJvdVaekiVGDL3FhkeUFiG90OTtY8wQU=
|
||||
github.com/Danile71/go-logger v0.1.2/go.mod h1:saFCu/TU1L2Ypl48em66PQcFGy9lHz8lzn42bulF7W4=
|
||||
github.com/Kagami/go-face v0.0.0-20200825065730-3dd2d74dccfb/go.mod h1:9wdDJkRgo3SGTcFwbQ7elVIQhIr2bbBjecuY7VoqmPU=
|
||||
github.com/hybridgroup/mjpeg v0.0.0-20140228234708-4680f319790e/go.mod h1:eagM805MRKrioHYuU7iKLUyFPVKqVV6um5DAvCkUtXs=
|
||||
github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
|
||||
gocv.io/x/gocv v0.28.0 h1:hweRS9Js60YEZPZzjhU5I+0E2ngazquLlO78zwnrFvY=
|
||||
gocv.io/x/gocv v0.28.0/go.mod h1:oc6FvfYqfBp99p+yOEzs9tbYF9gOrAQSeL/dyIPefJU=
|
BIN
tracking/images/screen.jpg
Normal file
BIN
tracking/images/screen.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 262 KiB |
116
tracking/main.go
Normal file
116
tracking/main.go
Normal file
@@ -0,0 +1,116 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"image/color"
|
||||
|
||||
"github.com/Danile71/go-face"
|
||||
"github.com/Danile71/go-logger"
|
||||
"gocv.io/x/gocv"
|
||||
)
|
||||
|
||||
const (
|
||||
cnnModel = "models/mmod_plate_detector.dat"
|
||||
|
||||
plateVideo = "video/video.mp4"
|
||||
)
|
||||
|
||||
var (
|
||||
greenColor = color.RGBA{0, 255, 0, 255}
|
||||
redColor = color.RGBA{255, 0, 0, 255}
|
||||
)
|
||||
|
||||
func init() {
|
||||
logger.SetLevel(logger.DEBUG)
|
||||
}
|
||||
|
||||
func main() {
|
||||
// create window
|
||||
w := gocv.NewWindow("example")
|
||||
defer w.Close()
|
||||
|
||||
// Init recognizer
|
||||
rec, err := face.NewRecognizer()
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
// close it
|
||||
defer rec.Close()
|
||||
|
||||
// Load CNN model
|
||||
if err = rec.SetCNNModel(cnnModel); logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
img := gocv.NewMat()
|
||||
defer img.Close()
|
||||
|
||||
frames, err := gocv.VideoCaptureFile(plateVideo)
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
trackers := make(map[int]*face.Tracker)
|
||||
|
||||
for {
|
||||
if ok := frames.Read(&img); !ok {
|
||||
return
|
||||
}
|
||||
|
||||
if len(trackers) == 0 {
|
||||
// try detect plates
|
||||
plates, err := rec.DetectFromMatCNN(img)
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range plates {
|
||||
tracker, err := face.NewTracker()
|
||||
if logger.OnError(err) {
|
||||
return
|
||||
}
|
||||
|
||||
tracker.StartMat(img, p.Rectangle)
|
||||
|
||||
trackers[len(trackers)] = tracker
|
||||
|
||||
// draw rect
|
||||
gocv.Rectangle(&img, p.Rectangle, greenColor, 2)
|
||||
|
||||
p.Close()
|
||||
}
|
||||
}
|
||||
|
||||
for key, tracker := range trackers {
|
||||
conf, err := tracker.UpdateMat(img)
|
||||
if conf < 3 || err != nil {
|
||||
delete(trackers, key)
|
||||
continue
|
||||
}
|
||||
|
||||
position, err := tracker.Position()
|
||||
if err != nil {
|
||||
delete(trackers, key)
|
||||
continue
|
||||
}
|
||||
|
||||
// draw rect
|
||||
gocv.Rectangle(&img, position, greenColor, 2)
|
||||
}
|
||||
|
||||
w.IMShow(img)
|
||||
|
||||
if key := w.WaitKey(1); key != -1 {
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fmt.Println("press any key to exit...")
|
||||
|
||||
for {
|
||||
if key := w.WaitKey(1000); key != -1 {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
BIN
tracking/models/mmod_plate_detector.dat
Normal file
BIN
tracking/models/mmod_plate_detector.dat
Normal file
Binary file not shown.
BIN
tracking/video/video.mp4
Normal file
BIN
tracking/video/video.mp4
Normal file
Binary file not shown.
Reference in New Issue
Block a user