pgm是什么意思 pgm是什么意思

目标
目的:为了让大家了解图像识别和检索的算法开发过程,以及加深对特征和分类器的理解 。
概要
对于图像分类和检索来说,最重要的有两个内容,一个是特征提取方法,另一个是分类方法 。图像识别就是先提取图像的特征,然后根据图像的特征进行分类识别的过程 。为了让大家最快的了解图像识别算法的开发过程,我特意使用“图像尺寸缩小+欧式距离”的思想编写了相应的程序 。算法实现的流程图如下图所示 。

pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
pgm是什么意思 pgm是什么意思

文章插图
,这都告诉你们了,感觉损失大了)
为了实现本文的算法,我特意使用上面的公式编写了一个欧式距离分类器 。即edpredict.m文件 。下面简单的介绍一下该函数文件 。
该函数文件的源代码如下所示:
function = edpredict(dtrain,dtest,ltrain,ltest)
---------------------------------------------------------------------------------------------------------------标记1
if nargin ~= 4
disp('输入的参数必须是4个');
return;
end
if length(size(dtrain)) ~= 2
disp('训练样本必须是二维矩阵!');
return;
end
if length(size(dtest)) ~= 2
disp('测试样本必须是二维矩阵!');
return;
end
if size(dtrain,2) ~= size(dtest,2)
disp('测试样本特征向量维度应该和训练样本特征向量维数相同!');
end
--------------------------------------------------------------------------------------------------------------标记2
dtrain = double(dtrain); % 训练数据
dtest = double(dtest); % 测试数据
ltrain = double(ltrain); % 训练样本标签
ltest = double(ltest); % 测试样本标签
-------------------------------------------------------------------------------------------------------------标记3
= size(dtrain);
= size(dtest);
index = zeros(m2,1);
-------------------------------------------------------------------------------------------------------------标记4
for i = 1:m2
distance = 1000000;
for j = 1:m1
temp = sqrt(norm(dtest(i,:) - dtrain(j,:)));
if distance > temp
distance = temp;
index(i) = ltrain(j); % 预测标签
end
end
end
-------------------------------------------------------------------------------------------------------------标记5
accuracy = 100*sum(index == ltest)/m2; % 准确度
str = strcat('accuracy = ',num2str(accuracy),'%',' (classify)');
disp(str);
end
首先说function 。MATLAB的m文件有两种,一种是脚本文件,一种是函数文件 。它们的相同点都是由一系列的命令组成的,但是,脚本文件不能返回变量哦,函数文件可以啊!即,调用脚本文件时,它能实现一定的功能并产生一些结果,但是不能返回任何东东到调用的位置 。但是当调用函数文件时,处理完成脚本文件的功能外,还能返回变量到调用位置 。大家明白没有?没有的话baidu或看看matlab教程 。不过话说回来,大家不明白也就算了,这里其实就想说function的功能是:声明本文件是函数文件,不是脚本文件 。(脚本文件的话,开头没有标志性的语句,直接开始写自己的代码就可以了)
第一行“function = edpredict(dtrain,dtest,ltrain,ltest)”叫函数头,function声明这是函数文件,等号左边是函数的返回变量,即;等号右边是函数名(edpredict)和输入参数” (dtrain,dtest,ltrain,ltest)” 。注意几点:①定义函数时,函数的名字一定想好,不要和MATLAB自带函数重名;②参数之间都是用逗号间隔开的,记住哦!!!
从第二行开始下面是4个if条件语句 。第一个if语句,如下所示:
if nargin ~= 4
disp('输入的参数必须是4个');
return;
end
它的功能是:判断输入变量个数是不是4个,nargin表示输入变量个数,当nargin不等于4时,在命令窗口中显示“输入的参数必须是4个”,并终止整个程序(由return实现) 。注意:if语句和for循环都是用end结束的 。
第2个if语句的功能是:判断输入变量dtrain的维数是否是2维,如果不是2维的话,就报错,并终止程序 。
第3个if语句的功能和第2个if语句几乎相同,只不过这里判断的变量是dtest 。
第4个if语句的功能是判断训练样本的特征向量维数和测试样本的特征向量维数是否相等 。如果不相等,欧氏距离也就没有办法计算了!!!
思考:为什么加这些if语句?
编写函数文件是为了实现一定的功能的,但它只能处理特定的数据 。如果输入的数据不符合程序的需要,程序执行过程中也会报错(这还是好事,如果不报错,你的程序按照错误的方式执行,你还以为结果是正确的,这才真悲剧!) 。所以,为了程序的正常运行,有必要在正式执行程序前,检测一下输入变量是否符号要求 。
下面就是程序的主要内容了,就像脚本文件中一样写代码就可以了 。标记2下面的四行语句的功能是将输入变量都变成double型,目的是为了防止有的输入变量不是双精度 。这四行分别将训练样本、测试样本、训练样本标签和测试样本标签变成双精度数据 。
标记3和标记4之间的代码如下所示:
= size(dtrain);
= size(dtest);
index = zeros(m2,1);
第一行代码计算了dtrain的尺寸,m1即dtrain的行数;同理,第2行代码计算dtest的行数m2 。第3行生成的全0变量index,是用来存储测试样本的预测标签的 。
标记4下面的for循环实现了欧式距离分类器的功能 。其中,i=1:m2分别对应每一个测试样本,即最外边的循环执行一次,就处理一个测试样本 。”distance = 1000000;”设定了初始距离(该距离必须足够大) 。内部的for循环j = 1:m1 是对所有的训练样本进行了遍历,其实就是一个测试样本和所有的训练样本做了次比较 。“temp = sqrt(norm(dtest(i,:) - dtrain(j,:)));”就是利用上面的公式计算欧式距离 。下面的if语句实现的功能是:判断刚刚计算的欧式距离temp和参考距离distance的大小关系,当temp小于distance时,说明这两个样本之间的距离更近(欧式距离又称为最近距离法,当然认为最近的两个样本为同一类了),就把temp的值赋给distance,并将该训练样本的标签放到index中,作为该测试样本的预测标签 。总的来说,就是先拿出一个测试样本,然后计算它和所有训练样本之间的距离,与它距离最近的训练样本的标签就是该测试样本的预测值 。
标记5下面的语句就是实现计算准确度,并在命令窗口中显示准确度 。第一个语句计算了准确度,index是测试样本的预测值,ltest是测试样本的实际值,如果它们相等,就说明预测结果对呗 。求预测对的个数sum()并除以总数m2,就得到了准确度 。
最简人脸识别程序
最简单的人脸识别算法的实现程序在FaceED1.m文件中,当然为了便于大家观察,还是将代码贴在下面吧 。
% ORL人脸库 + 欧式距离分类器
% 有均值化
clear;
clc;
-------------------------------------------------------------------------------------------------------------标记1
M=40; %40个人
N=5; %选每个人的前五幅图片
row=8; %图像尺寸归一化后的行数
clum=7; %图像尺寸归一化后的列数
pho=zeros(row*clum,M*N); %用来存储训练样本
pic=zeros(row*clum,M*(10-N)); %用来存储测试样本
-------------------------------------------------------------------------------------------------------------标记2
% 导入训练样本
t=1; %赋值t的值为1
for i=1:M
for j=1:N
str=strcat('F:\科研\人脸识别\人脸数据库\ORL\',num2str(i),'_',num2str(j),'.pgm');%获得图像的路径
I1=imread(str); %读入图像
I2=imresize(I1,); % 尺寸变换
pho(:,t) = reshape(I2,); % 形状变换
t=t+1; %计数变量t加1
end
end
dtrain = pho'; % 转置,dtrain中每一行表示一个样本
-------------------------------------------------------------------------------------------------------------标记3
% 导入测试样本
t = 1;
for i=1:M
for j=N+1:10
str=strcat('F:\科研\人脸识别\人脸数据库\ORL\',num2str(i),'_',num2str(j),'.pgm');%获得图像的路径
I1=imread(str); %读入图像
I2=imresize(I1,); % 尺寸变换
pic(:,t) = reshape(I2,); % 形状变换
t=t+1; %计数变量t加1
end
end
dtest = pic';
-------------------------------------------------------------------------------------------------------------标记4
% 获取标签
ltrain = zeros(M*N,1); % 存储训练样本的标签
ltest = zeros(M*(10-N),1); % 存储测试样本的标签
for i=0:M-1
ltrain((N*i+1):(N*i+N),1)=i+1; % 添训练样本加标签
ltest(((10-N)*i+1):(10-N)*(i+1),1)=i+1; % 添加测试样本标签
end
-------------------------------------------------------------------------------------------------------------标记5
= edpredict(dtrain,dtest,ltrain,ltest);
上面的程序中已添加了必要的注释,为了更好的理解本程序,下面给出了简要的说明 。标记1上面的东东就是清空工作空间和命令窗口的 。这也是MATLAB写脚本文件的常识,其实,就是为了防止工作空间中的变量影响程序的运行 。当然,这不是硬性的要求,不过还是建议添加,这样子更专业点哦!
对了,忘了说了,这个就是一个脚本文件,开头没有function引导哦 。知道区别了吧!不知道的话google去吧~
标记1和标记2之间的东东就是设置一个参数,“M=40;”限定了使用40个人的图像,当然也可以改成20,或10,分别表示使用20个人或10个人的样本图像 。“N=5;”限定了每个人的训练样本数量,就是说,每个人有10个样本图像,取前5个作为训练样本(剩下的呢,当然是用来做测试样本了) 。“row=8; clum=7; ”限定了图像的尺寸变换后的尺寸 。前面讲到,使用imresize()函数变换图像的尺寸,row和clum分别是尺寸变换后的行数和列数 。“pho=zeros(row*clum,M*N);”预定义变量pho,用来存储训练样本数据;同理,pic用来存储测试样本数据 。对zeros函数有任何疑问,可以看前面的讲解,也可以到网络中寻求帮助 。
在讲解下面的内容之前,需先说明一个问题 。前面的流程图中,是先将ORL人脸库进行尺寸变换和形状变化,然后才将其分成训练样本和测试样本 。在编写程序的时候,为了方便,我先将ORL库分成了训练样本和测试样本,然后在分别对其进行尺寸变换 。即标记2和标记3之间导入的是训练样本;标记3和标记4之间时导入的测试样本 。
下面先说如何导入训练样本,见标记2和标记3之间的代码 。“t = 1;”t是计数变量,这里是对其赋初值,它的作用就是指定样本数据放在pho矩阵的位置 。for循环有2层,外边的循环是对每个人进行遍历,里面的for循环是对某个人的样本图像进行遍历 。简单的说,就是先固定一个人,然后将它的样本(用作训练的N个)都导入,接着进行第2人,…,直到第M个人 。“t=t+1;”的位置在最内层,它的作用是每导入一幅图像,则t的值就增加1 。前面提到t决定样本数据放置在pho矩阵中的位置,假如当前导入的图像放在pho的第t列,则下一幅图像就要放在t+1列,否则,数据就会覆盖掉原来的数据,understand???
同理,标记3和标记4之间的程序实现将测试样本导入到MATLAB中 。注意:“j=N+1:10”,j变量啥意思来?为什么从N+1开始,而不是从1开始???思考一下 。
前面提到ORL库中一个人有十幅样本图像,选前N个(1:N)个作为训练样本,剩余的(N+1:10)作为测试样本 。明白没?
标记4到标记5间的代码功能是:获取标签 。标签分为训练样本标签ltrain和测试样本标签ltest 。前两行代码是预定义变量ltrain和ltest 。下面的for循环是生成标签 。其中,训练样本标签和训练样本是对应的;测试样本标签和测试样本对应的 。这里一定要理解好,第一个人的标签是1,第2个人的标签是2,…,第40个人的标签是40 。理解这里,还要理解ltrain和ltest中数据的排列方式,在ltrain中,每一行存储了一个样本图像的数据,而且还有一点特点,那就是同一个的N幅训练样本在ltrain中式连续排列的,例如,ltrain中前5行对应第1个人的样本图像,ltrain中6-10行对应第2个人的样本图像 。同理ltest也是如此 。添加标签的时候,也是按照这种连续性添加的,当然也不反对你手工一个个添加,只要你不嫌麻烦!
标记5下面的语句就是调用edpredict()函数,使用欧式距离判别法分类识别 。其中,返回变量pre是返回的测试样本的预测标签,accuracy是测试样本预测的准确度 。
【pgm是什么意思 pgm是什么意思】至此,最简人脸识别算法讲完了,大家赶快学习吧!!!

    推荐阅读