人脸识别一般包括人脸检测、识别2大方面,其中有些还需要对人脸进行校正,定位以便达到更准确。本文主要在检测和识别2个方面,做个简单的实时的实现。
人脸图像文件夹分布格式
简单的人脸识别示例代码如下:
%% 导入原始图像(640*480).其中srcPath路径下有若干个文件夹,
% 每个文件夹下为同一个人的图片(至少15张,越多越好),文件夹名字为该人的姓名
srcPath = 'E:\Temp';
imds = imageDatastore(srcPath,...
'LabelSource','foldernames',...
'includesubfolder',true,...
'FileExtensions','.jpg');
%% 检测并保存人脸为png格式,小图人脸
faceDetector = vision.CascadeObjectDetector;
for i = 1:length(imds.Files)
I = readimage(imds,i);
bboxes = step(faceDetector, I);
maxRect = [];
for j = 1:size(bboxes,1)
if bboxes(j,3)>=bboxes(1,3)
maxRect = bboxes(j,:);
end
end
if ~isempty(maxRect)
faceImg = imcrop(I,maxRect);
[dstPath,imageName,~] = fileparts(imds.Files{i});
imwrite(faceImg,fullfile(dstPath,[imageName,'.png']));
end
end
%% 导入检测到的人脸图像png
imdsFace = imageDatastore(srcPath,...
'LabelSource','foldernames',...
'includesubfolder',true,...
'FileExtensions','.png',...
'ReadFcn',@IMAGERESIZE);
[imdsTrain,imdsTest] = splitEachLabel(imdsFace,10);
%% 画图看训练的数据集
numsCategories = length(categories(imdsTrain.Labels));
I = zeros(150,150,3,numsCategories*10);% 图像大小为150*150*3,有numsCategories*10张图像
for i = 1:numsCategories*10
I(:,:,:,i) = readimage(imdsTrain,i);
end
montage(uint8(I),'size',[numsCategories,10]);
%% 提取LBP特征
numTrain = length(imdsTrain.Labels);
image1 = rgb2gray(readimage(imdsTrain,1));
feature1 = extractLBPFeatures(image1, 'Upright',true,'cellsize',[18 18]);
featuresMat = zeros(numTrain,length(feature1));
for i = 1:numTrain
image = rgb2gray(readimage(imdsTrain,i));
featuresMat(i,:) = extractLBPFeatures(image, 'Upright',true,'cellsize',[18 18]);
end
%% test
numCorrect = 0;
numTest = length(imdsTest.Files);
for i = 1:numTest
grayTest = rgb2gray(readimage(imdsTest,i));
featureTest = extractLBPFeatures(grayTest,'Upright',true,'cellsize',[18 18]);
actualLabel = imdsTest.Labels(i);
%% predict
minDist = realmax;
minIndex = 1;
for j =1:numTrain
currentDist = sum((featureTest-featuresMat(j,:)).^2);
if currentDist<minDist
minDist = currentDist;
predictLabel = imdsTrain.Labels(j);% categorical类型
minIndex = j;
end
end
%% 统计正确的个数
grayActual = rgb2gray(readimage(imdsTrain,minIndex));
figure;imshowpair(grayActual,grayTest,'montage');
if predictLabel == actualLabel
numCorrect = numCorrect+1;
end
end
disp(['正确率:',num2str(numCorrect/numTest)])
%% -----------------------------------隔断-----------------
%% 识别并显示
cam = webcam();% 摄像头接口,没有的话从matlab central网站搜索下载
detector = vision.CascadeObjectDetector('lbpcascade_frontalface.xml');
detector.MinSize = [110,110];
videoPlayer = vision.VideoPlayer;
fig = figure;
axes('parent',fig)
while ishandle(fig)
I = snapshot(cam);
bboxes = step(detector, I);
maxRect = [];
for j = 1:size(bboxes,1)
if bboxes(j,3)>=bboxes(1,3)
maxRect = bboxes(j,:);
end
end
if ~isempty(maxRect)&&(maxRect(1,3)>100)
faceImg = imcrop(I,maxRect);
grayTest = rgb2gray(faceImg);
grayTest = imresize(grayTest,[150,150]);
featureTest = extractLBPFeatures(grayTest,'Upright',true,'cellsize',[18 18]);
%% predict
minDist = realmax;
minIndex = 1;
for j =1:numTrain
currentDist = sum((featureTest-featuresMat(j,:)).^2);
if currentDist<minDist
minDist = currentDist;
predictLabel = imdsTrain.Labels(j);% categorical类型
minIndex = j;
end
end
strLabels = char(predictLabel);
RGB = insertObjectAnnotation(I,'rectangle',maxRect,strLabels,'color','g');
step(videoPlayer,RGB);
end
end
第85行代码如果webcam()报错,可以去这个网站下载usb摄像头接口函数,https://cn.mathworks.com/matlabcentral/fileexchange/49749--webcam-support--demo-files
程序中用到的分类器为OpenCV的人脸检测分类器“lbpcascade_frontalface.xml”,这里给出下载地址:https://pan.baidu.com/s/1JLep6nVWTOXppa2M0crerw 密码: 3wuc
其中用到的人脸归一化小图形函数IMAGERESIZE为:
function output = IMAGERESIZE(input)
input = imread(input);
output = imresize(input,[150,150]);
识别效果图:
注意:imageDatastore为Matlab2016a引进的函数,适合大数据图像导入。如果您的版本过低,请改用其他检索图片的函数,如dir。