台风天整理下这段时间做的东西。前段时间帮师兄做了一个人脸情绪识别的数据预处理,年纪大了,记性不大好,现在来Mark一下。

工具:Matlab

数据集:cohn-kanade-images

如图:我把数据集放在G盘

以知道上图有123个文件夹,一个文件夹表示一个人

假如打开其中一个文件夹S005,可以看到有1个子文件夹,一个子文件夹代表这个人的一种情绪。

DS_Store (Desktop Services Store)是苹果Mac OS X 操作系统用于储存某个文件夹图标位置和背景图片一类属性的文件,在这里对我处理图片没有用处,需要去掉。

接下来打开001文件夹,可以看到这个人的人脸情绪变化过程,这是从一个视频中得到的,所以在这里我们需要最典型的表情来作为我们的数据集

而在对应的另一个文件夹含有每种人脸情绪的标签,比如开心、愤怒、惊讶等,在这里分别标为1、2、3...等类别

打开S005的001子文件夹可以看到标签

首先将各文件夹中的.DS_Store文件删除,但又有另外的问题就是相关的有些情绪文件夹没有标签,存在空文件夹

这时在遍历过程中就需要仔细判断,如果是空文件就删除

首先是遍历G:\人脸情绪数据集\Emotion中的S开头的123个子文件夹,第一个进入到G:\人脸情绪数据集\Emotion\S005,在遍历S005中的文件夹,判断是否存在空文件夹,如果存在,那么记录路径信息,同时删除对应的人脸情绪图片的文件夹(因为没有了标签的图片失去了用处)

在删除了没有标签的人脸图片文件夹以后,需要挑选最典型的的人脸情绪作为训练集,我对每个情绪图片挑选了5张,如图

以上是最典型的这种情绪的5幅图

但是这个图像存在很多没有用的部分,我只需要人脸这块位置,而且在做人脸情绪识别时,一张图片如果是500*500像素,那么转换成一行将是个特征,一个是会降低识别率,另一个会造成电脑运算量的指数级增长。但是视频中,每个人的人脸位置都是不一样的,如果手动提取的话势必非常浪费时间

在这里我首先采用

经过人脸检测以后裁剪人脸图片得到

为了便于计算,将人脸图片缩小为64*64

存到对应的文件夹即可。

人脸识别检测程序如下:

%===============================================================================

%函数名称:face_segment

%输入参数:mImageSrc,待分割的人脸图像,可能是灰度图像,也可能是彩色图像

%输出参数:mFaceResult,分割后的人脸结果,应为灰度图像

%主要步骤:1)进行人脸检测,得到脸部区域的框框

%         2)得到脸部图像框的中心点

%         3)根据中心点,对图像进行等比例外扩,得到合适大小的人脸图像

%注意事项:1)首先需要判断该图像是否为灰度图,若为灰度图,需要先将其转换为三通道彩色图

%===============================================================================

function mFaceResult = face_segment(mImageSrc)

%%%%%%%%%%%%%%%%%%%%将灰度图变为三通道图%%%%%%%%%%%%%%%%%%%%

%mImageSrc = imread('G:\cohn-kanade-images\S154\002\S154_002_.png');

if(size(mImageSrc,3) == 1)

mImage2detect(:,:,1) = mImageSrc;

mImage2detect(:,:,2) = mImageSrc;

mImage2detect(:,:,3) = mImageSrc;

mImage2detect = mImageSrc;

%%%%%%%%%%%%%%%%%%%%对图像进行人脸检测%%%%%%%%%%%%%%%%%%%%

FaceDetector               = buildDetector();

[bbox,bbimg,faces,bbfaces] = detectFaceParts(FaceDetector,mImage2detect,2);

%%%%%%%%%%%%%%%%%%%%输入图像灰度化%%%%%%%%%%%%%%%%%%%%

if 1 ~= size(mImageSrc,3)

mImageSrc = rgb2gray(mImageSrc);

mImageSrc = double(mImageSrc);

elseif 1     == size(mImageSrc,3)

mImageSrc = double(mImageSrc);

%%%%%%%%%%%%%%%%%%%%得到人脸区域框的中心点%%%%%%%%%%%%%%%%%%%%

recFace.x          = bbox(1,1);  %224

recFace.y          = bbox(1,2);  %94

recFace.width      = bbox(1,3);  %309

recFace.height     = bbox(1,4);  %309

ptFaceCenter.x     = recFace.x + recFace.width / 2;  %224+309/2

ptFaceCenter.y     = recFace.y + recFace.height / 2; %94+309/2

%%%%%%%%%%%%%%%%%%%%以中心点为基准进行外扩(即对人脸选框进行调整)%%%%%%%%%%%%%%%%%%%%

recFace.x         = ptFaceCenter.x - recFace.width * 0.4;   %254.9

recFace.y         = ptFaceCenter.y - recFace.height * 0.35;  %140.35

recFace.width     = recFace.width * 0.8 ;  %247.2

recFace.height    = recFace.height * 0.9 ; %278.1

mFaceResult       = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));

%%手动处理图片

% mImageSrc = imread('G:\cohn-kanade-images\S154\002\S154_002_.png');

% if 1 ~= size(mImageSrc,3)

%     mImageSrc = rgb2gray(mImageSrc);

%     mImageSrc = double(mImageSrc);

% elseif 1     == size(mImageSrc,3)

%     mImageSrc = double(mImageSrc);

% mFaceResult = uint8(imcrop(mImageSrc,[recFace.x,recFace.y,recFace.width,recFace.height]));

% imwrite(mFaceResult,strcat('G:\FaceDetection\S154\002\',int2str(2),'.bmp'));

批量自动处理文件夹中的图片程序如下:

ImageSavePath  = 'G:\resize64\';

FaceResize = 'G:\resize64';

FaceDetection ='G:\FaceDetection';

images_dir = 'G:\Emotion';

images_dir_txt = 'G:\Emotion';  %最初文件夹的路径

images_dir_pic = 'G:\cohn-kanade-images';

D = dir(FaceResize);  %打开最初文件夹

%返回一个结构数组,第1个数组元素和第2个数组元素分别是'.'和'..',表示当前目录和上层目录。

images_files_num = size(D,1);   %最初文件夹里含有的子文件个数

P = [];  %train_data的变量

T = [];  %train_test的变量

for k = 3:images_files_num  %循环子文件夹

images_name = D(k);     %第k个子文件结构数组

images_deep_dir = [FaceResize '\' images_name.name];%得到第k个子文件夹的名字加到打开的路径里

D_deep = dir(images_deep_dir);    %打开第k个子文件夹

images_deep_files_num = size(D_deep,1);    %第k个子文件夹含有的子子文件个数

sum = sum+images_deep_files_num-2;

name_of_folder_k = [images_name.name];

for i = 3:images_deep_files_num    %循环子子文件夹

images_deep_name = D_deep(i,1);  %第k个子文件夹中含有的第i个子子文件夹名字

images_deep_deep_dir = [images_deep_dir '\' images_deep_name.name];%第i个子子文件夹的路径

name_of_folder_i = [name_of_folder_k '\' images_deep_name.name];

D_deep_deep = dir(images_deep_deep_dir); %打开第i个子子文件夹

D_deep_deep_num = size(D_deep_deep,1);  %3

%提取子文件夹名字,大于等于3表示文件夹非空

if D_deep_deep_num >= 3

A = [A ;name_of_folder_i];

A(end-3:end)=[];

C = [C ;A];

%提取子子文件夹名字

if D_deep_deep_num >= 3

B = [B ;name_of_folder_i];

E = [E ;B];

ImageSavePath_i = [ImageSavePath A];

%         mkdir(ImageSavePath,A);

images_deep_deep_files_num = size(D_deep_deep,1); %第i个子子文件夹中的图片数量

%         mkdir(ImageSavePath_i,E);

for j = 3:images_deep_deep_files_num   %循环图片个数

ImageSavePath_j = [ImageSavePath_i '\' E '\'];

%读取文本里的标签

Label_dir = [images_dir_txt '\' C '\'  E];

Label_images = dir(Label_dir);

Label_images_num = size(Label_images,1);

Label_images_true = Label_images(3,:);

true_path = [Label_dir '\' Label_images_true.name];

txt_read = uint8(textread(true_path));

T = [T;txt_read];

%  Label = [Label

images_deep_deep_name = D_deep_deep(j);  %第j张图片的结构数组

images_deep_deep_deep_dir = [images_deep_deep_dir '\' images_deep_deep_name.name];%路径

name_of_folder_j = [name_of_folder_i '\' images_deep_deep_name.name];

I = imread(images_deep_deep_deep_dir);

[m,n,l] = size(I);  %图像的大小,通道数

for a = 1:m

for b = 1:n

c(q) = I(a,b);

%             %人脸识别检测截取

%             iSaveNum = int2str(j-2);

%             mFaceResult = face_segment(I);

%             imwrite(mFaceResult,strcat(ImageSavePath_j,iSaveNum,'.bmp'));

%将得到的人脸照片转化为灰度图

%             if l == 3

%                 J = rgb2gray(I);

%             else

%                 J = I;

%             end

%              H2=DSLBP(X,mapping,W);%提取图片的LBP直方图

%              RECT = [217 100 300 330];   %X轴Y轴坐标以及图像长宽的大小

%              P = imcrop(J,RECT);

%              X = double(P);

%              X = 255*imadjust(X/255,[0.3;1],[0;1]);%光照补偿(可以不用,效果差不多)

%将图片变为64*64存放好

%               iSaveNum = int2str(j-2);

%               X = imresize(J,[64 64],'bilinear');  %采用'bilinear':采用双线性插值算法扩展为64*64

%               imwrite(X,strcat(ImageSavePath_j,iSaveNum,'.bmp'));

%             figure, imshow(I),

%             figure, imshow(P),

%             figure, imshow(X),

%             figure, imshow(J);

%              break

%             name_of_folder_i = zeros(m,n,l,images_deep_deep_files_num-2);

%             name_of_folder_i(:,:,j-2) = I;

%        break

%    break

save_path = 'G:\FaceMotionData';

cd(save_path);

save train_label T;

save train_data P;

%% 删除空文件夹

% C_num = size(C,1);

% for c = 1:C_num

%     dir_c = [images_dir_txt '\' C(c,:)];   %删除文本的空文件夹