python+opencv处理人脸数据集。

本文主要做了以下的工作:

把数据集中的人脸抠出来,单独作为人脸的数据。(已经有了图片中人脸的位置,放在.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+的人脸数据,所以这里就不放数据集了,有需要的可以评论留言。)





评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值