Task2 :Caffe-ssd Face Detection

0 绪论

使用 caffe 的步骤:
(1) convert data(run a script)
(2) Define net(edit prototxt)  网络结构
(3) Define solver(edit prototxt)  超参数
(4) Train(witjh pretrained weights)(run a script)

 

1. 数据打包:VOC 格式,lmdb 封装

1.1构造VOC 格式数据集:图片,xml标注

        VOC 含3个文件夹,Annotations、ImageSets、JPEGImages。其中Annotations存放xml格式的标注信息。ImageSets/Main目录存放文件名列表,train.txt、val.txt、test.txt。JPEGImages存放图片。
       VOC 中的图片仅拷贝即可。而标注数据,将真值文件解析成xml格式。人脸业务调用:writexml(filename,saveimg,bboxes,xmlpath)。
        xml文件采取节点-子节点的数据结构。

 1.1.1 write_xml 

	from xml.dom.minidom import Document 
	
	(1)doc = Document()  # 创建文件对象

	(2)doc.createElement()  # 用文件对象创建元素

	(3)doc.createTextNode()  # 用文件对象创建文本

	(4)node.appendChild()  # 在node之后追加对象
	
	(5)node.setAttribute('A','B') # 节点内 A = "B" 

	(6)f.write(doc.toprettyxml())  # 写入xml文件

凡是写节点或者写文本,都要遵循先创建元素,再添加的步骤。

详情参考:https://www.cnblogs.com/wcwnina/p/7222180.html

 1.1.2 解析原标注数据,生成VOC格式

       从数据集提供的标注文件中,解析出 write_xml 函数所需的入参,按照 VOC 格式进行封装。

 

1.2修改数据打包脚本的相关路径并运行,获得lmdb

在路径 caffe-ssd/data/widerface 下:

(1)修改labelmap,VOC原本含21个类别,人脸业务含2个类别,人脸和背景    
(2)修改文件 create_list.sh 并执行 :让 dataset_file 指向 Imageset/Main 下 trainval.txt 和 test.txt。对这两个列表文件进行随即排序、复制,在 widerface 这个目录下生成 trian.txt、test.txt 和 test_name_size.txt。
(3)修改文件 create_data.sh 并执行:让 mapfile 指向 caffe-ssd/data/widerface/labelmap_voc.prototxt。这个shell脚本执行了 caffe-ssd/scripts/create_annoset.py ,在存储原VOC格式数据的widerface文件夹下生成一个lmdb文件夹存放数据。

 

2. caffe 源码解读及优化

2.1 主干网络 : python/caffe/model_libs.py

这个文件中提供了多个定义主干网络结构的函数。

 

2.2 模型训练配置: examples/ssd/ssd_pascal.py

在 "# Create train/test net"之后,通过调用 model_libs.py 中的不同函数,选择主干网络结构。

 2.3 模型优化:提速

(1)减小模型: 修改 model_libs.py 定义网络结构中每一层的输出大小。
(2)去掉一些卷积层

 

3. caffe-ssd 测试

(1) 测试网络模型需要使用:deploy.prototxt 、 face.caffemodel 

(2) 实例化 caffe 模型:

net = caffe.Net(model_def,model_weight,caffe.TEST)

(3) 处理输入数据层:

image_data = caffe.io.load_image(img_path)

tranformer = caffe.io.Transformer({'data':net.blobs['data'].data.shape})

tranformer.set_transpose('data',(2,0,1))

tranformer.set_channel_swap('data',(2,1,0))

tranformer.set_mean('data',np.array([128,128,128]))

tranformer.set_raw_scale('data',255)

tranformer_image = tranformer.preprocess('data',image_data)

net.blobs['data'].reshape(1,3,300,300)
net.blobs['data'].data[...] = tranformer_image

(4) 解析并显示结果:

detect_out = net.forward()['detection_out']

# print(detect_out)

det_label = detect_out[0,0,:,1]
det_conf = detect_out[0,0,:,2]

det_xmin = detect_out[0,0,:,3]
det_ymin = detect_out[0,0,:,4]
det_xmax = detect_out[0,0,:,5]
det_ymax = detect_out[0,0,:,6]

top_indices = [i for i,conf in enumerate(det_conf) if conf >= 0]

top_conf = det_conf[top_indices]

top_xmin = det_conf[top_indices]
top_ymin = det_conf[top_indices]
top_xmax = det_conf[top_indices]
top_ymax = det_conf[top_indices]

[height,width,_] = image_data.shape

for i in range(min(5,top_conf.shape[0])):
    xmin = int(top_xmin[i] * width)
    ymin = int(top_ymin[i] * height)
    xmax = int(top_xmax[i] * width)
    ymax = int(top_ymax[i] * height)

    cv2.rectangle(image_data,(xmin,ymin),(xmax,ymax),(255,0,0),2)

cv2.imshow("face",image_data)

cv2.waitKey(0)

 

你可能感兴趣的:(caffe)