作者的环境为windos 10,64位。
一、准备需要检测的图片
这个是在网络上下载。
准备工具,imglab.exe,这个工具用于标记矩形框
1、创建images目录,把图片放到里面。
2、运行cmd命令行,imglab -c training_with_face_landmarks.xml images,创建相关文件。
3、运行cmd命令行,imglab training_with_face_landmarks.xml,打开制作数据集的软件。
工具的使用说明:
shirt+左键 长方形的框
先选中长方形的框,再shirt+左键 特征点标注
ctrl+滚动轴 放大或者缩小
键盘的up和down 上/下一张图片
alt+d 删除当前图片
选中框+del 删除框
最终生成文件training_with_face_landmarks.xml和image_metadata_stylesheet.xsl
一、在go-face库增加训练接口
如果没有安装go-face和dlib库,请参考go使用dlib人脸检测和人脸识别_xinlinhack的博客-CSDN博客_go 人脸识别
官方的源码路径:GitHub - Kagami/go-face: Face recognition with Go
需要增加两个接口:
1、修改头文件facerec.h,增加结构体,增加两个函数facerec_train_object_detector和facerec_test_object_detector声明。
- typedef struct tagSimpleTestResults
- {
- double precision;
- double recall;
- double average_precision;
- }tagSimpleTestResults;
-
- void facerec_train_object_detector(const char* dataset_filename, const char* detector_output_filename);
- tagSimpleTestResults facerec_test_object_detector(const char* dataset_filename, const char* detector_filename);
2、修改文件facerec.cc。
增加头文件#include
增加两个函数facerec_train_object_detector和facerec_test_object_detector
- #include
- #include
- #include
- #include
- #include
- #include
- #include "facerec.h"
- #include "jpeg_mem_loader.h"
- #include "classify.h"
-
-
-
- void facerec_train_object_detector(const char* dataset_filename, const char* detector_output_filename) {
-
- // options用于设置训练的参数和模式
- simple_object_detector_training_options gsOptions;
-
- // 持向量机的C参数,通常默认取为5.自己适当更改参数以达到最好的效果
- gsOptions.C = 5;
- // 线程数,你电脑有4核的话就填4
- gsOptions.num_threads = 4;
- // 打印信息
- gsOptions.be_verbose = 1;
-
- gsOptions.add_left_right_image_flips = 1;
-
- train_simple_object_detector(dataset_filename, detector_output_filename, gsOptions);
- }
-
- tagSimpleTestResults facerec_test_object_detector(const char* dataset_filename, const char* detector_filename) {
-
- struct simple_test_results t;
- tagSimpleTestResults res;
-
- t = test_simple_object_detector(dataset_filename, detector_filename, -1);
-
- res.precision = t.precision;
- res.recall = t.recall;
- res.average_precision = t.average_precision;
-
- return res;
- }
3、在目录C:\msys64\mingw64\include\dlib\image_processing,添加三个头文件
simple_object_detector.h、simple_object_detector_py.h和serialize_object_detector.h
这三个文件原本是PYTHON的头文件,经过修改。
4、修改C:\msys64\mingw64\include\dlib\config.h头文件,把DLIB_GIF_SUPPORT屏蔽,否则编译不过。
5、face.go文件增加两接口
- func TrainSimpleObjectDetector(dataset_filename, detector_output_filename string) {
- datasetFilePath := C.CString(dataset_filename)
- defer C.free(unsafe.Pointer(datasetFilePath))
-
- detectorOutFilePath := C.CString(detector_output_filename)
- defer C.free(unsafe.Pointer(detectorOutFilePath))
-
- C.facerec_train_object_detector(datasetFilePath, detectorOutFilePath)
-
- return
- }
-
-
- func TestSimpleObjectDetector(dataset_filename, detector_filename string) (precision, recall, average_precision float32) {
-
- datasetFilePath := C.CString(dataset_filename)
- defer C.free(unsafe.Pointer(datasetFilePath))
-
- detectorFilePath := C.CString(detector_filename)
- defer C.free(unsafe.Pointer(detectorFilePath))
-
- ret := C.facerec_test_object_detector(datasetFilePath, detectorFilePath)
- //defer C.free(unsafe.Pointer(ret))
-
- precision = float32(ret.precision)
- recall = float32(ret.recall)
- average_precision = float32(ret.average_precision)
-
- return
- }
至此,人脸库可以使用了。
三、训练例子代码
- package main
-
- import (
- "fmt"
- "github.com/Kagami/go-face"
- "path/filepath"
- )
-
-
- // 训练
- func trainSimple() {
-
- fmt.Println("开始训练:")
-
- dataset_filename := filepath.Join("cat_face_train", "cat_face_train.xml")
-
- face.TrainSimpleObjectDetector(dataset_filename, "catDetector.svm")
-
- precision, recall, average_precision := face.TestSimpleObjectDetector("cat_face_train/cat_face_train.xml", "catDetector.svm")
- fmt.Println("训练图片的精确度: ", precision, recall, average_precision )
-
- precision, recall, average_precision = face.TestSimpleObjectDetector("cat_face_test/cat_face_test.xml", "catDetector.svm")
- fmt.Println("测试图片的精确度: ", precision, recall, average_precision )
-
- }
-
-
- func main() {
- // 训练
- trainSimple()
-
- }
可以看到准确率差不多7成,模型保存到了catDetector.svm中。
四、测试模型
接口NewRecognizer3、SetSimpleDetector和DetectFromBufferSimple都是定制的,需要修改go-face的库,达到跟python的接口一致。
- package main
-
- import (
- "fmt"
- "github.com/Kagami/go-face"
- "gocv.io/x/gocv"
- "image"
- "image/color"
- "log"
- "path/filepath"
- )
-
-
- func testDetectorSimple() {
-
- // open display window
- window := gocv.NewWindow("cat Detector")
- defer window.Close()
-
- // color for the rect when faces detected
- greenColor := color.RGBA{0, 255, 0, 255}
- //redColor := color.RGBA{255, 0, 0, 255}
-
- // Init recognizer
- rec, err := face.NewRecognizer3()
- if nil != err {
- log.Fatal(err)
- }
- // close it
- defer rec.Close()
-
- // Load
- if err = rec.SetSimpleDetector("catDetector.svm"); nil != err {
- log.Fatal(err)
- }
-
- faceImagePath := "cat_face_test/6.jpg"
-
- //
- fmt.Println("正在读的人脸图像 = ", faceImagePath)
-
- img1 := gocv.IMRead(faceImagePath, gocv.IMReadColor)
- defer img1.Close()
-
- buff, err := gocv.IMEncode(".jpg", img1)
-
- //
- faces, err := rec.DetectFromBufferSimple(buff.GetBytes())
-
- if err != nil {
- log.Fatalf("无法识别: %v", err)
- }
-
- if 0 == len(faces){
- log.Fatal("图片中没找到人脸")
- }
-
- for _, f := range faces{
-
- gocv.Rectangle(&img1, f.Rectangle, greenColor, 3)
-
- pt := image.Pt(f.Rectangle.Min.X, f.Rectangle.Min.Y-10)
- gocv.PutText(&img1, "cat", pt, gocv.FontHersheyPlain, 1, greenColor, 1)
-
- }
-
- // show the image in the window, and wait 1 millisecond
- window.IMShow(img1)
-
- for{
- if window.WaitKey(1) >= 0 {
- break
- }
- }
-
- }
-
- func main() {
-
- // 使用模型测试
- testDetectorSimple()
-
- }
工具和代码的路径:训练工具、测试代码、goface修改的代码和头文件。-机器学习文档类资源-CSDN下载