dlib是人脸检测领域内的大拿,非常好用,提供了python版本和c++版本,非常友好。
在从github https://github.com/davisking/dlib 上clone下来的源码中,在python_example文件夹中提供了train_object_detector.py文件。这个文件就是帮助开发者对特定内容进行训练,进而达到检测的目的,而不仅仅是针对人脸。
dlib的训练是基于HOG(Histograms of Oriented Gradients,方向梯度直方图)的检测器,可以用来对脸、行人等其他半刚性物体(此处我认为刚性物体的效果会更好)进行检测。方案的起源是2005年的论文Histograms of Oriented Gradients for Human Detection by Dalal and Triggs。
接下里是代码分析:
(dlib的安装此处就不说了,linux下直接pip install dlib就可以了)
#这个没得讲,python引入库
import os
import sys
import glob
import dlib
#首先是指定训练集的所在位置,以原有的作为样例,是examples/faces. 将这个路径作为参数输入,执行 python train_object_detector.py ../examples/faces
if len(sys.argv) != 2:
print( "Give the path to the examples/faces directory as the argument to this program. For example, if you are in the python_examples folder then execute this program by running: ./train_object_detector.py ../examples/faces")
exit()
faces_folder = sys.argv[1]
# 接下来开始准备训练,利用函数 train_simple_object_detector(),首先准备设定函数的参数(许多都是已经设定好的)
options = dlib.simple_object_detector_training_options()
# 由于人脸左右对称,所以设置检测器左右对称。
options.add_left_right_image_flips = True
# 设置检测器的C参数。这个检测器是基于HOG的SVM,所以这个C参数就是SVM中的C参数。一般来讲,C大一点会好,但过大也会导致过拟合。因此需要多尝试几次C,看不同的训练结果在测试集上的表现而确定。
options.C = 5 #需要自己调整
# 设置可用于训练的CPU核数,一般来说CPU是多少核的就填多少核,会快一点。
options.num_threads = 4
options.be_verbose = True
#指定标注文件的路径,包括训练集和测试集
training_xml_path = os.path.join(faces_folder, "training.xml")
testing_xml_path = os.path.join(faces_folder, "testing.xml")
# 接下来启动开始训练,函数是train_simple_object_detector,它会导入上面的xml文件和上面设定的option,进行训练,并将训练结果存入detector.svm文件中。xml文件的产生可以自己用labelimg标注,dlib也提供了标注工具tools/imglab进去编译就可以使用了
dlib.train_simple_object_detector(training_xml_path, "detector.svm", options)
#到达这一步,训练就完成了。
#然后第一步在训练集上进行测试,看是否过拟合,
print("Training accuracy: {}".format(dlib.test_simple_object_detector(training_xml_path, "detector.svm")))
#第二步,如果不过拟合,在测试机上看检测效果
print("Testing accuracy: {}".format(dlib.test_simple_object_detector(testing_xml_path, "detector.svm")))
#上面两步如果都不错,说明我们现在得到了一个检测器,可以用于一个应用或者项目了。
# 首先载入训练好的模型文件detector.svm
detector = dlib.simple_object_detector("detector.svm")
# 看下模型文件的样子,像个人脸
win_det = dlib.image_window()
win_det.set_image(detector)
# 可以使用了
print("Showing detections on the images in the faces folder...")
win = dlib.image_window()
for f in glob.glob(os.path.join(faces_folder, "*.jpg")):
print("Processing file: {}".format(f))
img = dlib.load_rgb_image(f)
dets = detector(img)
print("Number of faces detected: {}".format(len(dets)))
for k, d in enumerate(dets):
print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
k, d.left(), d.top(), d.right(), d.bottom()))
win.clear_overlay()
win.set_image(img)
win.add_overlay(dets)
dlib.hit_enter_to_continue()
#使用完毕
#高级功能
# 在实际应用中,我们会训练很多个检测器(毕竟,目标很少只有有一种),然后把这些检测器放在一起使用,代码如下:
detector1 = dlib.fhog_object_detector("detector.svm")
detector2 = dlib.fhog_object_detector("detector.svm")
detectors = [detector1, detector2]
image = dlib.load_rgb_image(faces_folder + '/2008_002506.jpg')
[boxes, confidences, detector_idxs] = dlib.fhog_object_detector.run_multiple(detectors, image, upsample_num_times=1, adjust_threshold=0.0)
for i in range(len(boxes)):
print("detector {} found box {} with confidence {}.".format(detector_idxs[i], boxes[i], confidences[i]))
#完毕
#最后附件一点。如果你已经知道训练图像以及其对应的标注数据,可以不使用xml文件作为输入进行训练,而只需这样操作: (实例中训练集只有两张图)
images = [dlib.load_rgb_image(faces_folder + '/2008_002506.jpg'),dlib.load_rgb_image(faces_folder + '/2009_004587.jpg')]
boxes_img1 = ([dlib.rectangle(left=329, top=78, right=437, bottom=186),dlib.rectangle(left=224, top=95, right=314, bottom=185),dlib.rectangle(left=125, top=65, right=214, bottom=155)])
boxes_img2 = ([dlib.rectangle(left=154, top=46, right=228, bottom=121),dlib.rectangle(left=266, top=280, right=328, bottom=342)])
boxes = [boxes_img1, boxes_img2]
detector2 = dlib.train_simple_object_detector(images, boxes, options)
detector2.save('detector2.svm')
# 搞定