利用facerec代码包中的eigenface进行人脸识别

来源:互联网 发布:淘宝买灯具要3c认证吗 编辑:程序博客网 时间:2024/05/22 18:55

1.   一个非常好的人脸识别代码包:

https://www.github.com/bytefish/facerec

https://github.com/bytefish/facerecognition_guide

http://bytefish.de/blog/eigenfaces/

http://www.bytefish.de/blog/fisherfaces/

 

第一个网址是一个非常好的人脸识别代码包地址,里面实现了eigenface和fisherface两种人脸识别方法,分别用matlab/octave和python实现;

第二个网址好像是较早的一个实现版本,但是里面包括了详细的说明文档;

第三个和第四个网址是作者的写的关于eigenface和fisherface的博客。

值得一提的是,opencvfaceRecognizer的说明文档貌似也是这位作者所写的(http://docs.opencv.org/trunk/modules/contrib/doc/facerec/index.html)。


2.   利用facerec代码包中的eigenface进行人脸识别:

2.1        训练eigenface model:

close all;clear;clc;% read imagesimage_path = 'att_faces_select';[X y width height names] = read_images(image_path);% compute a model[d,n] = size(X);num_components = 30;eigenface = eigenfaces(X,y,num_components);%% plot the first (atmost) 16 eigenfacesfigure; title('Eigenfaces');hold on;for i=1:min(16, size(eigenface.W,2))  subplot(4,4,i);  comp = cvtGray(eigenface.W(:,i), width, height);  imshow(comp);  %colormap(jet(256));  title(sprintf('Eigenface %i', i));end%% 3D plot of projection (first three classes, add those you want)if(d >= 3)  figure; hold on;  for i = findclasses(eigenface.y, [1,2,3])    % LineSpec: red dots 'r.'    plot3(eigenface.P(1,i), eigenface.P(2,i), eigenface.P(3,i), 'r.'), view(45,-45);    text(eigenface.P(1,i), eigenface.P(2,i), eigenface.P(3,i), num2str(eigenface.y(i)));  endend%% save eigenfaces and namessave eigenface.mat eigenface names

首先利用read_images函数读入训练图像,read_images函数的参数是训练图像所在路径,注意,不同subject的图像应放在独自的文件夹中,read_images函数会给每个文件夹一个类别值(从1递增),并会记录每个文件夹的名字作为subject的名字。函数的输出参数X是把所有训练图像连接到一起组成的数据,其中每个二维图像都被转换为一维数据,存储成一列;输出参数y是各个图像所属类别值的集合;names是各个图像文件夹名字,即作为subject的名字。

之后调用eigenfaces函数训练eigenface,其中第三个输入参数为component个数,该参数可以省略,省略时eigenfaces函数内部取图像数目减1为component个数(是否应取类别个数减1为component个数呢?待考),输出参数为训练出的eigenface model。

之后会显示前16个eigenfaces.

之后会3d显示所有eigenface的位置,显示的是每个eigenface投影空间中三个数据组成的坐标值。Findclasses作用(???)

最后将eigenface和names保存。


2.2    预测图像

close all;clear;clc;% user defined variablethreshold = 0.65;%% load eigenface modelload eigenface.mat%% load image%filename = 'train_set/lcy_train/frame4_face0.jpg';%filename = 'train_set/meilin_train/frame4_face0.jpg';%filename = 'test_set/lcy_test/frame24_face0.jpg';%filename = 'test_set/meilin_test/frame4_face0.jpg';filename = 'att_faces_select/s3/2.pgm';try    T = double(imread(filename));catch    lerr = lasterror;    fprintf(1,'Cannot read image %s', filename)end[height width channels] = size(T);% greyscale the image if we have 3 channelsif(channels == 3)    T = (T(:,:,1) + T(:,:,2) + T(:,:,3)) / 3;endtest_image = [];try    test_image = [test_image, reshape(T,width*height,1)];catch    lerr = lasterror;    fprintf(1,'Image cannot be added to the Array. Wrong image size?\n')end%% predictk = 9;%Predicts nearest neighbor for given Eigenfaces model.model = eigenface;Q = model.W' * (test_image - model.mu);[c, v, mean_k_dis, mean_all_dis] = my_knn(model.P, model.y, Q,  k);%% show resultfigure;imshow(T,[]);display(sprintf('subject: %s, mean_k_dis=%.2f, mean_all_dis=%.2f, dis_ratio=%.2f', names{c}, mean_k_dis, mean_all_dis, mean_k_dis/mean_all_dis));display(sprintf('\tv=%i, k=%i', v, k));if mean_k_dis/mean_all_dis < threshold    title(names{c});else    title('unknown');end

首先载入eigenface model数据;

其次载入待预测的图像数据,如果是彩色图,将其转换成灰度图;并将二维数据重新排列成一维向量数据;

之后利用训练好的eigenface model对test_image进行投影得到feature数据Q, 再对Q做knn分类,knn分类用my_knn函数实现,该函数改写自代码包中的knn函数。my_knn函数返回值包括:

c: test_image所属类别;

v:与test_image所属同一类别的neighbor个数;

mean_k_dis: Q和k个neighbor的平均距离,这k个neighbors是与Q距离最近的K个;

mean_all_dis: Q和所有vector的平均距离。

最后显示结果,从控制台显示subject名字, mean_k_dis, mean_all_dis和二者的比值,并显示v和k的值;

当mean_k_dis/mean_all_dis小于一定阈值时,认为正确识别,图像的title显示subject名字,否则认为未正确识别,图像的title显示unknown。

图像结果:


控制台输出结果:

subject: s3, mean_k_dis=3059.42, mean_all_dis=4770.58, dis_ratio=0.64
v=9, k=9



my_knn实现:

function [c, v, mean_k_dis, mean_all_dis] = my_knn(P, y, Q,  k)%%My k-nearest neighbor classification.%%%%Args:%%P [dim x num_data] reference vectors%%Q [dim x 1] query vector%%y [1 x num_data] classes corresponding to P. (y = {1,2,...,n})%%k [int] nearest neighbors used in this prediction%%%%Returns:%%c [int] Class identified by the majority of k neighbors.%%      v [int] Number of majority of k neighbors.    %%      mean_k_dis [double] Mean distance of Q to the k neighbors.    %%      mean_all_dis [double] Mean distance of Q to all vectors of P.n = size(P,2);% clip kif (nargin == 3)k=1;elseif (k>n)k=n;endQ = repmat(Q, 1, n);distances = sqrt(sum(power((P-Q),2),1));[distances, idx] = sort(distances);y = y(idx);y = y(1:k);h = histc(y,(1:max(y)));[v,c] = max(h);        min_k_dist = distances(1:k);    mean_all_dis = mean(distances);    mean_k_dis = mean(min_k_dist);end


1 0
原创粉丝点击