基于Matlab LBP实现植物叶片识别功能
一、LBP简介
第一章 引言
植物在我们的身边随处可见,它们从产生发展进化到现在,其间经历了漫长的岁月。地球上的植物种类繁多、数量浩瀚,它们是生物圈的重要组成部分,在维持整个生物界的平衡方面发挥着巨大的作用;它们同时也是构成人类生存环境的重要组成部分,是人类社会延续和发展不可或缺的重要因素。由于植物对于地球和人类都具有如此重要的意义,对它们的研究就显得尤为重要,但不同种类的植物在形态构造、生活习性、经济价值等各方面都表现出不同的特性,为了能更好、更有效地研究和利用各种植物,人们对植物进行了识别和分类,从而产生了植物分类学。在计算机科学与技术广泛渗透于的大环境中,如何将计算机的各种相关技术应用于该领域也就成为研究工作中一项非常重要的内容。
1.1 课题的提出与研究意义
自然界的植物是世界上物种数量最多并且分布最广泛的的生命形式,与人类以及环境的关系最为密切。而即使是最专业的科学家也不可能记住所有植物的种类。所以由于人类生产活动造成了植物物种的灭绝的实例也数不胜数。而植物在维持生物平衡、水土保持等方面又起着重要的作用;同时,植物农业作为国民经济命脉,是人们生产生活的基础部分,提高农业生产需要植物的精细数据,因此植物分类和识别具有非常重要的意义。一方面,人们能够通过植物识别系统毫不费力的查询到植物的种类以及其他相关信息,能够更好的保护濒危物种,帮助维持生态平衡,另一方面,通过植物叶片图像也可以鉴别出植物是否受到病虫害。因此我们希望建立植物叶片识别系统来对农作物以及各种稀有植物进行识别。采用模式识别和图像处理的方法,用计算机软件来对农作物病虫害以及各种植物进行分析、鉴别,从而实现稀有物种的快速鉴别或者农作物病虫害的自动诊断。因此,开发一种快速、准确的识别植物叶片的方法极具现实意义。
1.2 国内外相关研究情况
植物的分类与识别一般选取植物的局部特征[1],例如植物的叶、花、根等特征。这些器官都有各自的分类价值,但是比起植物的其他器官,植物叶片的存活时间较长,在一年的大部分时间里都可较为方便的采集到,所以作为植物的识别特征和认知植物的主要参照器官。因此基于叶片的识别是识别一种植物最直接有效的切最简单的方法。
Ojala[2]等人于2002年提出的局部二进制模式(LBP)[3],LBP算子定义为在33的窗口内,以窗口中心像素为阈值,将相邻的8个像素的灰度值与其进行比较,若周围像素值大于中心像素值,则该像素点的位置被标记为1,否则为0。33领域内的8个点可产生8bit的无符号数,即得到该窗口的LBP值,并用这个值来反映该区域的纹理信息.该方法分析纹理的吸引人的地方在于其计算复杂度小,具有多尺度特性和旋转不变特性,在纹理检索领域[4]得到应用。局部二值模式(LBP)是由Ojala等人于2002年提出,它被用于特征提取,而且,提取的特征是图像的纹理特征,并且,是局部的纹理特征。
局部二值模式(LBP)提取的特征跟位置信息是紧密相关的。直接对两幅图片提取这种特征,并进行判别分析的话,会因为“位置没有对准”而产生很大的误差。后来,研究人员发现,可以将一幅图片划分为若干的子区域,对每个子区域内的每个像素点都提取LBP特征,然后,在每个子区域内建立LBP特征的统计直方图。如此一来,每个子区域,就可以用一个统计直方图来进行描述;整个图片就由若干个统计直方图组成。
原始的LBP提出后,研究人员不断对其提出了各种改进和优化,从而得到了诸如半径为R的圆形区域内含有P个采样点的LBP算子;LBP均匀模式;LBP旋转不变模式;LBP等价模式[5] 。
1.3 论文的主要研究工作
本文的研究工作主要包括以下几个方面:综述了模式识别相关技术的研究现状,研究了 LBP 方法以及 LBP 算子的相关理论、研究及应用,设计并实现了基于 LBP的植物叶片识别系统,并用叶片样本对系统进行了测试验证。
本文深入研究了 LBP 方法的相关理论。LBP 方法将图像纹理的两种不同分类方法(即基于统计特征判别的分类方法和基于结构特征判别的分类方法)有效地结合了起来,在一定程度上解决了对图像纹理构成的单一分类所带来的问题。LBP 算子是提取图像 LBP 特征的具体工具,本文详细介绍了 LBP 算子的基本方法。
本文规划了系统的体系结构,设计了系统的工作流程,将整个系统所实现的功能分成了样本采集和预处理模块、LBP 特征提取模块和数据库模块等三个个功能模块,然后对系统流程的各主要环节的设计与实现进行了详细的介绍。
实际采集了3种不同植物的叶片图像样本,样本总数将近40例。用这些样本对系统进行了测试,得到了测试结果。
本文主要的工作在于应用 LBP 方法进行植物叶片样本纹理分析,进而设计与实现了基于 LBP 的植物叶片分类识别系统。虽然 LBP 方法的应用领域涉及面很广,但是目前在植物叶片分类识别领域几乎还没有相关的研究和应用,有很多具体的理论研究与实践应用方面的工作还有待于进一步的深化。本文所设计与实现的基于 LBP 的植物叶片识别系统属于该领域内的创新工作。
1.4 论文结构
本文结构如下:
第一章 绪论
阐述课题背景,分析特征提取及LBP方法的国内外研究现状,明确课题研究的意义及目标,介绍论文的主要工作;并对论文结构安排做了说明。
第二章 LBP方法的理论研究
对LBP特征提取的相关概念进行介绍,重点介绍LBP相关原理及基本特性,针对本研究课题,重点研究LBP特征在相关领域中的应用,针对当前的主要应用对LBP方法进行分析,为本文研究奠定理论基础。
第三章基于LBP植物叶片识别系统设计
主要阐述了植物叶片识别系统的总体设计思路,并且详细介绍了每个系统模块的设计思想。在此基础之上,更加详细的介绍了每个系统模块的主要功能和实现方法。同时,介绍了关键环节的设计。
第四章实验结果
主要展示了本次研究得到的成果,分析实验结果,验证了基于LBP特征提取在植物叶片识别中的可行性。
第五章总结与展望
对论文的主要研究工作和贡献进行总结,并在当前工作的基础上,结合研究中遇到的问题,为下一步研究工作提供参考。
二、部分源代码
clc;clear; allsamples=[];%所有训练图像 M=300;N=300; SubNum=3; SubRow = M/SubNum; SubCol = N/SubNum; LbpHist=zeros(8,SubNum*SubNum*59); for n=1:3 for m=1:8 I11=imread(strcat('.bmp')); [M,N]=size(I11); %分块获取LBP直方图,共分SubNum*SubNum块,每块提取1*59的特征 %所以总共特征数为1*(SubNum*SubNum*59) %初始化特征向量及分块数 h=((n-1)*8+m); SP=[-1 -1; -1 0; -1 1; 0 -1; -0 1; 1 -1; 1 0; 1 1]; mapping=getmapping(8,'u2'); for i=1:SubNum for j=1:SubNum Img = I11(((i-1)*SubRow+1):i*SubRow, ((j-1)*SubCol+1):j*SubCol); LbpImg = LBP(Img,SP,0,'i'); H11=LBP(LbpImg,1,8,mapping,'h'); Index = (i-1)*SubNum+j; %计算第几块 LbpHist(h,((Index-1)*59+1):Index*59)=H11; end end %imshow(I11); %下面这行的112和92两个数据哪里来的?干什么用?记住多用容易认的变量,比如SubNum b=I11(1:SubNum*SubNum*59); % b是行矢量 1×N,其中N=112*92,提取顺序是先列后行,即从上到下,从左到右 b=double(b); %allsamples有何作用? allsamples=[allsamples; b]; % allsamples 是一个M * N 矩阵,allsamples 中每一行数据代表一张图片,其中M=200 end end [fn,pn,fi]=uigetfile('*.bmp','选择图片'); I12=imread([pn fn]); [M1,N1]=size(I12); SubNum=3; SubRow = M1/SubNum; SubCol = N1/SubNum; LbpHist1=zeros(1,SubNum*SubNum*59); SP=[-1 -1; -1 0; -1 1; 0 -1; -0 1; 1 -1; 1 0; 1 1]; mapping=getmapping(8,'u2'); for i=1:SubNum for j=1:SubNum Img1 = I12(((i-1)*SubRow+1):i*SubRow, ((j-1)*SubCol+1):j*SubCol); LbpImg1 = LBP(Img1,SP,0,'i'); H12=LBP(LbpImg1,1,8,mapping,'h'); Index = (i-1)*SubNum+j; %计算第几块 LbpHist1(((Index-1)*59+1):Index*59)=H12; end end juli=zeros(1,24); for j=1:24 for i=1:SubNum*SubNum*59 S=LbpHist(j,i); Q=LbpHist1(i); S1=S-Q; Q1=S+Q; f=sum(S1^2/Q1); end juli(1,j:j+1)=f; end min=min(juli); [m2,n2]=find(juli==min); [xsort,index]=sort(juli); n3=index(1); class1=8; class2=16; class3=24; if n3<=class1 disp('这个叶片属于class1'); else if n3>class1&&n3<=class2 disp('这个叶片属于class2'); else if n3>class2&&n3<=class3 disp('这个叶片属于class3'); else disp('没有类别'); end end end % GETMAPPING returns a structure containing a mapping table for LBP codes. % MAPPING = GETMAPPING(SAMPLES,MAPPINGTYPE) returns a % structure containing a mapping table for % LBP codes in a neighbourhood of SAMPLES sampling % points. Possible values for MAPPINGTYPE are % 'u2' for uniform LBP % 'ri' for rotation-invariant LBP % 'riu2' for uniform rotation-invariant LBP. % % Example: % I=imread('rice.tif'); % MAPPING=getmapping(16,'riu2'); % LBPHIST=lbp(I,2,16,MAPPING,'hist'); % Now LBPHIST contains a rotation-invariant uniform LBP % histogram in a (16,2) neighbourhood. % function mapping = getmapping(samples,mappingtype) % Version 0.1.1 % Authors: Marko Heikkil?and Timo Ahonen % Changelog % 0.1.1 Changed output to be a structure % Fixed a bug causing out of memory errors when generating rotation % invariant mappings with high number of sampling points. % Lauge Sorensen is acknowledged for spotting this problem. table = 0:2^samples-1; newMax = 0; %number of patterns in the resulting LBP code index = 0; if strcmp(mappingtype,'u2') %Uniform 2 newMax = samples*(samples-1) + 3; for i = 0:2^samples-1 j = bitset(bitshift(i,1,samples),1,bitget(i,samples)); %rotate left numt = sum(bitget(bitxor(i,j),1:samples)); %number of 1->0 and %0->1 transitions %in binary string %x is equal to the %number of 1-bits in %XOR(x,Rotate left(x)) if numt <= 2 table(i+1) = index; index = index + 1; else table(i+1) = newMax - 1; end end end if strcmp(mappingtype,'ri') %Rotation invariant tmpMap = zeros(2^samples,1) - 1; for i = 0:2^samples-1 rm = i; r = i; for j = 1:samples-1 r = bitset(bitshift(r,1,samples),1,bitget(r,samples)); %rotate %left if r < rm rm = r; end end if tmpMap(rm+1) < 0 tmpMap(rm+1) = newMax; newMax = newMax + 1; end table(i+1) = tmpMap(rm+1); end end if strcmp(mappingtype,'riu2') %Uniform & Rotation invariant newMax = samples + 2; for i = 0:2^samples - 1 j = bitset(bitshift(i,1,samples),1,bitget(i,samples)); %rotate left numt = sum(bitget(bitxor(i,j),1:samples)); if numt <= 2 table(i+1) = sum(bitget(i,1:samples)); else table(i+1) = samples+1; end end end mapping.table=table; mapping.samples=samples; mapping.num=newMax;