代码本身是在CSDN上下载其他老哥分享出来的包,用途是对图像进行处理,截出人脸部分并保存。根据自己的实际情况,我对主函数进行了一定少量修改,目前程序已经能正常跑通了。但是其中有很多被调用的.m文件,我并没有看明白处理过程,希望有好心的人指点一下,为我讲解一下这些函数。
主函数
currentPath = 'D:\Graduation project\T\';
image = imageDatastore(fullfile(currentPath),'IncludeSubfolders',true,'LabelSource','foldernames');
SavePath = 'D:\Graduation project\save\';
numImages = length(image.Files);
imagedata = readimage(image,2);
tt = image.Files(2);
tt1 = regexp(tt,'\','split');
cellLength = cellfun('length',tt1);
imagename = char(tt1{1}(1,cellLength));
save_path=[SavePath,imagename];
detector = buildDetector();
[bbox, bbimg, faces, bbfaces] = detectFaceParts(detector,imagedata,0);
for a=1:size(bbfaces,1)
imwrite(bbfaces{a},save_path);
end
buildDetector
function detector = buildDetector( thresholdFace, thresholdParts, stdsize )
if( nargin < 1 )
thresholdFace = 1;
end
if( nargin < 2 )
thresholdParts = 1;
end
if( nargin < 3 )
stdsize = 176;
end
nameDetector = {'LeftEye'; 'RightEye'; 'Mouth'; 'Nose'; };
mins = [[12 18]; [12 18]; [15 25]; [15 18]; ];
detector.stdsize = stdsize;
detector.detector = cell(5,1);
for k=1:4
minSize = int32([stdsize/5 stdsize/5]);
minSize = [max(minSize(1),mins(k,1)), max(minSize(2),mins(k,2))];
detector.detector{k} = vision.CascadeObjectDetector(char(nameDetector(k)), 'MergeThreshold', thresholdParts, 'MinSize', minSize);
end
detector.detector{5} = vision.CascadeObjectDetector('FrontalFaceCART', 'MergeThreshold', thresholdFace);
function ret = checkToolboxes(req)
info = ver;
s=size(info);
flg = zeros(size(req));
reqSize = size(req,2);
for i=1:s(2)
for j=1:reqSize
if( strcmpi(info(1,i).Name,req{1,j}) )
flg(1,j)=1;
end
end
end
ret = prod(flg);
function [bbox,bbX,faces,bbfaces] = detectFaceParts(detector,X,thick)
if( nargin < 3 )
thick = 1;
end
% Detect faces
bbox = step(detector.detector{5}, X);
bbsize = size(bbox);
partsNum = zeros(size(bbox,1),1);
nameDetector = {'LeftEye'; 'RightEye'; 'Mouth'; 'Nose'; };
mins = [[12 18]; [12 18]; [15 25]; [15 18]; ];
stdsize = detector.stdsize;
for k=1:4
if( k == 1 )
region = [1,int32(stdsize*2/3); 1, int32(stdsize*2/3)];
elseif( k == 2 )
region = [int32(stdsize/3),stdsize; 1, int32(stdsize*2/3)];
elseif( k == 3 )
region = [1,stdsize; int32(stdsize/3), stdsize];
elseif( k == 4 )
region = [int32(stdsize/5),int32(stdsize*4/5); int32(stdsize/3),stdsize];
else
region = [1,stdsize;1,stdsize];
end
bb = zeros(bbsize);
for i=1:size(bbox,1)
XX = X(bbox(i,2):bbox(i,2)+bbox(i,4)-1,bbox(i,1):bbox(i,1)+bbox(i,3)-1,:);
XX = imresize(XX,[stdsize, stdsize]);
XX = XX(region(2,1):region(2,2),region(1,1):region(1,2),:);
b = step(detector.detector{k},XX);
if( size(b,1) > 0 )
partsNum(i) = partsNum(i) + 1;
if( k == 1 )
b = sortrows(b,1);
elseif( k == 2 )
b = flipud(sortrows(b,1));
elseif( k == 3 )
b = flipud(sortrows(b,2));
elseif( k == 4 )
b = flipud(sortrows(b,3));
end
ratio = double(bbox(i,3)) / double(stdsize);
b(1,1) = int32( ( b(1,1)-1 + region(1,1)-1 ) * ratio + 0.5 ) + bbox(i,1);
b(1,2) = int32( ( b(1,2)-1 + region(2,1)-1 ) * ratio + 0.5 ) + bbox(i,2);
b(1,3) = int32( b(1,3) * ratio + 0.5 );
b(1,4) = int32( b(1,4) * ratio + 0.5 );
bb(i,:) = b(1,:);
end
end
bbox = [bbox,bb];
p = ( sum(bb') == 0 );
bb(p,:) = [];
end
%%%%%%%%%%%%%%%%%%%%%%% draw faces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
bbox = [bbox,partsNum];
bbox(partsNum<=2,:)=[];
if( thick >= 0 )
t = (thick-1)/2;
t0 = -int32(ceil(t));
t1 = int32(floor(t));
else
t0 = 0;
t1 = 0;
end
bbX = X;
boxColor = [[0,255,0]; [255,0,255]; [255,0,255]; [0,255,255]; [255,255,0]; ];
for k=5:-1:1
shapeInserter = vision.ShapeInserter('BorderColor','Custom','CustomBorderColor',boxColor(k,:));
for i=t0:t1
bb = int32(bbox(:,(k-1)*4+1:k*4));
bb(:,1:2) = bb(:,1:2)-i;
bb(:,3:4) = bb(:,3:4)+i*2;
bbX = step(shapeInserter, bbX, bb);
end
end
%%%%%%%%%%%%%%%%%%%%%%% faces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
if( nargout > 2 )
faces = cell(size(bbox,1),1);
bbfaces = cell(size(bbox,1),1);
for i=1:size(bbox,1)
faces{i,1} = X(bbox(i,2):bbox(i,2)+bbox(i,4)-1,bbox(i,1):bbox(i,1)+bbox(i,3)-1,:);
bbfaces{i,1} = bbX(bbox(i,2):bbox(i,2)+bbox(i,4)-1,bbox(i,1):bbox(i,1)+bbox(i,3)-1,:);
end
end
function [fourpoints,bbX,faces,bbfaces] = detectRotFaceParts(detector,X,thick,rotate)
if( nargin < 4 )
rotate = 15;
end
if( nargin < 3 )
thick = 1;
end
rotate = [0:rotate:360-rotate/2];
srcOrg = [size(X,2);size(X,1)]/2+0.5;
fourpoints = [];
k = 1;
for deg = rotate
R = imrotate(X,deg,'bicubic');
bbox = detectFaceParts(detector,R);
if( size(bbox,1) >= 1 )
dstOrg = [size(R,2);size(R,1)]/2+0.5;
fourpoints = vertcat(fourpoints,bbox2fourpoint(bbox,srcOrg,dstOrg,deg));
end
end
fourpoints = mergeFourPoints(fourpoints);
if( nargout >= 2 )
bbX = drawFourPoints(X,fourpoints,thick);
if( nargout >= 3 )
faces = cell(size(fourpoints,1),1);
bbfaces = cell(size(fourpoints,1),1);
leng = round(sqrt( three2area( fourpoints(:,1:2), fourpoints(:,3:4), fourpoints(:,5:6) ) + three2area( fourpoints(:,1:2), fourpoints(:,7:8), fourpoints(:,5:6) ) ));
for i=1:size(fourpoints,1)
U = [1,1;leng(i,1)-1,1;leng(i,1)-1,leng(i,1)-1;1,leng(i,1)-1];
V = [fourpoints(i,1:2); fourpoints(i,3:4); fourpoints(i,5:6); fourpoints(i,7:8)];
T = maketform('projective',V,U);
faces{i,1} = imtransform(X,T,'bicubic','XData',[1,leng(i,1)],'YData',[1,leng(i,1)]);
bbfaces{i,1} = imtransform(bbX,T,'bicubic','XData',[1,leng(i,1)],'YData',[1,leng(i,1)]);
end
end
end
function fourpoint = bbox2fourpoint( bbox, srcOrg, dstOrg, deg )
T = [cos(deg*pi/180), -sin(deg*pi/180); sin(deg*pi/180), cos(deg*pi/180)];
fourpoint = zeros(size(bbox,1), 2*4*5+1);
for i=1:size(bbox,1)
for j=0:4
if( bbox(i,j*4+1) > 0 && bbox(i,j*4+2) > 0 )
x = bbox(i,j*4+1:j*4+2)' - dstOrg;
y = T * x + srcOrg;
fourpoint(i,j*8+1:j*8+2) = y';
x = bbox(i,j*4+1:j*4+2)' + [bbox(i,j*4+3);0] - dstOrg;
y = T * x + srcOrg;
fourpoint(i,j*8+3:j*8+4) = y';
x = bbox(i,j*4+1:j*4+2)' + [bbox(i,j*4+3);bbox(i,j*4+4)] - dstOrg;
y = T * x + srcOrg;
fourpoint(i,j*8+5:j*8+6) = y';
x = bbox(i,j*4+1:j*4+2)' + [0;bbox(i,j*4+4)] - dstOrg;
y = T * x + srcOrg;
fourpoint(i,j*8+7:j*8+8) = y';
end
end
fourpoint(i,2*4*5+1) = deg;
end
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
function area = three2area(xy1, xy2, xy3)
xy1 = xy1 - xy3;
xy2 = xy2 - xy3;
area = abs( xy1(:,1) .* xy2(:,2) - xy1(:,2) .* xy2(:,1) ) / 2;
function Y = drawFourPoints( X, fourpoints, thick )
if( nargin < 3 )
thick = 1;
end
Y = X;
if( size(fourpoints,1) > 0 )
boxColor = [[0,255,0]; [255,0,255]; [255,0,255]; [0,255,255]; [255,255,0]; ];
M=int32(fourpoints);
if( thick >= 0 )
t = (thick-1)/2;
t0 = -int32(ceil(t));
t1 = int32(floor(t));
else
t0 = 0;
t1 = 0;
end
for k=5:-1:1
shapeInserter = vision.ShapeInserter('Shape','Lines','BorderColor','Custom','Antialiasing',true,'CustomBorderColor',boxColor(k,:));
N = horzcat(M(:,(k-1)*8+1:(k-1)*8+8),M(:,(k-1)*8+1:(k-1)*8+2));
for i=t0:t1
NN = N;
NN(:,[1,3,5,7,9]) = N(:,[1,3,5,7,9]) + i;
Y = step(shapeInserter, Y, NN);
NN = N;
NN(:,[2,4,6,8,10]) = N(:,[2,4,6,8,10]) + i;
Y = step(shapeInserter, Y, NN);
end
end
end
function dst = mergeFourPoints(src)
if( size(src,1) > 0 )
pos = zeros(size(src,1),2);
pos(:,1) = mean(src(:,[1,3,5,7]),2);
pos(:,2) = mean(src(:,[2,4,6,8]),2);
pos = horzcat(pos,[1:size(src,1)]');
dst = [];
while( ~isempty(pos) )
if( size(pos,1) == 1 )
dst = vertcat(dst,src(pos(1,3),:));
pos = [];
else
tmp = src(pos(1,3),:);
rad = norm(pos(1,1:2) - tmp(1,1:2)) + norm(pos(1,1:2) - tmp(1,3:4)) + norm(pos(1,1:2) - tmp(1,5:6)) + norm(pos(1,1:2) - tmp(1,7:8));
th = rad / 8;
p = 1;
for i=2:size(pos,1)
rad = norm(pos(1,1:2) - pos(i,1:2));
if( rad < th )
tmp = vertcat(tmp,src(pos(i,3),:));
p = horzcat(p,i);
end
end
if( size(tmp,1) > 1 )
num = tmp > 0;
tmp = sum(tmp) ./ sum(num);
end
dst = vertcat(dst,tmp);
pos(p,:) = [];
end
end
else
dst = src;
end
clc
clear
currentPath = 'D:\Graduation project\T\002.jpg';
faceDetector = vision.CascadeObjectDetector;
I = imread(currentPath);
bboxes = faceDetector(I);
IFaces = insertObjectAnnotation(I,'rectangle',bboxes,'Face');
figure
imshow(IFaces)
title('Detected faces');