本文主要做了以下的工作:
把数据集中的人脸抠出来,单独作为人脸的数据。(已经有了图片中人脸的位置,放在.mat文件中)。
利用python+opencv以及标签的数据抠出人脸如下图
。
在这个实验中,可以学习到怎么在python中读.mat(MATLAB的文件),以及如何简单使用opencv
-----------------------------------------------------------------分割线----------------------------------------------------
准备工具:
到 http://mmlab.ie.cuhk.edu.hk/projects/WIDERFace/ 下载数据集。
。
前两个圈里面的是原始图像,第三个圈是标签文件。也就是图像中人脸位置的数据。(数据集准备好了)
----------------------------------------------------------------------------------------------------------------------
python版本建议用Anaconda2(2.7)的,因为这个集成了很多常会用到的库。
如果没有opencv的请到下面地址下载,名字是cv2.pyd ( Python2.7版本 3.5可能用不了)
http://pan.baidu.com/s/1o8qbp6y
如果有opencv在电脑里的,请到./Build/python/2.7/x64 下可以找到。
把上面的cv2.pyd放到python目录的./lib/site-package里面。
至此准备工作做完,下面就开始进入正题
-------------------------------------------------------------------------------------------------------------------------------------------------
由于机器学习很多时候的标签文件都是存放在.mat文件中的,所以对于初学者而不会matlab的人来说,.mat文件在Python中如何读取会感到很苦恼。
所以这一部分就简单介绍一下.mat文件。
我们把上面的人脸标签数据集下载下来后可以看到这些文件
可能下载下来后默认打开的类型不是.mat,更改的办法如下:
控制面板----程序----默认程序---将文件类型与程序关联
(不同的系统可能略有差异,但是大致都差不多)
打开wider_face_train.mat后。看到工作区。我的版本是2014的。
,这些都是这个.mat文件中所含有的标签类别。
例如这个 file_list 它是把所有训练集中的图片名字都放在了这里。具体点开进去就可以看到。下图中460x1 cell就是代表着里面一共有460个单元。
这是每个图片的名字。
其他标签也类似。这里再说一个相对比较复杂的就是人脸位置的标签数据。
这个是存放在face_bbx_list,点进去里面之后可以看到下面的结构
这里的第一行第一列的意思是:只有一个列表的数据(只有一个列表意味着只有一张人脸),这个列表里面有4个数据。
第一个数据和第二数据是代表人脸位置左上角的坐标点。(列,行)
第三个数据和第四个数据是代表宽度和高度。(可以在下载数据集的网站找到这些信息。)
同样,第四行第一列代表着,这里有9*4的数组,这个数组第一行代表第一个人脸的位置,第二行是第二个人人脸的位置,以此类推。
简单介绍完.mat文件后下面就是如何在python中读这些数据。
---------------------------------------------------------------------------------------------------------------------------------------------
在Python中读取.mat需要用到scipy.io模块,如果前面安装的时候Anaconda,你就可以直接import。
读取的时候主要是用到这以下几句:
import scipy.io
data=scipy.io.loadmat("val.mat")
FileName=data['file_list']
FileValue=data['face_bbx_list']
FileOcc=data['occlusion_label_list']
data['file_list']里面的file_list就是标签的名字。由于data是字典格式。所以可以用data.keys()去查询一下它所有标签的名字。
那么已经读了.mat的文件了,如何把数据显示出来呢?,注意到,下面这三个圈圈,其实就是我们显示的方法。
当然,这里是从1开始的,我们索引的时候要自然脑补到0.
因此,如果我们想显示0_Parade_marchingband_1_849这个文件名。方法就是
FileName[0][0][0][0]。
故,我们可以有如下的结论
FileName[n][x][k][y]中,n是第n个图像集(比方这里有共61有类),x是只能取0,因为file_list只有1列。k是第k个图片。y也只能取0.
所以,我们想第1类的所有图片名字程序如下:
for x in FileName[0][0]:
print x[0][0]
改成如下可以遍历所有训练样本的名字。
for k in range(61):
for x in FileName[k][0]:
print x[0][0]
同样,对于坐标的标签页可以这样读。会处理.mat数据后就是如何用opencv处理图片了。
---------------------------------------------------------------------------------------------------------------------------
这一部分涉及到的操作也不多,首先把cv2这个模块import进来。
import cv2
还用到把把图片读进来。
cv2.imread("path")
用图片按区域裁剪
crop=img[row:col]
最后是把图片保存
cv2.imwrite("path",crop)
------------------------------------------
最后附上程序的最关键的一部分,(简单版)。
noicecount=0
count=0
TIMES=0
index=0
picNum=0
RandCor=[]
FaceCor=[]
data=scipy.io.loadmat("val.mat")
FileName=data['file_list']
FileValue=data['face_bbx_list']
FileOcc=data['occlusion_label_list']
for step in range(61):
log=open("log.txt",'w')
for (i,j,p) in zip(FileName[step][0],FileValue[step][0],FileOcc[step][0]):
newstring=FindAddress(step)
print "THE k is",step
if(newstring==0):
continue
newstring=newstring+i[0][0]+'.jpg'
print newstring
img=cv2.imread(newstring)
if(img==None):
continue
FaceCor=[]
for k in range(j[0].shape[0]):
if int(j[0][k][2])<=50 and int(j[0][k][3])<=50 or p[0][k]!=0:
continue
crop=img[int(j[0][k][1]):int(j[0][k][1])+int(j[0][k][3]),int(j[0][k][0]):int(j[0][k][0])+int(j[0][k][2])]
count+=1
filename="E:/photo2/face"+str(count)+".jpg"
cv2.imwrite(filename,crop)
print count
FaceCor=FaceCor+[j[0][k]]
print FaceCor
if(FaceCor!=[]):
picNum=0
RandCor=RandomClipPhoto(FaceCor,img.shape[1],img.shape[0])
for w in range(len(RandCor)):
if(picNum==4):
break
picNum+=1
crop2=img[RandCor[w][1]:RandCor[w][1]+RandCor[w][3],RandCor[w][0]:RandCor[w][0]+RandCor[w][2]]
filename2="E:/random2/noice"+str(noicecount)+".jpg"
noicecount+=1
cv2.imwrite(filename2,crop2)
TIMES+=1# the processing image num
log.write(i[0][0]+" finish")
log.close()
-----------------------------------------------------------------------------------
这是效果图(由于数据集处理完后一共有29000+的人脸数据,所以这里就不放数据集了,有需要的可以评论留言。)