研究背景
自70年代以来.随着人工智能技术的兴起.以及人类视觉研究的进展.人们逐渐对人脸图像的机器识别投入很大的热情,并形成了一个人脸图像识别研究领域,.这一领域除了它的重大理论价值外,也极具实用价值。
在进行人工智能的研究中,人们一直想做的事情就是让机器具有像人类一样的思考能力,以及识别事物、处理事物的能力,因此从解剖学、心理学、行为感知学等各个角度来探求人类的思维机制、以及感知事物、处理事物的机制,并努力将这些机制用于实践,如各种智能机器人的研制。人脸图像的机器识别研究就是在这种背景下兴起的,因为人们发现许多对于人类而言可以轻易做到的事情,而让机器来实现却很难,如人脸图像的识别,语音识别,自然语言理解等。如果能够开发出具有像人类一样的机器识别机制,就能够逐步地了解人类是如何存储信息,并进行处理的,从而最终了解人类的思维机制。
同时,进行人脸图像识别研究也具有很大的使用价依。如同人的指纹一样,人脸也具有唯一性,也可用来鉴别一个人的身份。现在己有实用的计算机自动指纹识别系统面世,并在安检等部门得到应用,但还没有通用成熟的人脸自动识别系统出现。人脸图像的自动识别系统较之指纹识别系统、DNA鉴定等更具方便性,因为它取样方便,可以不接触目标就进行识别,从而开发研究的实际意义更大。
本文介绍了人脸图像识别中所应用MATLAB对图像进行预处理,应用该工具箱对图像进行经典图像处理,通过实例来应用matlab图像处理功能,对某一特定的人脸图像处理,进而应用到人脸识别系统。本文在总结分析人脸识别系统中几种常用的图像预处理方法基础上,利用MATLAB实现了一个集多种预处理方法于一体的通用的人脸图像预处理仿真系统,将该系统作为图像预处理模块可嵌入在人脸识别系统中,并利用灰度图像的直方图比对来实现人脸图像的识别判定。
其中涉及到图像的选取,脸部定位,特征提取,图像处理和识别几个过程。
(1)人脸图像的获取
一般来说,图像的获取都是通过摄像头摄取,但摄取的图像可以是真人,也可以是人脸的图片或者为了相对简单,可以不考虑通过摄像头来摄取头像,而是直接给定要识别的图像。
(2)人脸的检测
人脸检测的任务是判断静态图像中是否存在人脸。若存在人脸,给出其在图像中的坐标位置、人脸区域大小等信息。而人脸跟踪则需要进一步输出所检测到的人脸位置、大小等状态随时间的连续变化情况。
(3)特征提取
通过人脸特征点的检测与标定可以确定人脸图像中显著特征点的位置(如眼睛、眉毛、鼻子、嘴巴等器官),同时还可以得到这些器官及其面部轮廓的形状信息的描述。
根据人脸特征点检测与标定的结果,通过某些运算得到人脸特征的描述(这些特征包括:全局特征和局部特征,显式特征和统计特征等)。
(4)基于人脸图像比对的身份识别
即人脸识别(Face Identification)问题。通过将输入人脸图像与人脸数据库中的所有已知原型人脸图像计算相似度并对其排序来给出输入人脸的身份信息。这包括两类识别问题:一类是闭集(Close Set)人脸识别问题,即假定输入的人脸一定是人脸库中的某个个体;另一类是开集(Open Set)识别,即首先要对输入人脸是否在已知人脸库中做出判断,如果是,则给出其身份。
(5)基于人脸图像比对的身份验证
即人脸确认(Face Verification)问题。系统在输入人脸图像的同时输入一个用户宣称的该人脸的身份信息,系统要对该输入人脸图像的身份与宣称的身份是否相符作出判断。
三、算法流程实现
人脸检测定位程序:
i=imread('face1.jpg');
I=rgb2gray(i);
BW=im2bw(I);
figure,imshow(BW)
[n1 n2]=size(BW);
r=floor(n1/10);
c=floor(n2/10);
x1=1;x2=r;
s=r*c;
for i=1:10
y1=1;y2=c;
for j=1:10
if (y2<=c | y2>=9*c) | (x1==1 | x2==r*10)
loc=find(BW(x1:x2, y1:y2)==0);
[o p]=size(loc);
pr=o*100/s;
if pr<=100
BW(x1:x2, y1:y2)=0;
r1=x1;r2=x2;s1=y1;s2=y2;
pr1=0;
end
imshow(BW);
end
y1=y1+c;
y2=y2+c;
end
x1=x1+r;
x2=x2+r;
end
figure,imshow(BW)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%% detection of face object
L = bwlabel(BW,8);
BB = regionprops(L, 'BoundingBox');
BB1=struct2cell(BB);
BB2=cell2mat(BB1);
[s1 s2]=size(BB2);
mx=0;
for k=3:4:s2-1
p=BB2(1,k)*BB2(1,k+1);
if p>mx & (BB2(1,k)/BB2(1,k+1))<1.8
mx=p;
j=k;
end
end
figure,imshow(I);
hold on;
rectangle('Position',[BB2(1,j-2),BB2(1,j-1),BB2(1,j),BB2(1,j+1)],'EdgeColor','r' )
不同的人脸识别系统根据其采用的图像来源和识别算法需要不同,采用的预处理方法也不同。常用的人脸图像预处理方法有:滤波去噪、灰度变换、图像二值化、边缘检测、尺寸归一化、灰度归一化等。用在同一系统中的可能只有其中一种或几种预处理方法,但一旦库中采集到的原始图像质量发生较大变化(如人脸大小、光照强度、拍摄条件、成像系统等方面变化),原有的预处理模块便不能满足特征提取的需要,还要更新,这是极不方便的。鉴于此,作者在总结分析了滤波去噪、边缘检测、灰度变换三种广泛应用于不同人脸识别系统中的预处理方法基础上,设计了一个通用的人脸图像预处理仿真系统。该系统可对不同条件下的原始图像进行相应的预处理。如,用户可根据需要选择使用不同的滤波方法去除噪声、不同的边缘检测算子检测人脸边缘、选择不同的灰度变换算法实现图像的灰度校正和灰度归一化,仿真系统同时还实现了尺寸归一化、二值化等其他常用的图像预处理算法。
对输入人脸图像进行边缘检测是很多人脸识别系统在人脸粗定位及人脸主要器官(眼睛、鼻子、嘴巴)定位时采用的预处理方法。边缘检测的方法有很多,主要有:微分算子法、Sobel算子法、拉普拉斯算子法、canny算子法等。每种算子对不同方向边缘的检测能力和抑制噪声的能力都不同。所以,和灰度变换及滤波去噪部分的设计思路相同,在仿真系统中,笔者给出了canny、sobel、log、prewitt四种算子在不同灰度阈值下、不同方向的边缘检测算法,使用者可从检测结果中加以比较、选择合适的算法。图像类型转换、图像二值化、尺寸归一化也是一些人脸识别系统中经常使用的预处理方法。为了在不修改其他算法的基础上,扩大系统处理图像的类型和范围,将输入图像首先转换为统一的类型,是多数人脸图像预处理中的第一步。在本仿真系统中通过调用MATLAB中提供的各种图像类型转换函数来实现TIF、JPG转换为BMP格式及彩色到灰度图像的转换;对图像二值化,采用了graythresh()函数来自动选择阈值的二值化方法[1];尺寸归一化采用的算法是对人脸图像进行剪裁和尺寸缩放,实现去除大部分头发、服饰和背景的干扰并将人脸图像大小统一。
实现结果如图4.1和4.2
附录 人脸识别matlab程序
function varargout = FR_Processed_histogram(varargin)
gui_Singleton = 1;
gui_State = struct('gui_Name', mfilename, ...
'gui_Singleton', gui_Singleton, ...
'gui_OpeningFcn', @FR_Processed_histogram_OpeningFcn, ...
'gui_OutputFcn', @FR_Processed_histogram_OutputFcn, ...
'gui_LayoutFcn', [] , ...
'gui_Callback', []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
%--------------------------------------------------------------------------
% --- Executes just before FR_Processed_histogram is made visible.
function FR_Processed_histogram_OpeningFcn(hObject, eventdata, handles, varargin)
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes FR_Processed_histogram wait for user response (see UIRESUME)
% uiwait(handles.figure1);
global total_sub train_img sub_img max_hist_level bin_num form_bin_num;
total_sub = 40;
train_img = 200;
sub_img = 10;
max_hist_level = 256;
bin_num = 9;
form_bin_num = 29;
%--------------------------------------------------------------------------
% --- Outputs from this function are returned to the command line.
function varargout = FR_Processed_histogram_OutputFcn(hObject, eventdata, handles)
varargout{1} = handles.output;
%--------------------------------------------------------------------------
% --- Executes on button press in train_button.
function train_button_Callback(hObject, eventdata, handles)
global train_processed_bin;
global total_sub train_img sub_img max_hist_level bin_num form_bin_num;
train_processed_bin(form_bin_num,train_img) = 0;
K = 1;
train_hist_img = zeros(max_hist_level, train_img);
for Z=1:1:total_sub
for X=1:2:sub_img %%%train on odd number of images of each subject
I = imread( strcat('ORL\S',int2str(Z),'\',int2str(X),'.bmp') );
[rows cols] = size(I);
for i=1:1:rows
for j=1:1:cols
if( I(i,j) == 0 )
train_hist_img(max_hist_level, K) = train_hist_img(max_hist_level, K) + 1;
else
train_hist_img(I(i,j), K) = train_hist_img(I(i,j), K) + 1;
end
end
end
K = K + 1;
end
end
[r c] = size(train_hist_img);
sum = 0;
for i=1:1:c
K = 1;
for j=1:1:r
if( (mod(j,bin_num)) == 0 )
sum = sum + train_hist_img(j,i);
train_processed_bin(K,i) = sum/bin_num;
K = K + 1;
sum = 0;
else
sum = sum + train_hist_img(j,i);
end
end
train_processed_bin(K,i) = sum/bin_num;
end
display ('Training Done')
save 'train' train_processed_bin;
%--------------------------------------------------------------------------
% --- Executes on button press in Testing_button.
function Testing_button_Callback(hObject, eventdata, handles)
global train_img max_hist_level bin_num form_bin_num;
global train_processed_bin;
global filename pathname I
load 'train'
test_hist_img(max_hist_level) = 0;
test_processed_bin(form_bin_num) = 0;
[rows cols] = size(I);
for i=1:1:rows
for j=1:1:cols
if( I(i,j) == 0 )
test_hist_img(max_hist_level) = test_hist_img(max_hist_level) + 1;
else
test_hist_img(I(i,j)) = test_hist_img(I(i,j)) + 1;
end
end
end
[r c] = size(test_hist_img);
sum = 0;
K = 1;
for j=1:1:c
if( (mod(j,bin_num)) == 0 )
sum = sum + test_hist_img(j);
test_processed_bin(K) = sum/bin_num;
K = K + 1;
sum = 0;
else
sum = sum + test_hist_img(j);
end
end
test_processed_bin(K) = sum/bin_num;
sum = 0;
K = 1;
for y=1:1:train_img
for z=1:1:form_bin_num
sum = sum + abs( test_processed_bin(z) - train_processed_bin(z,y) );
end
img_bin_hist_sum(K,1) = sum;
sum = 0;
K = K + 1;
end
[temp M] = min(img_bin_hist_sum);
M = ceil(M/5);
getString_start=strfind(pathname,'S');
getString_start=getString_start(end)+1;
getString_end=strfind(pathname,'\');
getString_end=getString_end(end)-1;
subjectindex=str2num(pathname(getString_start:getString_end));
if (subjectindex == M)
axes (handles.axes3)
%image no: 5 is shown for visualization purpose
imshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))
msgbox ( 'Correctly Recognized');
else
display ([ 'Error==> Testing Image of Subject >>' num2str(subjectindex) ' matches with the image of subject >> ' num2str(M)])
axes (handles.axes3)
%image no: 5 is shown for visualization purpose
imshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))
msgbox ( 'Incorrectly Recognized');
end
display('Testing Done')
%--------------------------------------------------------------------------
function box_Callback(hObject, eventdata, handles)
function box_CreateFcn(hObject, eventdata, handles)
if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor'))
set(hObject,'BackgroundColor','white');
end
%--------------------------------------------------------------------------
% --- Executes on button press in Input_Image_button.
function Input_Image_button_Callback(hObject, eventdata, handles)
% hObject handle to Input_Image_button (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
global filename pathname I
[filename, pathname] = uigetfile('*.bmp', 'Test Image');
axes(handles.axes1)
imgpath=STRCAT(pathname,filename);
I = imread(imgpath);
imshow(I)
%--------------------------------------------------------------------------
% --- Executes during object creation, after setting all properties.
function axes3_CreateFcn(hObject, eventdata, handles)