1.描述 用有监督学习机制设计并实现模式识别方法,用于进行人脸面部特征识别,如性别(男性、女性)、年龄(儿童、青少年、成年、老年)、佩戴眼镜(是、否)、戴帽子(是、否)、表情(微笑、严肃)等。 2.数据 数据来源:链接:https://pan.baidu.com/s/17zU6A4-8Zs-TjspizbAOhA 提取码:dpb1 3.实现过程
4.特征提取
程序流程图:
5. 特征提取代码
function [dataFaceR_maleExtra,dataFaceR_femaleExtra,dataFaceS_maleExtra,dataFaceS_femaleExtra] = sexDistanceJ2(dataFaceR_male,dataFaceR_female,dataFaceS_male,dataFaceS_female,dimension)
%UNTITLED2 此处显示有关此函数的摘要
%{
函数输入:各个类别的数据,特征提取的维数dimension
函数的输出:经过特征提取后的各类别数据
函数的功能:基于可分性依据J2进行特征的提取
%}
% 此处显示详细说明
[maleRow,maleCol] = size(dataFaceR_male);%获取dataFaceR_male的行数和列数
[femaleRow,femaleCol] = size(dataFaceR_female);%获取dataFaceR_female的行数和列数
%求类内的均值向量
%maleMean = mean(dataFaceR_male(:,1:maleCol+1)); %男性的均值向量
maleMean = mean(dataFaceR_male); %男性的均值向量
%femaleMean = mean(dataFaceR_female(:,1:femaleCol+1));%女性的均值向量
femaleMean = mean(dataFaceR_female);%女性的均值向量
%类别先验概率
maleP = 0.5; %男性先验概率
femaleP = 0.5;%女性先验概率
sexTotalMean = maleMean.*maleP + femaleMean.*femaleP; %性别总体均值
%求类间离散度矩阵
discreteSbMale = (maleMean - sexTotalMean)' * (maleMean - sexTotalMean);
discreteSbFemale = (femaleMean - sexTotalMean)' * (femaleMean - sexTotalMean);
discreteSb = discreteSbMale.*maleP + discreteSbFemale.*femaleP;
%求类内离散度矩阵
maleDiscrete = zeros(99,99);
femaleDiscrete = zeros(99,99);
for i=1:maleRow
maleDiscrete = maleDiscrete + (dataFaceR_male(i,:) - maleMean(1,:))' * (dataFaceR_male(i,:) - maleMean(1,:));
end
maleDiscreteSw = (maleDiscrete.*maleP)./maleRow; %计算男性类的类内的离散度
for i=1:femaleRow
femaleDiscrete = femaleDiscrete + (dataFaceR_female(i,:) - femaleMean(1,:))' * (dataFaceR_female(i,:) - femaleMean(1,:));
end
femaleDiscreteSw = (femaleDiscrete.*femaleP)./femaleRow; %计算女性类的类内的离散度
discreteSw = maleDiscreteSw + femaleDiscreteSw;%类内总的离散度
%求变换矩阵
transforMatrix = discreteSw\discreteSb;
%求变换矩阵的特征值瑜特征向量
[featureVec,eigenValMat] = eig(transforMatrix); %featureVec:特征向量,eigenValMat:对角矩阵
eigenVal = diag(eigenValMat); %取对角矩阵的元素,组成一列
%求特征值矩阵的行数和列数
[eigenValRow,eigenValCol] = size(eigenVal);
vec = zeros(eigenValRow,1); %做为中间变量进行排序
Eig = zeros(1,1); %作为中间变量对特征值从大到小排序
%将特征值从大到小排序并跟着调制特征向量。
for i=1:eigenValRow
k = eigenValRow - i;
for j=1:k
Eig = eigenVal(j,1);
vec(:,1) = featureVec(:,j);
if(eigenVal(j+1,1)>=Eig)
eigenVal(j,1) = eigenVal(j+1,1);
featureVec(:,j) = featureVec(:,j+1);
eigenVal(j+1,1) = Eig;
featureVec(:,j+1) = vec(:,1);
end
end
end
%获得降到dimension维数的变换矩阵
extraMatrix = featureVec(:,1:dimension);
% extraMatrix = featureVec(:,1:50);
for i=1:maleRow
dataFaceR_maleExtra1 = dataFaceR_male(i,:)*extraMatrix;
dataFaceR_maleExtra(i,:) = dataFaceR_maleExtra1;
end
for j=1:femaleRow
dataFaceR_femaleExtra1 = dataFaceR_female(j,:)*extraMatrix;
dataFaceR_femaleExtra(j,:) = dataFaceR_femaleExtra1;
end
%=================================================================================================================
[maleRowS,maleColS] = size(dataFaceS_male);%获取dataFaceR_male的行数和列数
[femaleRowS,femaleColS] = size(dataFaceS_female);%获取dataFaceR_female的行数和列数
%求类内的均值向量
maleMeanS = mean(dataFaceS_male); %男性的均值向量
femaleMeanS = mean(dataFaceS_female);%女性的均值向量
%类别先验概率
malePS = 0.5; %男性先验概率
femalePS = 0.5;%女性先验概率
sexTotalMeanS = maleMeanS.*malePS + femaleMeanS.*femalePS; %性别总体均值
%求类间离散度矩阵
discreteSbMaleS = (maleMeanS - sexTotalMeanS)' *(maleMeanS - sexTotalMeanS) ;
discreteSbFemaleS = (femaleMeanS - sexTotalMeanS)' *(femaleMeanS - sexTotalMeanS);
discreteSbS = discreteSbMaleS.*malePS + discreteSbFemaleS.*femalePS;
%求类内离散度矩阵
maleDiscreteS = zeros(99,99);
femaleDiscreteS = zeros(99,99);
for i=1:maleRowS
maleDiscreteS = maleDiscreteS + (dataFaceS_male(i,:) - maleMeanS(1,:))'*(dataFaceS_male(i,:) - maleMeanS(1,:));
end
maleDiscreteSwS = (maleDiscreteS.*malePS)./maleRowS; %计算男性类的类内的离散度
for i=1:femaleRowS
femaleDiscreteS = femaleDiscreteS + (dataFaceS_female(i,:) - femaleMeanS(1,:))' * (dataFaceS_female(i,:) - femaleMeanS(1,:));
end
femaleDiscreteSwS = (femaleDiscreteS.*femalePS)./femaleRowS; %计算女性类的类内的离散度
discreteSwS = maleDiscreteSwS + femaleDiscreteSwS;%类内总的离散度
%求变换矩阵
% ivdiscreteSwS = inv(discreteSwS); %Sw矩阵的逆
% transforMatrixS = ivdiscreteSwS .* discreteSbS;
%求变换矩阵
transforMatrixS = discreteSwS\discreteSbS;
%求变换矩阵的特征值瑜特征向量
[featureVecS,eigenValMatS] = eig(transforMatrixS); %featureVec:特征向量,eigenValMat:对角矩阵
eigenValS = diag(eigenValMatS); %取对角矩阵的元素,组成一列
%求特征值矩阵的行数和列数
[eigenValRowS,eigenValColS] = size(eigenValS);
vecS = zeros(eigenValRowS,1); %做为中间变量进行排序
EigS = 0; %作为中间变量对特征值从大到小排序
%将特征值从大到小排序并跟着调制特征向量。
for i=1:eigenValRowS
for j=1:eigenValRowS - i
EigS = eigenValS(j,1);
vecS(:,1) = featureVecS(:,j);
if(eigenValS(j+1,1)>=EigS)
eigenValS(j,1) = eigenValS(j+1,1);
featureVecS(:,j) = featureVecS(:,j+1);
eigenValS(j+1,1) = EigS;
featureVecS(:,j+1) = vecS(:,1);
end
end
end
%获得降到dimension维数的变换矩阵
extraMatrixS = featureVecS(:,1:dimension);
% extraMatrixS = featureVecS(:,1:50);
for i=1:maleRowS
dataFaceS_maleExtra1 =dataFaceS_male(i,:) * extraMatrixS;
dataFaceS_maleExtra(i,:) = dataFaceS_maleExtra1;
end
for j=1:femaleRowS
dataFaceS_femaleExtra1 =dataFaceS_female(j,:) * extraMatrixS;
dataFaceS_femaleExtra(j,:) = dataFaceS_femaleExtra1;
end
end
6.算法
function [predictSex_label, accuracySex, dec_valuesSex,lable_sexR,lable_sexS,dataFaceR_sexKnn,dataFaceS_sexKnn,label_sexRKnn,label_sexSKnn] = sex(dataFaceR_maleExtra,dataFaceR_femaleExtra,dataFaceS_maleExtra,dataFaceS_femaleExtra)
%UNTITLED 此处显示有关此函数的摘要
% 此处显示详细说明
dataFaceR_sex =[dataFaceR_maleExtra;dataFaceR_femaleExtra];
dataFaceR_sexKnn =dataFaceR_sex';
dataFaceR_sex = real(dataFaceR_sex);
[RsexRow,RsexCol] =size(dataFaceR_sex);
dataFaceS_sex = [dataFaceS_maleExtra;dataFaceS_femaleExtra];
dataFaceS_sexKnn =dataFaceS_sex';
dataFaceS_sex = real(dataFaceS_sex);
[SsexRow,SsexCol] = size(dataFaceS_sex);
[maleRow,maleCol] = size(dataFaceR_maleExtra);
[femaleRow,femaleCol] = size(dataFaceR_femaleExtra);
[maleRowS,maleColS] = size(dataFaceS_maleExtra);
[femaleRowS,femaleColS] = size(dataFaceS_femaleExtra);
lable_sexR = zeros(RsexRow,1);
lable_sexS = zeros(SsexRow,1);
for i=1:RsexRow
if(i<=maleRow)
lable_sexR(i,1) = 1; %男性的标签为1,女性的标签为0
elseif(i>maleRow)
lable_sexR(i,1) = 2;
end
end
label_sexRKnn = lable_sexR';
for i=1:SsexRow
if(i<=maleRowS)
lable_sexS(i,1) = 1; %男性的标签为1,女性的标签为0
elseif(i>maleRowS)
lable_sexS(i,1)=2;
end
end
label_sexSKnn = lable_sexS';
%==============================SVM==========================================================
t1=cputime;
model = svmtrain(lable_sexR,dataFaceR_sex);
[predictSex_label, accuracySex, dec_valuesSex] = svmpredict(lable_sexS, dataFaceS_sex, model); % test the trainingdat
t2=cputime;
t=t2-t1
%===============================随机森林===================================================
nTree = 20;
t1=cputime;
B = TreeBagger(nTree,dataFaceR_sex,lable_sexR);
predict_label = predict(B,dataFaceS_sex);
t2=cputime;
t=t2-t1
%predict_label为待转换的cell
for n=1:length(predict_label)
x{n}=str2num(predict_label{n});
end
for m=1:length(x)
y(m)=x{m}(1);
end
%y即为所得double类型数据
y=y';
a=0;
for i=1:SsexRow
if(y(i,1)==lable_sexS(i,1))
a=a+1;
end
end
accuracy = a/SsexRow
%=======================================贝叶斯========================================
t1=cputime;
nb =fitcnb(dataFaceR_sex,lable_sexR);
predict_label = predict(nb,dataFaceS_sex);
t2=cputime;
t=t2-t1
a=0;
for i=1:SsexRow
if(predict_label(i,1)==lable_sexS(i,1))
a=a+1;
end
end
accuracy = a/SsexRow
%==================================集成方法============================================
% ens = fitensemble(dataFaceR_sex,lable_sexR,'AdaBoostM1' ,100,'tree','type','classification');
% predict_label = predict(ens, dataFaceS_sex);
% a=0;
% for i=1:SsexRow
% if(predict_label(i,1)==lable_sexS(i,1))
% a=a+1;
% end
% end
% accuracy = a/SsexRow
%================================鉴别分析分类器===========================================
% obj = ClassificationDiscriminant.fit(dataFaceR_sex,lable_sexR);
% predict_label = predict(obj, dataFaceS_sex);
% a=0;
% for i=1:SsexRow
% if(predict_label(i,1)==lable_sexS(i,1))
% a=a+1;
% end
% end
% accuracy = a/SsexRow
%============================KNN===================================================
t1=cputime;
mdl = ClassificationKNN.fit(dataFaceR_sex,lable_sexR,'NumNeighbors',50);
predict_label = predict(mdl, dataFaceS_sex);
t2=cputime;
t=t2-t1
a=0;
for i=1:SsexRow
if(predict_label(i,1)==lable_sexS(i,1))
a=a+1;
end
end
accuracy = a/SsexRow
end