(完整版)人脸识别MATLAB代码
- 格式:doc
- 大小:66.01 KB
- 文档页数:11
基于肤色的人脸检测matlab代码mainclose allclear allclc% 输入图像名字img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s'); % 当输入0时结束while ~strcmp(img_name,'0')% 进行人脸识别facedetection(img_name);img_name = input('请输入图像名字(图像必须为RGB图像,输入0结束):','s'); endfacedetectionfunctionfacedetection(img_name)% 读取RGB图像I = imread(img_name);% 转换为灰度图像gray = rgb2gray(I);% 将图像转化为YCbCr颜色空间YCbCr = rgb2ycbcr(I);% 获得图像宽度和高度heigth = size(gray,1);width = size(gray,2);% 根据肤色模型将图像二值化fori = 1:heigthfor j = 1:widthY = YCbCr(i,j,1);Cb = YCbCr(i,j,2);Cr = YCbCr(i,j,3);if(Y < 80)gray(i,j) = 0;elseif(skin(Y,Cb,Cr) == 1)gray(i,j) = 255;elsegray(i,j) = 0;endendendend% 二值图像形态学处理SE=strel('arbitrary',eye(5));%gray = bwmorph(gray,'erode');% imopen先腐蚀再膨胀gray = imopen(gray,SE);% imclose先膨胀再腐蚀%gray = imclose(gray,SE);imshow(gray);% 取出图片中所有包含白色区域的最小矩形[L,num] = bwlabel(gray,8);STATS = regionprops(L,'BoundingBox'); % 存放经过筛选以后得到的所有矩形块n = 1;result = zeros(n,4);figure,imshow(I);hold on;fori = 1:numbox = STATS(i).BoundingBox;x = box(1); %矩形坐标xy = box(2); %矩形坐标yw = box(3); %矩形宽度wh = box(4); %矩形高度h% 宽度和高度的比例ratio = h/w;ux = uint8(x);uy = uint8(y);ifux> 1ux = ux - 1;endifuy> 1uy = uy - 1;end% 可能是人脸区域的矩形应满足以下条件:% 1、高度和宽度必须都大于20,且矩形面积大于400 % 2、高度和宽度比率应该在范围(0.6,2)内% 3、函数findeye返回值为1if w < 20 || h < 20 || w*h < 400continueelseif ratio < 2 && ratio > 0.6 &&findeye(gray,ux,uy,w,h) == 1 % 记录可能为人脸的矩形区域result(n,:) = [uxuy w h];n = n+1;endend% 对可能是人脸的区域进行标记if size(result,1) == 1 && result(1,1) > 0rectangle('Position',[result(1,1),result(1,2),result(1,3),result(1, 4)],'EdgeColor','r'); else% 如果满足条件的矩形区域大于1则再根据其他信息进行筛选for m = 1:size(result,1)m1 = result(m,1);m2 = result(m,2);m3 = result(m,3);m4 = result(m,4);% 标记最终的人脸区域if m1 + m3 < width && m2 + m4 <heigth< p=""> rectangle('Position',[m1,m2,m3,m4],'EdgeColor','r');endendendfindeye% 判断二值图像中是否含有可能是眼睛的块% bImage----二值图像% x---------矩形左上角顶点X坐标% y---------矩形左上角顶点Y坐标% w---------矩形宽度% h---------矩形长度% 如果有则返回值eye等于1,否则为0function eye = findeye(bImage,x,y,w,h)% 根据矩形相关属性得到二值图像中矩形区域中的数据% 存放矩形区域二值图像信息part = zeros(h,w);% 二值化fori = y:(y+h)for j = x:(x+w)ifbImage(i,j) == 0part(i-y+1,j-x+1) = 255;elsepart(i-y+1,j-x+1) = 0;endendend[L,num] = bwlabel(part,8);% 如果区域中有两个以上的矩形则认为有眼睛ifnum< 2eye = 0;elseeye = 1;endskin% Anil K.Jain提出的基于YCbCr颜色空间的肤色模型% 根据当前点的Cb Cr值判断是否为肤色function result = skin(Y,Cb,Cr)% 参数% a = 25.39;a = 28;% b = 14.03;b=18;ecx = 1.60;ecy = 2.41;sita = 2.53;cx = 109.38;cy = 152.02;xishu = [cos(sita) sin(sita);-sin(sita) cos(sita)];% 如果亮度大于230,则将长短轴同时扩大为原来的1.1倍if(Y > 230)a = 1.1*a;b = 1.1*b;end% 根据公式进行计算Cb = 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; % 大于1则不是肤色,返回0;否则为肤色,返回1if value > 1result = 0;elseresult = 1;end</heigth<>。
%% Face recognition% This algorithm uses the eigenface system (based on pricipal component% analysis - PCA) to recognize faces. For more information on this method% refer to /content/m12531/latest/%% Download the face database% You can find the database at the follwoing link,% /research/dtg/attarchive/facedatabase.html The% database contains 400 pictures of 40 subjects. Download the zipped% database and unzip it in the same directory as this file.%% Loading the database into matrix vw=load_database();%% Initializations% We randomly pick an image from our database and use the rest of the% images for training. Training is done on 399 pictues. We later% use the randomly selectted picture to test the algorithm.ri=round(400*rand(1,1)); % Randomly pick an index.r=w(:,ri); % r contains the image we later on will use to test the algorithmv=w(:,[1:ri-1 ri+1:end]); % v contains the rest of the 399 images.N=20; % Number of signatures used for each image.%% Subtracting the mean from vO=uint8(ones(1,size(v,2)));m=uint8(mean(v,2)); % m is the maen of all images.矩阵V每一行的均值vzm=v-uint8(single(m)*single(O)); % vzm is v with the mean removed.%% Calculating eignevectors of the correlation matrix% We are picking N of the 400 eigenfaces.L=single(vzm)'*single(vzm);[V,D]=eig(L);V=single(vzm)*V;V=V(:,end:-1:end-(N-1)); % Pick the eignevectors corresponding to the 10 largest eigenvalues.%% Calculating the signature for each imagecv=zeros(size(v,2),N);for i=1:size(v,2);cv(i,:)=single(vzm(:,i))'*V; % Each row in cv is the signature for one image.end%% Recognition% Now, we run the algorithm and see if we can correctly recognize the face.subplot(121);imshow(reshape(r,112,92));title('Looking for ...','FontWeight','bold','Fontsize',16,'color','red');subplot(122);p=r-m; % Subtract the means=single(p)'*V;z=[];for i=1:size(v,2)z=[z,norm(cv(i,:)-s,2)];if(rem(i,20)==0),imshow(reshape(v(:,i),112,92)),end;drawnow;end[a,i]=min(z);subplot(122);imshow(reshape(v(:,i),112,92));title('Found!','FontWeight','bold','Fontsize',16,'color','red');。
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 to FR_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 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_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_subfor X=1:2:sub_img %%%train on odd number of images of each 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 (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 CreateFcnscalled% 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人脸识别的matlab程序以下是LDA的m文件函数:你稍稍改改就能用了!function [eigvector, eigvalue, elapse] = LDA(gnd,options,data)% LDA: Linear Discriminant Analysis%% [eigvector, eigvalue] = LDA(gnd, options, data)%% Input:% data - Data matrix. Each row vector of fea is a data point.% gnd - Colunm vector of the label information for each % data point.% options - Struct value in Matlab. The fields in options % that can be set:%% Regu - 1: regularized solution,% a* = argmax(a'X'WXa)/(a'X'Xa+ReguAlpha*I)% 0: solve the sinularity problem by SVD% Default: 0%% ReguAlpha - The regularization parameter. Valid% when Regu==1. Default value is 0.1.%% ReguType - 'Ridge': Tikhonov regularization% 'Custom': User provided% regularization matrix% Default: 'Ridge'% regularizerR - (nFea x nFea) regularization% matrix which should be provided% if ReguType is 'Custom'. nFea is% the feature number of data % matrix% Fisherface - 1: Fisherface approach% PCARatio = nSmp - nClass % Default: 0%% PCARatio - The percentage of principal% component kept in the PCA % step. The percentage is % calculated based on the % eigenvalue. Default is 1 % (100%, all the non-zero % eigenvalues will be kept. % If PCARatio > 1, the PCA step% will keep exactly PCARatio principle% components (does not exceed the% exact number of non-zero components).%%% Output:% eigvector - Each column is an embedding function, for a new% data point (row vector) x, y = x*eigvector % will be the embedding result of x.% eigvalue - The sorted eigvalue of LDA eigen-problem. % elapse - Time spent on different steps%% 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;%%% See also LPP, constructW, LGE%%%%Reference:%% P. N. Belhumeur, J. P. Hespanha, and D. J. Kriegman, 揈igenfaces % vs. fisherfaces: recognition using class specific linear% projection,� IEEE Transactions on Pattern Analysis and Machine % Intelligence, vol. 19, no. 7, pp. 711-720, July 1997.%% Deng Cai, Xiaofei He, Yuxiao Hu, Jiawei Han, and Thomas Huang, % "Learning a Spatially Smooth Subspace for Face Recognition", CVPR'2007%% Deng Cai, Xiaofei He, Jiawei Han, "SRDA: An Efficient Algorithm for % Large Scale Discriminant Analysis", IEEE Transactions on Knowledge and% Data Engineering, 2007.%% version 2.1 --June/2007% version 2.0 --May/2007% version 1.1 --Feb/2006% version 1.0 --April/2004%% Written by Deng Cai (dengcai2 AT )%if ~exist('data','var')global data;endif (~exist('options','var'))options = [];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);if length(gnd) ~= nSmperror('gnd and data mismatch!');endclassLabel = unique(gnd);nClass = length(classLabel);Dim = nClass - 1;if bPCA & isfield(options,'Fisherface') & options.Fisherface options.PCARatio = nSmp - nClass;endif issparse(data)data = full(data);endsampleMean = mean(data,1);data = (data - repmat(sampleMean,nSmp,1));bChol = 0;if bPCA & (nSmp > nFea+1) & (options.PCARatio >= 1)DPrime = data'*data;DPrime = max(DPrime,DPrime');[R,p] = chol(DPrime);if p == 0bPCA = 0;bChol = 1;endend%======================================% SVD%======================================if bPCAif nSmp > nFeaddata = data'*data;ddata = max(ddata,ddata');[eigvector_PCA, eigvalue_PCA] = eig(ddata);eigvalue_PCA = diag(eigvalue_PCA);clear ddata;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);%=======================================if options.PCARatio > 1idx = options.PCARatio;if idx < length(eigvalue_PCA)eigvalue_PCA = eigvalue_PCA(1:idx);eigvector_PCA = eigvector_PCA(:,1:idx);endelseif options.PCARatio < 1sumEig = sum(eigvalue_PCA);sumEig = sumEig*options.PCARatio;sumNow = 0;for idx = 1:length(eigvalue_PCA)sumNow = sumNow + eigvalue_PCA(idx);if sumNow >= 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);clear ddata;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);%=======================================if options.PCARatio > 1idx = options.PCARatio;if idx < length(eigvalue_PCA)eigvalue_PCA = eigvalue_PCA(1:idx);eigvector = eigvector(:,1:idx);endelseif options.PCARatio < 1sumEig = sum(eigvalue_PCA);sumEig = sumEig*options.PCARatio;sumNow = 0;for idx = 1:length(eigvalue_PCA)sumNow = sumNow + eigvalue_PCA(idx);if sumNow >= 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;clear eigvector;endelseif ~bCholDPrime = data'*data;% options.ReguAlpha = nSmp*options.ReguAlpha;switch lower(options.ReguType)case {lower('Ridge')}for i=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('ReguType does not exist!');endDPrime = max(DPrime,DPrime');endend[nSmp,nFea] = size(data);Hb = zeros(nClass,nFea);for i = 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;if bPCA[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);if Dim > dimMatrixDim = dimMatrix;endif isfield(options,'bEigs')if options.bEigsbEigs = 1;elsebEigs = 0;endelseif (dimMatrix > 1000 & Dim < dimMatrix/10) | (dimMatrix > 500 & Dim < dimMatrix/20) | (dimMatrix > 250 & Dim < dimMatrix/30)bEigs = 1;elsebEigs = 0;endendif bEigs%disp('use eigs to speed up!');option = struct('disp',0);if bCholoption.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);if Dim < size(eigvector,2)eigvector = eigvector(:, 1:Dim);eigvalue = eigvalue(1:Dim);endendendfor i = 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人脸检测是人脸识别、人机交互、智能视觉监控等工作的前提。
完整版)基于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;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人脸检测是人脸识别、人机交互、智能视觉监控等工作的前提。