opencv默认提供了haar特征和lbp特征训练的人脸分类器,可是效果不太好,因此咱们能够用opencv提供的跑opencv_traincascade函数来训练一个LBP特征的分类器。(因为opencv3中hog与hog文章定义的不一样,所以在opencv3 的opencv_traincascade函数中被删掉了详情)html
按照官方文档的训练流程:python
首先把正例和负例样本按下面的结构存放:git
train -pos -- info.dat -- img ---- 1.jpg ---- 2.jpg ---- ... -neg -- info.dat -- img ---- 1.jpg ---- 2.jpg ---- ...
其中正例的info.dat格式以下:其中路径为必须为相对路径,1为图片中目标的个数,x,y为bounding box左上角的坐标;w,h为bounding box的长和宽github
img/1.jpg 1 x y w h img/2.jpg 1 x y w h # img/3.jpg 2 100 200 50 50 50 30 25 25 # 若是同一图片有多个目标
而负例的格式只是文件名,但*必须为全路径**(opencv坑1):bash
/path/to/img/1.jpg /path/to/img/2.jpg
通常来讲样本须要覆盖多种大小才能使模型比较鲁棒,对于负例样原本说,须要保证图片尺寸比训练时候的window size大,而从一张负例图片中能够截出许多个负例的window进行训练,所以负例的图片数量与正例差很少的时候能够在训练的时候设定比正例超过10倍的数目。ide
opencv_createsamples -vec face.vec \ # 输出的数据集vec文件 -info /startdt_data/face_datasets/opencv_face_dataset/train/pos/info.dat \ # 正例的annotation文件,这里须要用全路径,避免报错 -w 112 -h 112 -num 5000 \ # 正例的图片大小和数量 -maxxangle 20 \ # 数据加强:容许的最大的x方向的偏转角 -maxyangle 20 \ # 容许的最大的y方向的偏转角
opencv_traincascade -data data \ # 模型xml文件保存的目录 -vec face.vec \ # 数据集文件 -bg /startdt_data/face_datasets/opencv_face_dataset/train/neg/info.dat \ -numPos 4200 \ # 这里的数量须要比实际写入的正例图片要小,否则可能会报错 -numNeg 32000 \ # 负例图片数 -numStages 5 \ # stage数越多,训练效果越好,可是耗时也越长 -numThreads 6 \ -featureType LBP \ # 官方文档里面没有说支持HOG,可是在opencv3.4中,经过命令行能够看到有这个参数 ,虽然能够训练,可是已经不支持 -w 112 \ -h 112 \ -precalcValBufSize 4096 \ # (in Mb) Size of buffer for precalculated feature values; size larger, training faster -precalcIdxBufSize 4096
import cv2 face_detector = cv2.CascadeClassifier("cascade.xml") img = "test.jpg" frame = cv2.imread(img) frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = face_detector.detectMultiScale(frame, 1.3, 3) for face in faces: cv2.rectangle(frame, (face[0], face[1]), (face[0]+face[2],face[1]+face[3]), (0, 0, 255), 2) cv2.imshow("test", frame) cv2.waitKey(0)
虽然cascade classifier的HOG特征在3.x版本是不能用了(2.4版本仍是能够的),可是能够用opencv samples/cpp/train_HOG.cpp
(或者是这个库)
首先须要编译.cpp
文件得到.o
文件(编译opencv的sample文件能够看这里):函数
g++ `pkg-config --cflags --libs opencv` -o train_HOG opencv/samples/cpp/train_HOG.cpp
训练:测试
train_HOG --dw=112 \ # 图像的检测窗口高度 --dh=112 \ # 图像的检测窗口高度(与图像有关,可是必须为8的整数倍--脚本内划窗方式决定) -d \ # 训练2次(提升精度) --fn=hog_face_detector.xml \ # 输出训练模型文件 -f \ --nd=opencv_face_dataset/train_hog/neg \ # 负例文件目录 --pd=opencv_face_dataset/train_hog/pos \ # 正例文件目录 --td=opencv_face_dataset/train_hog/val \ # 测试文件目录 --tv=test.mp4 # 测试视频文件
测试:命令行
import cv2 hog_face_file = "hog_face_detector.xml" hog_model = cv2.HOGDescriptor() hog_model.load(hog_face_file) win_stride = (8, 8) padding = (16, 16) scale = 1.05 cam = cv2.VideoCapture(0) while cam.isOpened(): ret, frame = cam.read() if ret: detect_region = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY) faces = hog_model.detectMultiScale(detect_region, winStride=win_stride, padding=padding, scale=scale) # 返回tuple(array of bounding box, array of bounding box confidence) faces = list(faces[0]) if len(faces): face = faces[0] # 只取几率最高的一我的脸 cv2.rectangle(frame, (face[0], face[1]), (face[0]+face[2], face[1]+face[3]), (0, 0, 255), 2) cv2.imshow("test", frame) if cv2.waitKey(1) == ord("q"): break cv2.destroyAllWindows()
具体参数意义能够参考这里code
cascade classifier:
train_HOG