数字图像处理人脸识别matlab程序代码。
- 格式:doc
- 大小:205.50 KB
- 文档页数:4
function varargout = FR_Processed_histogram(varargin) %这种算法是基于直方图处理的方法%The histogram of image is calculated and then bin formation is done on the%basis of mean of successive graylevels frequencies. The training is done on odd images of 40 subjects (200 images out of 400 images)%The results of the implemented algorithm is 99.75 (recognition fails on image number 4 of subject 17)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});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});elsegui_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(hObjecte, ventdata, handles, varargin)% This function has no output args, see OutputFcn.% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to FR_Processed_histogram (see VARARGIN)% Choose default command line output forFR_Processed_histogramhandles.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_numform_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 cell array for returning output args (see VARARGOUT);% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structurevarargout{1} = handles.output;% -------------------------------------------------------------------------% --- Executes on button press in train_button.function train_button_Callback(hObject, eventdata, handles)% hObject handle to train_button (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)global train_processed_bin;global total_sub train_img sub_img max_hist_level bin_numform_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_subfor X=1:2:sub_img %%%train on odd number of images of each subjectI = imread( strcat('ORL\S',int2str(Z), '\',int2str(X), '.bmp') ); [rowscols] = size(I);for i=1:1:rowsfor j=1:1:colsif( 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;endendendK = K + 1;endend[r c] = size(train_hist_img);sum = 0;for i=1:1:cK = 1;for j=1:1:rif( (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;elsesum = sum + train_hist_img(j,i);endendtrain_processed_bin(K,i) = sum/bin_num;enddisplay ('Training Done') save'train' train_processed_bin;% --- Executes on button press in Testing_button.function Testing_button_Callback(hObject, eventdata, handles)% hObject handle to Testing_button (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) global train_img max_hist_level bin_num form_bin_num;global train_processed_bin;global filename pathname Iload 'train'test_hist_img(max_hist_level) = 0;test_processed_bin(form_bin_num) = 0;[rows cols] = size(I);for i=1:1:rowsfor j=1:1:colsif( I(i,j) == 0 )test_hist_img(max_hist_level)test_hist_img(max_hist_level) + 1;elsetest_hist_img(I(i,j)) = test_hist_img(I(i,j)) + 1;endendend[r c] = size(test_hist_img); sum = 0;K = 1;for j=1:1:cif( (mod(j,bin_num)) == 0 )sum = sum + test_hist_img(j); test_processed_bin(K) =sum/bin_num;K = K + 1;sum = 0;elsesum = sum + test_hist_img(j);endendtest_processed_bin(K) = sum/bin_num;sum = 0;K = 1;for y=1:1:train_imgfor z=1:1:form_bin_numsum = sum + abs( test_processed_bin(z) - train_processed_bin(z,y) );endimg_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 purposeimshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))msgbox ( 'Correctly Recognized');elsedisplay ([ '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 purposeimshow(imread(STRCAT( 'ORL\S' ,num2str(M),'\5.bmp')))msgbox ( 'Incorrectly Recognized');enddisplay('Testing Done')% -------------------------------------------------------------------------function box_Callback(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version ofMATLAB% handles structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of box as text% str2double(get(hObject,'String')) returns contents of box as a double% -------------------------------------------------------------------------% --- Executes during object creation, after setting all properties.function box_CreateFcn(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.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)% hObject handle to axes3 (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles empty - handles not created until after all CreateFcns called% Hint: place code in OpeningFcn to populate axes3%Programmed by Usman Qayyum。
function varargout = FR_Processed_histogram(varargin) %这种算法是基于直方图处理的方法%The histogram of image is calculated and then bin formation is done on the%basis of mean of successive graylevels frequencies. The training is done on odd images of 40 subjects (200 images out of 400 images)%The results of the implemented algorithm is 99.75 (recognition fails on image number 4 of subject 17)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});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});elsegui_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(hObjecte, ventdata, handles, varargin)% This function has no output args, see OutputFcn.% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to FR_Processed_histogram (see VARARGIN)% Choose default command line output forFR_Processed_histogramhandles.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_numform_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 cell array for returning output args (see VARARGOUT);% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structurevarargout{1} = handles.output;% -------------------------------------------------------------------------% --- Executes on button press in train_button.function train_button_Callback(hObject, eventdata, handles)% hObject handle to train_button (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA)global train_processed_bin;global total_sub train_img sub_img max_hist_level bin_numform_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_subfor X=1:2:sub_img %%%train on odd number of images of each subjectI = imread( strcat('ORL\S',int2str(Z), '\',int2str(X), '.bmp') ); [rowscols] = size(I);for i=1:1:rowsfor j=1:1:colsif( 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;endendendK = K + 1;endend[r c] = size(train_hist_img);sum = 0;for i=1:1:cK = 1;for j=1:1:rif( (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;elsesum = sum + train_hist_img(j,i);endendtrain_processed_bin(K,i) = sum/bin_num;enddisplay ('Training Done') save'train' train_processed_bin;% --- Executes on button press in Testing_button.function Testing_button_Callback(hObject, eventdata, handles)% hObject handle to Testing_button (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) global train_img max_hist_level bin_num form_bin_num;global train_processed_bin;global filename pathname Iload 'train'test_hist_img(max_hist_level) = 0;test_processed_bin(form_bin_num) = 0;[rows cols] = size(I);for i=1:1:rowsfor j=1:1:colsif( I(i,j) == 0 )test_hist_img(max_hist_level)test_hist_img(max_hist_level) + 1;elsetest_hist_img(I(i,j)) = test_hist_img(I(i,j)) + 1;endendend[r c] = size(test_hist_img); sum = 0;K = 1;for j=1:1:cif( (mod(j,bin_num)) == 0 )sum = sum + test_hist_img(j); test_processed_bin(K) =sum/bin_num;K = K + 1;sum = 0;elsesum = sum + test_hist_img(j);endendtest_processed_bin(K) = sum/bin_num;sum = 0;K = 1;for y=1:1:train_imgfor z=1:1:form_bin_numsum = sum + abs( test_processed_bin(z) - train_processed_bin(z,y) );endimg_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 purposeimshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp')))msgbox ( 'Correctly Recognized');elsedisplay ([ '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 purposeimshow(imread(STRCAT( 'ORL\S' ,num2str(M),'\5.bmp')))msgbox ( 'Incorrectly Recognized');enddisplay('Testing Done')% -------------------------------------------------------------------------function box_Callback(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version ofMATLAB% handles structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of box as text% str2double(get(hObject,'String')) returns contents of box as a double% -------------------------------------------------------------------------% --- Executes during object creation, after setting all properties.function box_CreateFcn(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.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)% hObject handle to axes3 (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles empty - handles not created until after all CreateFcns called% Hint: place code in OpeningFcn to populate axes3%Programmed by Usman Qayyum。
function varargout = FR_Processed_histogram(varargin)%这种算法是基于直方图处理的方法%The histogram of image is calculated and then bin formation is done on the%basis of mean of successive graylevels frequencies. The training is done on odd images of 40 subjects (200 images out of 400 images)%The results of the implemented algorithm is 99.75 (recognition fails on image number 4 of subject 17) 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});endif nargout[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});elsegui_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)% This function has no output args, see OutputFcn.% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)% varargin command line arguments toFR_Processed_histogram (see VARARGIN)% Choose default command line output for FR_Processed_histogramhandles.output = hObject;% Update handles structureguidata(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 cell array for returning output args (see VARARGOUT);% hObject handle to figure% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)% Get default command line output from handles structure varargout{1} = handles.output;%--------------------------------------------------------------------------% --- Executes on button press in train_button.function train_button_Callback(hObject, eventdata, handles)% hObject handle to train_button (see GCBO)% eventdata reserved - to be defined in a future versionof MATLAB% handles structure with handles and user data (see GUIDATA)global train_processed_bin;global total_sub train_img sub_img max_hist_level bin_numform_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_subfor X=1:2:sub_img %%%train on odd number of images ofeach subjectI = imread( strcat('ORL\S',int2str(Z),'\',int2str(X),'.bmp') );[rows cols] = size(I);for i=1:1:rowsfor j=1:1:colsif( I(i,j) == 0 )train_hist_img(max_hist_level, K) =train_hist_img(max_hist_level, K) + 1;elsetrain_hist_img(I(i,j), K) =train_hist_img(I(i,j), K) + 1;endendendK = K + 1;endend[r c] = size(train_hist_img);sum = 0;for i=1:1:cK = 1;for j=1:1:rif( (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;elsesum = sum + train_hist_img(j,i);endendtrain_processed_bin(K,i) = sum/bin_num;enddisplay ('Training Done')save 'train'train_processed_bin;%--------------------------------------------------------------------------% --- Executes on button press in Testing_button.function Testing_button_Callback(hObject, eventdata, handles)% hObject handle to Testing_button (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (seeGUIDATA)global train_img max_hist_level bin_num form_bin_num;global train_processed_bin;global filename pathname Iload 'train'test_hist_img(max_hist_level) = 0;test_processed_bin(form_bin_num) = 0;[rows cols] = size(I);for i=1:1:rowsfor j=1:1:colsif( I(i,j) == 0 )test_hist_img(max_hist_level) = test_hist_img(max_hist_level) + 1;elsetest_hist_img(I(i,j)) = test_hist_img(I(i,j)) + 1;endendend[r c] = size(test_hist_img);sum = 0;K = 1;for j=1:1:cif( (mod(j,bin_num)) == 0 )sum = sum + test_hist_img(j); test_processed_bin(K) = sum/bin_num;K = K + 1;sum = 0;elsesum = sum + test_hist_img(j);endendtest_processed_bin(K) = sum/bin_num;sum = 0;K = 1;for y=1:1:train_imgfor z=1:1:form_bin_numsum = sum + abs( test_processed_bin(z) - train_processed_bin(z,y) );endimg_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 purposeimshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp'))) msgbox ( 'Correctly Recognized');elsedisplay ([ '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 purposeimshow(imread(STRCAT('ORL\S',num2str(M),'\5.bmp'))) msgbox ( 'Incorrectly Recognized');enddisplay('Testing Done')%--------------------------------------------------------------------------function box_Callback(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles structure with handles and user data (see GUIDATA)% Hints: get(hObject,'String') returns contents of box as text% str2double(get(hObject,'String')) returns contents of box as a double%--------------------------------------------------------------------------% --- Executes during object creation, after setting all properties.function box_CreateFcn(hObject, eventdata, handles)% hObject handle to box (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles empty - handles not created until after all CreateFcns called% Hint: edit controls usually have a white background on Windows.% See ISPC and COMPUTER.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)% hObject handle to axes3 (see GCBO)% eventdata reserved - to be defined in a future version of MATLAB% handles empty - handles not created until after all CreateFcns called% Hint: place code in OpeningFcn to populate axes3%Programmed by Usman Qayyum(注:可编辑下载,若有不当之处,请指正,谢谢!)。
以下是LDA的m文件函数:你稍稍改改就能用了!function[eigvector,eigvalue,elapse]=LDA(gnd,options,data) %LDA:LinearDiscriminantAnalysis%%[eigvector,eigvalue]=LDA(gnd,options,data)%%Input:%data-Datamatrix.Eachrowvectoroffeaisadatapoint.%gnd-Colunmvectorofthelabelinformationforeach%datapoint.%options-StructvalueinMatlab.Thefieldsinoptions%thatcanbeset:%%Regu-1:regularizedsolution,%a*=argmax(a'X'WXa)/(a'X'Xa+ReguAlpha*I)%0:solvethesinularityproblembySVD%Default:0%%ReguAlpha-Theregularizationparameter.Valid%whenRegu==1.Defaultvalueis0.1.%%ReguType-'Ridge':Tikhonovregularization%'Custom':Userprovided%regularizationmatrix%Default:'Ridge'%regularizerR-(nFeaxnFea)regularization%matrixwhichshouldbeprovided%ifReguTypeis'Custom'.nFeais%thefeaturenumberofdata%matrix%Fisherface-1:Fisherfaceapproach%PCARatio=nSmp-nClass%Default:0%%PCARatio-Thepercentageofprincipal%componentkeptinthePCA%step.Thepercentageis%calculatedbasedonthe%eigenvalue.Defaultis1%(100%,allthenon-zero%eigenvalueswillbekept.%IfPCARatio>1,thePCAstep%willkeepexactlyPCARatioprinciple%components(doesnotexceedthe%exactnumberofnon-zerocomponents).%%%Output:%eigvector-Eachcolumnisanembeddingfunction,foranew%datapoint(rowvector)x,y=x*eigvector%willbetheembeddingresultofx.%eigvalue-ThesortedeigvalueofLDAeigen-problem.%elapse-Timespentondifferentsteps%%Examples:%%fea=rand(50,70);%gnd=[ones(10,1);ones(15,1)*2;ones(10,1)*3;ones(15,1)*4];%options=[];%options.Fisherface=1;%[eigvector,eigvalue]=LDA(gnd,options,fea);%Y=fea*eigvector;%%%SeealsoLPP,constructW,LGE%%%%Reference:%%P.N.Belhumeur,J.P.Hespanha,andD.J.Kriegman,揈igenfaces%vs.fisherfaces:recognitionusingclassspecificlinear%projection,?IEEETransactionsonPatternAnalysisandMachine%Intelligence,vol.19,no.7,pp.711-720,July1997.%%DengCai,XiaofeiHe,YuxiaoHu,JiaweiHan,andThomasHuang, %"LearningaSpatiallySmoothSubspaceforFaceRecognition",CVPR'2007 %%DengCai,XiaofeiHe,JiaweiHan,"SRDA:AnEfficientAlgorithmfor%LargeScaleDiscriminantAnalysis",IEEETransactionsonKnowledgeand %DataEngineering,2007.%%version2.1--June/2007%version2.0--May/2007%version1.1--Feb/2006%version1.0--April/2004%%WrittenbyDengCai(dengcai2AT%if~exist('data','var')globaldata;endif(~exist('options','var'))endif~isfield(options,'Regu')|~options.RegubPCA=1;if~isfield(options,'PCARatio')options.PCARatio=1;endelsebPCA=0;if~isfield(options,'ReguType')options.ReguType='Ridge';endif~isfield(options,'ReguAlpha')options.ReguAlpha=0.1;endendtmp_T=cputime;%======Initialization[nSmp,nFea]=size(data);iflength(gnd)~=nSmperror('gndanddatamismatch!');endclassLabel=unique(gnd);nClass=length(classLabel);Dim=nClass-1;ifbPCA&isfield(options,'Fisherface')&options.Fisherface options.PCARatio=nSmp-nClass;endifissparse(data)data=full(data);endsampleMean=mean(data,1);data=(data-repmat(sampleMean,nSmp,1));bChol=0;ifbPCA&(nSmp>nFea+1)&(options.PCARatio>=1) DPrime=data'*data;DPrime=max(DPrime,DPrime');[R,p]=chol(DPrime);ifp==0bPCA=0;bChol=1;endend%====================================== %SVD%====================================== ifbPCAddata=data'*data;ddata=max(ddata,ddata');[eigvector_PCA,eigvalue_PCA]=eig(ddata);eigvalue_PCA=diag(eigvalue_PCA);clearddata;maxEigValue=max(abs(eigvalue_PCA));eigIdx=find(eigvalue_PCA/maxEigValue<1e-12);eigvalue_PCA(eigIdx)=[];eigvector_PCA(:,eigIdx)=[];[junk,index]=sort(-eigvalue_PCA);eigvalue_PCA=eigvalue_PCA(index);eigvector_PCA=eigvector_PCA(:,index);%======================================= ifoptions.PCARatio>1idx=options.PCARatio;ifidx<length(eigvalue_PCA)eigvalue_PCA=eigvalue_PCA(1:idx);eigvector_PCA=eigvector_PCA(:,1:idx);endelseifoptions.PCARatio<1sumEig=sum(eigvalue_PCA);sumEig=sumEig*options.PCARatio;sumNow=0;foridx=1:length(eigvalue_PCA)sumNow=sumNow+eigvalue_PCA(idx);ifsumNow>=sumEigbreak;endendeigvalue_PCA=eigvalue_PCA(1:idx);eigvector_PCA=eigvector_PCA(:,1:idx);end%======================================= eigvalue_PCA=eigvalue_PCA.^-.5;data=(data*eigvector_PCA).*repmat(eigvalue_PCA',nSmp,1); elseddata=data*data';ddata=max(ddata,ddata');[eigvector,eigvalue_PCA]=eig(ddata);eigvalue_PCA=diag(eigvalue_PCA);clearddata;maxEigValue=max(eigvalue_PCA);eigIdx=find(eigvalue_PCA/maxEigValue<1e-12);eigvalue_PCA(eigIdx)=[];eigvector(:,eigIdx)=[];[junk,index]=sort(-eigvalue_PCA);eigvalue_PCA=eigvalue_PCA(index);eigvector=eigvector(:,index);%======================================= ifoptions.PCARatio>1idx=options.PCARatio;ifidx<length(eigvalue_PCA)eigvalue_PCA=eigvalue_PCA(1:idx);eigvector=eigvector(:,1:idx);endelseifoptions.PCARatio<1sumEig=sum(eigvalue_PCA);sumEig=sumEig*options.PCARatio;sumNow=0;foridx=1:length(eigvalue_PCA)sumNow=sumNow+eigvalue_PCA(idx);ifsumNow>=sumEigbreak;endendeigvalue_PCA=eigvalue_PCA(1:idx);eigvector=eigvector(:,1:idx);end%======================================= eigvalue_PCA=eigvalue_PCA.^-.5;eigvector_PCA=(data'*eigvector).*repmat(eigvalue_PCA',nFea,1); data=eigvector;cleareigvector;endelseif~bCholDPrime=data'*data;%options.ReguAlpha=nSmp*options.ReguAlpha;switchlower(options.ReguType)case{lower('Ridge')}fori=1:size(DPrime,1)DPrime(i,i)=DPrime(i,i)+options.ReguAlpha;endcase{lower('Tensor')}DPrime=DPrime+options.ReguAlpha*options.regularizerR;case{lower('Custom')}DPrime=DPrime+options.ReguAlpha*options.regularizerR; otherwiseerror('ReguTypedoesnotexist!');endDPrime=max(DPrime,DPrime');endend[nSmp,nFea]=size(data);Hb=zeros(nClass,nFea);fori=1:nClass,index=find(gnd==classLabel(i));classMean=mean(data(index,:),1);Hb(i,:)=sqrt(length(index))*classMean;endelapse.timeW=0;elapse.timePCA=cputime-tmp_T;tmp_T=cputime;ifbPCA[dumpVec,eigvalue,eigvector]=svd(Hb,'econ');eigvalue=diag(eigvalue);eigIdx=find(eigvalue<1e-3);eigvalue(eigIdx)=[];eigvector(:,eigIdx)=[];eigvalue=eigvalue.^2;eigvector=eigvector_PCA*(repmat(eigvalue_PCA,1,length(eigvalue)).*eigvector);elseWPrime=Hb'*Hb;WPrime=max(WPrime,WPrime');dimMatrix=size(WPrime,2);ifDim>dimMatrixDim=dimMatrix;endifisfield(options,'bEigs')ifoptions.bEigsbEigs=1;elsebEigs=0;endelseif(dimMatrix>1000&Dim<dimMatrix/10)|(dimMatrix>500&Dim<dimMatrix/20)|(dimMatrix>250&Dim<dimMatri x/30)bEigs=1;elsebEigs=0;endendifbEigs%disp('useeigstospeedup!');option=struct('disp',0);ifbCholoption.cholB=1;[eigvector,eigvalue]=eigs(WPrime,R,Dim,'la',option);else[eigvector,eigvalue]=eigs(WPrime,DPrime,Dim,'la',option);endeigvalue=diag(eigvalue);else[eigvector,eigvalue]=eig(WPrime,DPrime); eigvalue=diag(eigvalue);[junk,index]=sort(-eigvalue);eigvalue=eigvalue(index);eigvector=eigvector(:,index);ifDim<size(eigvector,2)eigvector=eigvector(:,1:Dim);eigvalue=eigvalue(1:Dim);endendendfori=1:size(eigvector,2)eigvector(:,i)=eigvector(:,i)./norm(eigvector(:,i)); endelapse.timeMethod=cputime-tmp_T;elapse.timeAll=elapse.timePCA+elapse.timeMethod;。
image = imread('im.jpg');figure,imshow(image);red = double(image(:,:,1));green = double(image(:,:,2));blue = double(image(:,:,3));[m n]=size(red);Y = zeros(m,n);Cb = zeros(m,n);Cr = zeros(m,n);I = zeros(m,n);Q = zeros(m,n);red_gama = zeros(m,n);green_gama = zeros(m,n);blue_gama = zeros(m,n);for i=1:m %gamma矫正for j=1:nif red(i,j)>0 && red(i,j)<90fai=pi*red(i,j)/180;gama=1+0.5*cos(fai);red_gama(i,j)=255*(red(i,j)/255)^(1/gama);elseif red(i,j)>=90 && red(i,j)<=170fai=pi/2;gama=1+0.5*cos(fai);red_gama(i,j)=255*(red(i,j)/255)^(1/gama);elseif red(i,j)>170 && red(i,j)<=255fai=pi-pi*(255-red(i,j))/170;gama=1+0.5*cos(fai);red_gama(i,j)=255*(red(i,j)/255)^(1/gama);endif green(i,j)>0 && green(i,j)<90fai=pi*green(i,j)/180;gama=1+0.5*cos(fai);green_gama(i,j)=255*(green(i,j)/255)^(1/gama);elseif green(i,j)>=90 && green(i,j)<=170fai=pi/2;gama=1+0.5*cos(fai);green_gama(i,j)=255*(green(i,j)/255)^(1/gama);elseif green(i,j)>170 && green(i,j)<=255fai=pi-pi*(255-green(i,j))/170;gama=1+0.5*cos(fai);green_gama(i,j)=255*(green(i,j)/255)^(1/gama);endif blue(i,j)>0 && blue(i,j)<90fai=pi*blue(i,j)/180;gama=1+0.5*cos(fai);blue_gama(i,j)=255*(blue(i,j)/255)^(1/gama);elseif blue(i,j)>=90 && blue(i,j)<=170fai=pi/2;gama=1+0.5*cos(fai);blue_gama(i,j)=255*(blue(i,j)/255)^(1/gama);elseif blue(i,j)>170 && blue(i,j)<=255fai=pi-pi*(255-blue(i,j))/170;gama=1+0.5*cos(fai);blue_gama(i,j)=255*(blue(i,j)/255)^(1/gama);endendendfor i=1:mfor j=1:nY(i,j)=0.2989*red_gama(i,j)+0.5866*green_gama(i,j)+0.1145*blue_gama(i,j) ;Cb(i,j)=-0.1688*red_gama(i,j)-0.3312*green_gama(i,j)+0.5000*blue_gama(iCr(i,j)=0.5000*red_gama(i,j)-0.4184*green_gama(i,j)-0.0817*blue_gama(i,j) ;endendemp=zeros(m,n);sita=zeros(m,n);for i=1:mfor j=1:nif Cr(i,j)>0 && Cb(i,j)>0sita(i,j)=atan(abs(Cr(i,j))/abs(Cb(i,j)))*180/pi;elseif Cr(i,j)>0 && Cb(i,j)<0sita(i,j)=180-atan(abs(Cr(i,j))/abs(Cb(i,j)))*180/pi;elseif Cr(i,j)<0 && Cb(i,j)<0sita(i,j)=180 + atan(abs(Cr(i,j))/abs(Cb(i,j)))*180/pi;elsesita(i,j)=0;endendendfor i=1:mfor j=1:nif sita(i,j)>105 && sita(i,j)<150emp(i,j)=sita(i,j);elseemp(i,j)=0;Y(i,j)=0;endendfigure,imshow(emp); figure,imshow(uint8(Y));原图像分割结果分割结果。
1.色彩空间转换function [r,g]=rgb_RGB(Ori_Face)R=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;row=size(Ori_Face,1); % 行像素column=size(Ori_Face,2); % 列像素for i=1:rowfor j=1:columnrr(i,j)=R1(i,j)/RGB(i,j);gg(i,j)=G1(i,j)/RGB(i,j);endendrrr=mean(rr);r=mean(rrr);ggg=mean(gg);g=mean(ggg);2.均值和协方差t1=imread('D:\matlab\皮肤库\1.jpg');[r1,g1]=rgb_RGB(t1); t2=imread('D:\matlab\皮肤库\2.jpg');[r2,g2]=rgb_RGB(t2); t3=imread('D:\matlab\皮肤库\3.jpg');[r3,g3]=rgb_RGB(t3); t4=imread('D:\matlab\皮肤库\4.jpg');[r4,g4]=rgb_RGB(t4); t5=imread('D:\matlab\皮肤库\5.jpg');[r5,g5]=rgb_RGB(t5); t6=imread('D:\matlab\皮肤库\6.jpg');[r6,g6]=rgb_RGB(t6); t7=imread('D:\matlab\皮肤库\7.jpg');[r7,g7]=rgb_RGB(t7); t8=imread('D:\matlab\皮肤库\8.jpg');[r8,g8]=rgb_RGB(t8);t9=imread('D:\matlab\皮肤库\9.jpg');[r9,g9]=rgb_RGB(t9);t10=imread('D:\matlab\皮肤库\10.jpg');[r10,g10]=rgb_RGB(t10);t11=imread('D:\matlab\皮肤库\11.jpg');[r11,g11]=rgb_RGB(t11);t12=imread('D:\matlab\皮肤库\12.jpg');[r12,g12]=rgb_RGB(t12);t13=imread('D:\matlab\皮肤库\13.jpg');[r13,g13]=rgb_RGB(t13);t14=imread('D:\matlab\皮肤库\14.jpg');[r14,g14]=rgb_RGB(t14);t15=imread('D:\matlab\皮肤库\15.jpg');[r15,g15]=rgb_RGB(t15);t16=imread('D:\matlab\皮肤库\16.jpg');[r16,g16]=rgb_RGB(t16);t17=imread('D:\matlab\皮肤库\17.jpg');[r17,g17]=rgb_RGB(t17);t18=imread('D:\matlab\皮肤库\18.jpg');[r18,g18]=rgb_RGB(t18);t19=imread('D:\matlab\皮肤库\19.jpg');[r19,g19]=rgb_RGB(t19);t20=imread('D:\matlab\皮肤库\20.jpg');[r20,g20]=rgb_RGB(t20);t21=imread('D:\matlab\皮肤库\21.jpg');[r21,g21]=rgb_RGB(t21);t22=imread('D:\matlab\皮肤库\22.jpg');[r22,g22]=rgb_RGB(t22);t23=imread('D:\matlab\皮肤库\23.jpg');[r23,g23]=rgb_RGB(t23);t24=imread('D:\matlab\皮肤库\24.jpg');[r24,g24]=rgb_RGB(t24);t25=imread('D:\matlab\皮肤库\25.jpg');[r25,g25]=rgb_RGB(t25);t26=imread('D:\matlab\皮肤库\26.jpg');[r26,g26]=rgb_RGB(t26);t27=imread('D:\matlab\皮肤库\27.jpg');[r27,g27]=rgb_RGB(t27);r=cat(1,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22, r23,r24,r25,r26,r27);g=cat(1,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15,g16,g17,g18,g19,g20 ,g21,g22,g23,g24,g25,g26,g27);m=mean([r,g])n=cov([r,g])3.求质心function [xmean, ymean] = center(bw)bw=bwfill(bw,'holes');area = bwarea(bw);[m n] =size(bw);bw=double(bw);xmean =0; ymean = 0;for i=1:m,for j=1:n,xmean = xmean + j*bw(i,j);ymean = ymean + i*bw(i,j);end;end;if(area==0)xmean=0;ymean=0;elsexmean = xmean/area;ymean = ymean/area;xmean = round(xmean);ymean = round(ymean);end4. 求偏转角度function [theta] = orient(bw,xmean,ymean) [m n] =size(bw);bw=double(bw);a = 0;b = 0;c = 0;for i=1:m,for j=1:n,a = a + (j - xmean)^2 * bw(i,j);b = b + (j - xmean) * (i - ymean) * bw(i,j);c = c + (i - ymean)^2 * bw(i,j);end;b = 2 * b;theta = atan(b/(a-c))/2;theta = theta*(180/pi); % 从幅度转换到角度5. 找区域边界function [left, right, up, down] = bianjie(A)[m n] = size(A);left = -1;right = -1;up = -1;down = -1;for j=1:n,for i=1:m,if (A(i,j) ~= 0)left = j;break;end;end;if (left ~= -1) break;end;end;for j=n:-1:1,for i=1:m,if (A(i,j) ~= 0)right = j;break;end;end;if (right ~= -1) break;end;for i=1:m,for j=1:n,if (A(i,j) ~= 0)up = i;break;end;end;if (up ~= -1)break;end;end;for i=m:-1:1,for j=1:n,if (A(i,j) ~= 0)down = i;break;end;end;if (down ~= -1)break;end;end;6. 求起始坐标function newcoord = checklimit(coord,maxval) newcoord = coord;if (newcoord<1)newcoord=1;end;if (newcoord>maxval)newcoord=maxval;end;7.模板匹配function [ccorr, mfit, RectCoord] = mobanpipei(mult, frontalmodel,ly,wx,cx, cy, angle)frontalmodel=rgb2gray(frontalmodel);model_rot = imresize(frontalmodel,[ly wx],'bilinear'); % 调整模板大小model_rot = imrotate(model_rot,angle,'bilinear'); % 旋转模板[l,r,u,d] = bianjie(model_rot); % 求边界坐标bwmodel_rot=imcrop(model_rot,[l u (r-l) (d-u)]); % 选择模板人脸区域[modx,mody] =center(bwmodel_rot); % 求质心[morig, norig] = size(bwmodel_rot);% 产生一个覆盖了人脸模板的灰度图像mfit = zeros(size(mult));mfitbw = zeros(size(mult));[limy, limx] = size(mfit);% 计算原图像中人脸模板的坐标startx = cx-modx;starty = cy-mody;endx = startx + norig-1;endy = starty + morig-1;startx = checklimit(startx,limx);starty = checklimit(starty,limy);endx = checklimit(endx,limx);endy = checklimit(endy,limy);for i=starty:endy,for j=startx:endx,mfit(i,j) = model_rot(i-starty+1,j-startx+1);end;end;ccorr = corr2(mfit,mult) % 计算相关度[l,r,u,d] = bianjie(bwmodel_rot);sx = startx+l;sy = starty+u;RectCoord = [sx sy (r-1) (d-u)]; % 产生矩形坐标8.主程序clear;[fname,pname]=uigetfile({'*.jpg';'*.bmp';'*.tif';'*.gif'},'Please choose a color picture...'); % 返回打开的图片名与图片路径名[u,v]=size(fname);y=fname(v); % 图片格式代表值switch ycase 0errordlg('You Should Load Image File First...','Warning...');case{'g';'G';'p';'P';'f';'F'}; % 图片格式若是JPG/jpg、BMP/bmp、TIF/tif 或者GIF/gif,才打开I=cat(2,pname,fname);Ori_Face=imread(I);subplot(2,3,1),imshow(Ori_Face);otherwiseerrordlg('You Should Load Image File First...','Warning...');endR=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型处理G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;m=[ 0.4144,0.3174]; % 均值n=[0.0031,-0.0004;-0.0004,0.0003]; % 方差row=size(Ori_Face,1); % 行像素数column=size(Ori_Face,2); % 列像素数for i=1:rowfor j=1:columnif RGB(i,j)==0rr(i,j)=0;gg(i,j)=0;elserr(i,j)=R1(i,j)/RGB(i,j); % rgb归一化gg(i,j)=G1(i,j)/RGB(i,j);x=[rr(i,j),gg(i,j)];p(i,j)=exp((-0.5)*(x-m)*inv(n)*(x-m)'); % 皮肤概率服从高斯分布endendendsubplot(2,3,2);imshow(p); % 显示皮肤灰度图像low_pass=1/9*ones(3);image_low=filter2(low_pass, p); % 低通滤波去噪声subplot(2,3,3);imshow(image_low);% 自适应阀值程序previousSkin2 = zeros(i,j);changelist = [];for threshold = 0.55:-0.1:0.05two_value = zeros(i,j);two_value(find(image_low>threshold)) = 1;change = sum(sum(two_value - previousSkin2));changelist = [changelist change];previousSkin2 = two_value;end[C, I] = min(changelist);optimalThreshold = (7-I)*0.1two_value = zeros(i,j);two_value(find(image_low>optimalThreshold)) = 1; % 二值化subplot(2,3,4);imshow(two_value); % 显示二值图像frontalmodel=imread('E:\我的照片\人脸模板.jpg'); % 读入人脸模板照片FaceCoord=[];imsourcegray=rgb2gray(Ori_Face); % 将原照片转换为灰度图像[L,N]=bwlabel(two_value,8); % 标注二值图像中连接的部分,L为数据矩阵,N为颗粒的个数for i=1:N,[x,y]=find(bwlabel(two_value)==i); % 寻找矩阵中标号为i的行和列的下标bwsegment = bwselect(two_value,y,x,8); % 选择出第i个颗粒numholes = 1-bweuler(bwsegment,4); % 计算此区域的空洞数if (numholes >= 1) % 若此区域至少包含一个洞,则将其选出进行下一步运算RectCoord = -1;[m n] = size(bwsegment);[cx,cy]=center(bwsegment); % 求此区域的质心bwnohole=bwfill(bwsegment,'holes'); % 将洞封住(将灰度值赋为1)justface = uint8(double(bwnohole) .* double(imsourcegray));% 只在原照片的灰度图像中保留该候选区域angle = orient(bwsegment,cx,cy); % 求此区域的偏转角度bw = imrotate(bwsegment, angle, 'bilinear');bw = bwfill(bw,'holes');[l,r,u,d] =bianjie(bw);wx = (r - l +1); % 宽度ly = (d - u + 1); % 高度wratio = ly/wx % 高宽比if ((0.8<=wratio)&(wratio<=2))% 如果目标区域的高度/宽度比例大于0.8且小于2.0,则将其选出进行下一步运算S=ly*wx; % 计算包含此区域矩形的面积A=bwarea(bwsegment); % 计算此区域面积if (A/S>0.35)[ccorr,mfit, RectCoord] = mobanpipei(justface,frontalmodel,ly,wx, cx,cy, angle);endif (ccorr>=0.6)mfitbw=(mfit>=1);invbw = xor(mfitbw,ones(size(mfitbw)));source_with_hole = uint8(double(invbw) .* double(imsourcegray));final_image = uint8(double(source_with_hole) + double(mfit));subplot(2,3,5);imshow(final_image); % 显示覆盖了模板脸的灰度图像imsourcegray = final_image;subplot(2,3,6);imshow(Ori_Face); % 显示检测效果图end;if (RectCoord ~= -1)FaceCoord = [FaceCoord; RectCoord];endendendend% 在认为是人脸的区域画矩形[numfaces x] = size(FaceCoord);for i=1:numfaces,hd = rectangle('Position',FaceCoord(i,:));set(hd, 'edgecolor', 'y');end人脸检测是人脸识别、人机交互、智能视觉监控等工作的前提。
人脸识别可能用到的代码:1.色彩空间转换function [r,g]=rgb_RGB(Ori_Face)R=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;row=size(Ori_Face,1); % 行像素column=size(Ori_Face,2); % 列像素for i=1:rowfor j=1:columnrr(i,j)=R1(i,j)/RGB(i,j);gg(i,j)=G1(i,j)/RGB(i,j);endendrrr=mean(rr);r=mean(rrr);ggg=mean(gg);g=mean(ggg);2.均值和协方差t1=imread('D:\matlab\皮肤库\1.jpg');[r1,g1]=rgb_RGB(t1); t2=imread('D:\matlab\皮肤库\2.jpg');[r2,g2]=rgb_RGB(t2); t3=imread('D:\matlab\皮肤库\3.jpg');[r3,g3]=rgb_RGB(t3); t4=imread('D:\matlab\皮肤库\4.jpg');[r4,g4]=rgb_RGB(t4); t5=imread('D:\matlab\皮肤库\5.jpg');[r5,g5]=rgb_RGB(t5); t6=imread('D:\matlab\皮肤库\6.jpg');[r6,g6]=rgb_RGB(t6);t7=imread('D:\matlab\皮肤库\7.jpg');[r7,g7]=rgb_RGB(t7);t8=imread('D:\matlab\皮肤库\8.jpg');[r8,g8]=rgb_RGB(t8);t9=imread('D:\matlab\皮肤库\9.jpg');[r9,g9]=rgb_RGB(t9);t10=imread('D:\matlab\皮肤库\10.jpg');[r10,g10]=rgb_RGB(t10);t11=imread('D:\matlab\皮肤库\11.jpg');[r11,g11]=rgb_RGB(t11);t12=imread('D:\matlab\皮肤库\12.jpg');[r12,g12]=rgb_RGB(t12);t13=imread('D:\matlab\皮肤库\13.jpg');[r13,g13]=rgb_RGB(t13);t14=imread('D:\matlab\皮肤库\14.jpg');[r14,g14]=rgb_RGB(t14);t15=imread('D:\matlab\皮肤库\15.jpg');[r15,g15]=rgb_RGB(t15);t16=imread('D:\matlab\皮肤库\16.jpg');[r16,g16]=rgb_RGB(t16);t17=imread('D:\matlab\皮肤库\17.jpg');[r17,g17]=rgb_RGB(t17);t18=imread('D:\matlab\皮肤库\18.jpg');[r18,g18]=rgb_RGB(t18);t19=imread('D:\matlab\皮肤库\19.jpg');[r19,g19]=rgb_RGB(t19);t20=imread('D:\matlab\皮肤库\20.jpg');[r20,g20]=rgb_RGB(t20);t21=imread('D:\matlab\皮肤库\21.jpg');[r21,g21]=rgb_RGB(t21);t22=imread('D:\matlab\皮肤库\22.jpg');[r22,g22]=rgb_RGB(t22);t23=imread('D:\matlab\皮肤库\23.jpg');[r23,g23]=rgb_RGB(t23);t24=imread('D:\matlab\皮肤库\24.jpg');[r24,g24]=rgb_RGB(t24);t25=imread('D:\matlab\皮肤库\25.jpg');[r25,g25]=rgb_RGB(t25);t26=imread('D:\matlab\皮肤库\26.jpg');[r26,g26]=rgb_RGB(t26);t27=imread('D:\matlab\皮肤库\27.jpg');[r27,g27]=rgb_RGB(t27);r=cat(1,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22,r23,r24,r25,r 26,r27);g=cat(1,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15,g16,g17,g18,g19,g20,g21,g22,g2 3,g24,g25,g26,g27);m=mean([r,g])n=cov([r,g])3.求质心function [xmean, ymean] = center(bw)bw=bwfill(bw,'holes');area = bwarea(bw);[m n] =size(bw);bw=double(bw);xmean =0; ymean = 0;for i=1:m,for j=1:n,xmean = xmean + j*bw(i,j);ymean = ymean + i*bw(i,j);end;end;if(area==0)xmean=0;ymean=0;elsexmean = xmean/area;ymean = ymean/area;xmean = round(xmean);ymean = round(ymean);end4. 求偏转角度function [theta] = orient(bw,xmean,ymean) [m n] =size(bw);bw=double(bw);a = 0;b = 0;c = 0;for i=1:m,for j=1:n,a = a + (j - xmean)^2 * bw(i,j);b = b + (j - xmean) * (i - ymean) * bw(i,j);c = c + (i - ymean)^2 * bw(i,j);end;b = 2 * b;theta = atan(b/(a-c))/2;theta = theta*(180/pi); % 从幅度转换到角度5. 找区域边界function [left, right, up, down] = bianjie(A) [m n] = size(A);left = -1;right = -1;up = -1;down = -1;for j=1:n,for i=1:m,if (A(i,j) ~= 0)left = j;break;end;end;if (left ~= -1) break;end;end;for j=n:-1:1,for i=1:m,if (A(i,j) ~= 0)right = j;break;end;end;if (right ~= -1) break;end;for i=1:m,for j=1:n,if (A(i,j) ~= 0)up = i;break;end;end;if (up ~= -1)break;end;end;for i=m:-1:1,for j=1:n,if (A(i,j) ~= 0)down = i;break;end;end;if (down ~= -1)break;end;end;6. 求起始坐标function newcoord = checklimit(coord,maxval) newcoord = coord;if (newcoord<1)newcoord=1;end;if (newcoord>maxval)newcoord=maxval;7.模板匹配function [ccorr, mfit, RectCoord] = mobanpipei(mult, frontalmodel,ly,wx,cx, cy, angle) frontalmodel=rgb2gray(frontalmodel);model_rot = imresize(frontalmodel,[ly wx],'bilinear'); % 调整模板大小model_rot = imrotate(model_rot,angle,'bilinear'); % 旋转模板[l,r,u,d] = bianjie(model_rot); % 求边界坐标bwmodel_rot=imcrop(model_rot,[l u (r-l) (d-u)]); % 选择模板人脸区域[modx,mody] =center(bwmodel_rot); % 求质心[morig, norig] = size(bwmodel_rot);% 产生一个覆盖了人脸模板的灰度图像mfit = zeros(size(mult));mfitbw = zeros(size(mult));[limy, limx] = size(mfit);% 计算原图像中人脸模板的坐标startx = cx-modx;starty = cy-mody;endx = startx + norig-1;endy = starty + morig-1;startx = checklimit(startx,limx);starty = checklimit(starty,limy);endx = checklimit(endx,limx);endy = checklimit(endy,limy);for i=starty:endy,for j=startx:endx,mfit(i,j) = model_rot(i-starty+1,j-startx+1);end;end;ccorr = corr2(mfit,mult) % 计算相关度[l,r,u,d] = bianjie(bwmodel_rot);sx = startx+l;sy = starty+u;RectCoord = [sx sy (r-1) (d-u)]; % 产生矩形坐标8.主程序clear;[fname,pname]=uigetfile({'*.jpg';'*.bmp';'*.tif';'*.gif'},'Please choose a color picture...');% 返回打开的图片名与图片路径名[u,v]=size(fname);y=fname(v); % 图片格式代表值switch ycase 0errordlg('You Should Load Image File First...','Warning...');case{'g';'G';'p';'P';'f';'F'}; % 图片格式若是JPG/jpg、BMP/bmp、TIF/tif或者GIF/gif,才打开I=cat(2,pname,fname);Ori_Face=imread(I);subplot(2,3,1),imshow(Ori_Face);otherwiseerrordlg('You Should Load Image File First...','Warning...');endR=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型处理G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;m=[ 0.4144,0.3174]; % 均值n=[0.0031,-0.0004;-0.0004,0.0003]; % 方差row=size(Ori_Face,1); % 行像素数column=size(Ori_Face,2); % 列像素数for i=1:rowfor j=1:columnif RGB(i,j)==0rr(i,j)=0;gg(i,j)=0;elserr(i,j)=R1(i,j)/RGB(i,j); % rgb归一化gg(i,j)=G1(i,j)/RGB(i,j);x=[rr(i,j),gg(i,j)];p(i,j)=exp((-0.5)*(x-m)*inv(n)*(x-m)'); % 皮肤概率服从高斯分布 endendendsubplot(2,3,2);imshow(p); % 显示皮肤灰度图像low_pass=1/9*ones(3);image_low=filter2(low_pass, p); % 低通滤波去噪声subplot(2,3,3);imshow(image_low);% 自适应阀值程序previousSkin2 = zeros(i,j);changelist = [];for threshold = 0.55:-0.1:0.05two_value = zeros(i,j);two_value(find(image_low>threshold)) = 1;change = sum(sum(two_value - previousSkin2));changelist = [changelist change];previousSkin2 = two_value;end[C, I] = min(changelist);optimalThreshold = (7-I)*0.1two_value = zeros(i,j);two_value(find(image_low>optimalThreshold)) = 1; % 二值化subplot(2,3,4);imshow(two_value); % 显示二值图像frontalmodel=imread('E:\我的照片\人脸模板.jpg'); % 读入人脸模板照片FaceCoord=[];imsourcegray=rgb2gray(Ori_Face); % 将原照片转换为灰度图像[L,N]=bwlabel(two_value,8); % 标注二值图像中连接的部分,L为数据矩阵,N为颗粒的个数for i=1:N,[x,y]=find(bwlabel(two_value)==i); % 寻找矩阵中标号为i的行和列的下标bwsegment = bwselect(two_value,y,x,8); % 选择出第i个颗粒numholes = 1-bweuler(bwsegment,4); % 计算此区域的空洞数if (numholes >= 1) % 若此区域至少包含一个洞,则将其选出进行下一步运算RectCoord = -1;[m n] = size(bwsegment);[cx,cy]=center(bwsegment); % 求此区域的质心bwnohole=bwfill(bwsegment,'holes'); % 将洞封住(将灰度值赋为1)justface = uint8(double(bwnohole) .* double(imsourcegray));% 只在原照片的灰度图像中保留该候选区域angle = orient(bwsegment,cx,cy); % 求此区域的偏转角度bw = imrotate(bwsegment, angle, 'bilinear');bw = bwfill(bw,'holes');[l,r,u,d] =bianjie(bw);wx = (r - l +1); % 宽度ly = (d - u + 1); % 高度wratio = ly/wx % 高宽比if ((0.8<=wratio)&(wratio<=2))% 如果目标区域的高度/宽度比例大于0.8且小于2.0,则将其选出进行下一步运算 S=ly*wx; % 计算包含此区域矩形的面积A=bwarea(bwsegment); % 计算此区域面积if (A/S>0.35)[ccorr,mfit, RectCoord] = mobanpipei(justface,frontalmodel,ly,wx, cx,cy, angle);endif (ccorr>=0.6)mfitbw=(mfit>=1);invbw = xor(mfitbw,ones(size(mfitbw)));source_with_hole = uint8(double(invbw) .* double(imsourcegray));final_image = uint8(double(source_with_hole) + double(mfit));subplot(2,3,5);imshow(final_image); % 显示覆盖了模板脸的灰度图像imsourcegray = final_image;subplot(2,3,6);imshow(Ori_Face); % 显示检测效果图end;if (RectCoord ~= -1)FaceCoord = [FaceCoord; RectCoord];endendendend% 在认为是人脸的区域画矩形[numfaces x] = size(FaceCoord);for i=1:numfaces,hd = rectangle('Position',FaceCoord(i,:));set(hd, 'edgecolor', 'y');end部分检测原理一、基于肤色模型的人脸检测对于一个成功的人脸识别系统,人脸检测是极其重要和关键的一步,它直接影响人脸特征的提取,识别等后续工作。
Matlab处理图像后实现简单的⼈脸检测⽬录1.⼈脸检测原理框图2 步骤2.1 均值滤波2.2 ⼆值化2.3.形态学边界提取2.4 纵向闭合与横向腐蚀2.5 消除边界多余连通域2.6 寻找最⼤连通域并画框3 检测结果1.⼈脸检测原理框图整体思路是寻找图⽚中最⼤的连通域,将其认定为⼈脸。
第⼀个环节均值滤波,是为了减弱图像的相关细节部分,以免⽑刺影响后期连通域的形成,⼆值化⽅便形态学处理,减少运算量。
考虑到⼈脸有⿊⼈和⽩⼈黄种⼈,⿊⼈肤⾊较深,在⼆值化之后⾯部区域不容易形成较⼤的连通域,如果采取形态学边界提取的办法,就可以避免这个问题,形态学边界提取,只要结构元素够⼤,也可以形成较⼤的封闭连通域。
然后就是纵向闭合操作,这⼀步我选择采⽤竖向长条状的结构元素进⾏闭合运算,因为⼈的脸部和颈部以及头发和⾐物等等都是纵向分布的,在进⾏形态学边界提取的时候,容易将这些靠近的成分割裂开来,这对连通域的判断极为不利,所以⽤竖向长条状的结构元素在在纵向进⾏闭合运算,将脸部上下部的区域重新连接起来。
紧接着我⼜⽤横向长条状结构元素进⾏横向腐蚀运算,这是因为,⼈的头部以下的⾝体部分存在有⼤量连通域的时候,容易对最⼤连通域的判决产⽣⼲扰,⼜因为下半部分,多半呈纵向分布,通过横向腐蚀可以将这些⼤块的连通域割裂开来,但是要注意的是,割裂程度不应太⼤,否则会使得上⼀步闭合操作丧失意义。
接着,由于背景杂物等因素,同样也会产⽣⼤量连通域,这会对最后结果的判决产⽣⼲扰,因此要予以剔除。
进⾏了层层筛选之后,在剩下的连通域⾥⾯挑⼀个最⼤的连通域,并且尺⼨形状满⾜要求的⽤矩形框框起来作为⼈脸检测结果。
2 步骤2.1 均值滤波h = ones(9)/81;I = uint8(conv2(I,h));figure,imshow(I),title('线性均值滤波')采⽤9x9模板进⾏线性均值滤波,因为后⾯调⽤gpuArray()函数转换对输⼊数据有要求,所以在进⾏了⼆维卷积之后重新将数据格式转换成8位⽆符号整形数据。
完整版)基于matlab程序实现人脸识别Based on MATLAB program。
face n is implemented。
1.Face n Process1.1.1 Basic PrincipleXXX carried out based on the YCbCr color space skin color model。
It has been found that the skin color clustering n in the Cb-Cr subplane n of the YCbCr color space will be XXX different from the central n。
Using this method。
image XXX-faces。
1.1.2 FlowchartXXX:1.Read the original image2.Convert the image to the YCbCr color spacee the skin color model to binarize the image and perform morphological processing4.Select the white area in the binary image。
measure the area attributes。
and filter to obtain all rectangular blocks5.Filter specific areas (height-to-width。
een 0.6 and 2.eye features)6.Store the rectangular area of the face7.Filter special areas based on other n and mark the final face area2.Face n Program1) Face and Non-XXXn result = skin(Y,Cb,Cr)SKIN Summary of this n goes hereDetailed n goes herea=25.39;b=14.03;ecx=1.60;ecy=2.41;sita=2.53;cx=109.38;cy=152.02;xishu=[cos(sita) sin(sita);-sin(sita) cos(sita)];If the brightness is greater than 230.the major and minor axes are expanded by 1.1 timesif(Y>230)a=1.1*a;b=1.1*b;endXXXCb=double(Cb);Cr=double(Cr);t=[(Cb-cx);(Cr-cy)];temp=xishu*t;value=(temp(1)-ecx)^2/a^2+(temp(2)-ecy)^2/b^2;If the value is greater than 1.it is not skin color and returns。
1.色彩空间转换function [r,g]=rgb_RGB(Ori_Face)R=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;row=size(Ori_Face,1); % 行像素column=size(Ori_Face,2); % 列像素for i=1:rowfor j=1:columnrr(i,j)=R1(i,j)/RGB(i,j);gg(i,j)=G1(i,j)/RGB(i,j);endendrrr=mean(rr);r=mean(rrr);ggg=mean(gg);g=mean(ggg);2.均值和协方差t1=imread('D:\matlab\皮肤库\1.jpg');[r1,g1]=rgb_RGB(t1); t2=imread('D:\matlab\皮肤库\2.jpg');[r2,g2]=rgb_RGB(t2); t3=imread('D:\matlab\皮肤库\3.jpg');[r3,g3]=rgb_RGB(t3); t4=imread('D:\matlab\皮肤库\4.jpg');[r4,g4]=rgb_RGB(t4); t5=imread('D:\matlab\皮肤库\5.jpg');[r5,g5]=rgb_RGB(t5); t6=imread('D:\matlab\皮肤库\6.jpg');[r6,g6]=rgb_RGB(t6); t7=imread('D:\matlab\皮肤库\7.jpg');[r7,g7]=rgb_RGB(t7); t8=imread('D:\matlab\皮肤库\8.jpg');[r8,g8]=rgb_RGB(t8);t9=imread('D:\matlab\皮肤库\9.jpg');[r9,g9]=rgb_RGB(t9);t10=imread('D:\matlab\皮肤库\10.jpg');[r10,g10]=rgb_RGB(t10);t11=imread('D:\matlab\皮肤库\11.jpg');[r11,g11]=rgb_RGB(t11);t12=imread('D:\matlab\皮肤库\12.jpg');[r12,g12]=rgb_RGB(t12);t13=imread('D:\matlab\皮肤库\13.jpg');[r13,g13]=rgb_RGB(t13);t14=imread('D:\matlab\皮肤库\14.jpg');[r14,g14]=rgb_RGB(t14);t15=imread('D:\matlab\皮肤库\15.jpg');[r15,g15]=rgb_RGB(t15);t16=imread('D:\matlab\皮肤库\16.jpg');[r16,g16]=rgb_RGB(t16);t17=imread('D:\matlab\皮肤库\17.jpg');[r17,g17]=rgb_RGB(t17);t18=imread('D:\matlab\皮肤库\18.jpg');[r18,g18]=rgb_RGB(t18);t19=imread('D:\matlab\皮肤库\19.jpg');[r19,g19]=rgb_RGB(t19);t20=imread('D:\matlab\皮肤库\20.jpg');[r20,g20]=rgb_RGB(t20);t21=imread('D:\matlab\皮肤库\21.jpg');[r21,g21]=rgb_RGB(t21);t22=imread('D:\matlab\皮肤库\22.jpg');[r22,g22]=rgb_RGB(t22);t23=imread('D:\matlab\皮肤库\23.jpg');[r23,g23]=rgb_RGB(t23);t24=imread('D:\matlab\皮肤库\24.jpg');[r24,g24]=rgb_RGB(t24);t25=imread('D:\matlab\皮肤库\25.jpg');[r25,g25]=rgb_RGB(t25);t26=imread('D:\matlab\皮肤库\26.jpg');[r26,g26]=rgb_RGB(t26);t27=imread('D:\matlab\皮肤库\27.jpg');[r27,g27]=rgb_RGB(t27);r=cat(1,r1,r2,r3,r4,r5,r6,r7,r8,r9,r10,r11,r12,r13,r14,r15,r16,r17,r18,r19,r20,r21,r22, r23,r24,r25,r26,r27);g=cat(1,g1,g2,g3,g4,g5,g6,g7,g8,g9,g10,g11,g12,g13,g14,g15,g16,g17,g18,g19,g20 ,g21,g22,g23,g24,g25,g26,g27);m=mean([r,g])n=cov([r,g])3.求质心function [xmean, ymean] = center(bw)bw=bwfill(bw,'holes');area = bwarea(bw);[m n] =size(bw);bw=double(bw);xmean =0; ymean = 0;for i=1:m,for j=1:n,xmean = xmean + j*bw(i,j);ymean = ymean + i*bw(i,j);end;end;if(area==0)xmean=0;ymean=0;elsexmean = xmean/area;ymean = ymean/area;xmean = round(xmean);ymean = round(ymean);end4. 求偏转角度function [theta] = orient(bw,xmean,ymean) [m n] =size(bw);bw=double(bw);a = 0;b = 0;c = 0;for i=1:m,for j=1:n,a = a + (j - xmean)^2 * bw(i,j);b = b + (j - xmean) * (i - ymean) * bw(i,j);c = c + (i - ymean)^2 * bw(i,j);end;end;b = 2 * b;theta = atan(b/(a-c))/2;theta = theta*(180/pi); % 从幅度转换到角度5. 找区域边界function [left, right, up, down] = bianjie(A)[m n] = size(A);left = -1;right = -1;up = -1;down = -1;for j=1:n,for i=1:m,if (A(i,j) ~= 0)left = j;break;end;end;if (left ~= -1) break;end;end;for j=n:-1:1,for i=1:m,if (A(i,j) ~= 0)right = j;break;end;end;if (right ~= -1) break;end;end;for i=1:m,for j=1:n,if (A(i,j) ~= 0)up = i;break;end;end;if (up ~= -1)break;end;end;for i=m:-1:1,for j=1:n,if (A(i,j) ~= 0)down = i;break;end;end;if (down ~= -1)break;end;end;6. 求起始坐标function newcoord = checklimit(coord,maxval) newcoord = coord;if (newcoord<1)newcoord=1;end;if (newcoord>maxval)newcoord=maxval;end;7.模板匹配function [ccorr, mfit, RectCoord] = mobanpipei(mult, frontalmodel,ly,wx,cx, cy, angle)frontalmodel=rgb2gray(frontalmodel);model_rot = imresize(frontalmodel,[ly wx],'bilinear'); % 调整模板大小model_rot = imrotate(model_rot,angle,'bilinear'); % 旋转模板[l,r,u,d] = bianjie(model_rot); % 求边界坐标bwmodel_rot=imcrop(model_rot,[l u (r-l) (d-u)]); % 选择模板人脸区域[modx,mody] =center(bwmodel_rot); % 求质心[morig, norig] = size(bwmodel_rot);% 产生一个覆盖了人脸模板的灰度图像mfit = zeros(size(mult));mfitbw = zeros(size(mult));[limy, limx] = size(mfit);% 计算原图像中人脸模板的坐标startx = cx-modx;starty = cy-mody;endx = startx + norig-1;endy = starty + morig-1;startx = checklimit(startx,limx);starty = checklimit(starty,limy);endx = checklimit(endx,limx);endy = checklimit(endy,limy);for i=starty:endy,for j=startx:endx,mfit(i,j) = model_rot(i-starty+1,j-startx+1);end;end;ccorr = corr2(mfit,mult) % 计算相关度[l,r,u,d] = bianjie(bwmodel_rot);sx = startx+l;sy = starty+u;RectCoord = [sx sy (r-1) (d-u)]; % 产生矩形坐标8.主程序clear;[fname,pname]=uigetfile({'*.jpg';'*.bmp';'*.tif';'*.gif'},'Please choose a color picture...'); % 返回打开的图片名与图片路径名[u,v]=size(fname);y=fname(v); % 图片格式代表值switch ycase 0errordlg('You Should Load Image File First...','Warning...');case{'g';'G';'p';'P';'f';'F'}; % 图片格式若是JPG/jpg、BMP/bmp、TIF/tif 或者GIF/gif,才打开I=cat(2,pname,fname);Ori_Face=imread(I);subplot(2,3,1),imshow(Ori_Face);otherwiseerrordlg('You Should Load Image File First...','Warning...');endR=Ori_Face(:,:,1);G=Ori_Face(:,:,2);B=Ori_Face(:,:,3);R1=im2double(R); % 将uint8型转换成double型处理G1=im2double(G);B1=im2double(B);RGB=R1+G1+B1;m=[ 0.4144,0.3174]; % 均值n=[0.0031,-0.0004;-0.0004,0.0003]; % 方差row=size(Ori_Face,1); % 行像素数column=size(Ori_Face,2); % 列像素数for i=1:rowfor j=1:columnif RGB(i,j)==0rr(i,j)=0;gg(i,j)=0;elserr(i,j)=R1(i,j)/RGB(i,j); % rgb归一化gg(i,j)=G1(i,j)/RGB(i,j);x=[rr(i,j),gg(i,j)];p(i,j)=exp((-0.5)*(x-m)*inv(n)*(x-m)'); % 皮肤概率服从高斯分布endendendsubplot(2,3,2);imshow(p); % 显示皮肤灰度图像low_pass=1/9*ones(3);image_low=filter2(low_pass, p); % 低通滤波去噪声subplot(2,3,3);imshow(image_low);% 自适应阀值程序previousSkin2 = zeros(i,j);changelist = [];for threshold = 0.55:-0.1:0.05two_value = zeros(i,j);two_value(find(image_low>threshold)) = 1;change = sum(sum(two_value - previousSkin2));changelist = [changelist change];previousSkin2 = two_value;end[C, I] = min(changelist);optimalThreshold = (7-I)*0.1two_value = zeros(i,j);two_value(find(image_low>optimalThreshold)) = 1; % 二值化subplot(2,3,4);imshow(two_value); % 显示二值图像frontalmodel=imread('E:\我的照片\人脸模板.jpg'); % 读入人脸模板照片FaceCoord=[];imsourcegray=rgb2gray(Ori_Face); % 将原照片转换为灰度图像[L,N]=bwlabel(two_value,8); % 标注二值图像中连接的部分,L为数据矩阵,N为颗粒的个数for i=1:N,[x,y]=find(bwlabel(two_value)==i); % 寻找矩阵中标号为i的行和列的下标bwsegment = bwselect(two_value,y,x,8); % 选择出第i个颗粒numholes = 1-bweuler(bwsegment,4); % 计算此区域的空洞数if (numholes >= 1) % 若此区域至少包含一个洞,则将其选出进行下一步运算RectCoord = -1;[m n] = size(bwsegment);[cx,cy]=center(bwsegment); % 求此区域的质心bwnohole=bwfill(bwsegment,'holes'); % 将洞封住(将灰度值赋为1)justface = uint8(double(bwnohole) .* double(imsourcegray));% 只在原照片的灰度图像中保留该候选区域angle = orient(bwsegment,cx,cy); % 求此区域的偏转角度bw = imrotate(bwsegment, angle, 'bilinear');bw = bwfill(bw,'holes');[l,r,u,d] =bianjie(bw);wx = (r - l +1); % 宽度ly = (d - u + 1); % 高度wratio = ly/wx % 高宽比if ((0.8<=wratio)&(wratio<=2))% 如果目标区域的高度/宽度比例大于0.8且小于2.0,则将其选出进行下一步运算S=ly*wx; % 计算包含此区域矩形的面积A=bwarea(bwsegment); % 计算此区域面积if (A/S>0.35)[ccorr,mfit, RectCoord] = mobanpipei(justface,frontalmodel,ly,wx, cx,cy, angle);endif (ccorr>=0.6)mfitbw=(mfit>=1);invbw = xor(mfitbw,ones(size(mfitbw)));source_with_hole = uint8(double(invbw) .* double(imsourcegray));final_image = uint8(double(source_with_hole) + double(mfit));subplot(2,3,5);imshow(final_image); % 显示覆盖了模板脸的灰度图像imsourcegray = final_image;subplot(2,3,6);imshow(Ori_Face); % 显示检测效果图end;if (RectCoord ~= -1)FaceCoord = [FaceCoord; RectCoord];endendendend% 在认为是人脸的区域画矩形[numfaces x] = size(FaceCoord);for i=1:numfaces,hd = rectangle('Position',FaceCoord(i,:));set(hd, 'edgecolor', 'y');end人脸检测是人脸识别、人机交互、智能视觉监控等工作的前提。