1 案例背景
目前,柑橘的分级主要靠人工完成,该方法存在主观误差大、效率低和柑橘易造成二次损伤等问题。随着机器视觉技术的快速发展, 图像处理在水果质量检测方面也取得了深入进展。
试验拟通过采集视野内柑橘图, 综合特征对苹果进行分级, 通过SVM决策树算法将柑橘分为特级果、一级果、二级果和三级果,以增加柑橘在线分级的准确度并提高分级效率。
2 背景分割
2.1 图像预处理
系统通过摄像头采集柑橘图像,由于柑橘表面光滑,光线容易发生反射,所拍摄到的果面可能会因为角度和光照影响出现光照不均现象,故采用同态滤波方式对图像进行增强,采用中值滤波方式消除噪声。同时,为了提高苹果在线分级的效率,仅对感兴趣区域进行背景分割与特征提取;最后综合两幅不同位姿的柑橘图像信息对苹果进行分级。
2.2 背景分割
为了从柑橘图像中提取出柑橘轮廓,一般采用边缘检测、阈值分割、区域提取3种方法。由于光照、拍摄角度等问题,单一的阈值又不利于多峰图像的分割,在复杂背景下容易出现欠分割、过分割等问题,所以采用全局阈值分割效果并不理想。自适应O stu阈值分割算法可以通过自动计算最佳阈值对图像中的苹果进行提取。泛洪填充算法是从一个点开始,将其附近像素点依次填充成新的颜色,直到封闭区域内的所有像素点均被填充成新颜色为止,采用泛洪填充算法将图像中与背景颜色相近的部分填充成黑色, 可以突出背景与前景的差距。故采用泛洪填充+自适应Ostu的算法进行背景分割, 使Ostu自适应分割效果更加显著, 具体步骤如下。
(1)将输入的原图[图2(a)]进行图像预处理。
(2) 对预处理后的图像进行泛洪填充, 计算得到图像高度h和宽度w, 种子点(w-1, h-1) , 填充的颜色RGB新值为(0,0,0),相对于种子点向下的像素值为(10,10,10),向上的像素值为(9,9,9),采用8领域填充法进行填充,结果如图2(d)所示。
(3)假设图2(d)前景与背景分割阈值为t,前景点占图像的比例为Wo,均值为Uo,背景点占图像的比例为W1,均值为U1。那么,整个图像的均值为:
目标函数为:
其中g(t) 是分割阈值为t时的类间方差表达式。O stu算法可以使g(t)取得全局最大值,当g(t)达到最大时,所对应的t被称为最佳阈值,处理结果如图2(f)所示。
由图2可知,未进行泛洪填充处理的图像灰度直方图存在两个尖峰,对原图进行O stu分割后的边缘较差, 存在欠分割问题; 经泛洪填充后的图像直方图尖峰明显, 进行O stu分割处理效果很好,证明了试验方法是可行的。
2.4 特征提取
2.4.1果径
根据鲜柑橘分级标准可知,柑橘果径等于柑橘的最大横截面直径。故采用最小外接圆法对柑橘上表面的二值化图像进行计算,得到柑橘果径,结果如图3所示。
首先按式(3)计算出最小外接圆的质心(Cx,Cy)
式中:
Cx———质心的横坐标;
Cy———质心的纵坐标;
M10———二值图中水平向右的像素个数;
M00———总像素个数;
M01———垂直向下的像素个数。
将图像的质心作为柑橘轮廓的圆心,遍历轮廓上所有像素点,计算出目标像素点离质心的最大距离d,即最小外接圆的半径。
式中:
xi———目标像素点的横坐标;
yi———目标像素点的纵坐标;
d———两点之间的距离。
式中:
R———果径,mm;
2.4.2 着色度
目前,常用的彩色模型包括RGB模型和HSV模型。其中HSV模型更符合人眼对颜色的认知,是面向彩色处理最常用的模型,其中H为色度、S为饱和度、V为明度[8]。故选择在HSV颜色空间上对苹果的着色度、疤痕和果锈特征进行提取。
根据柑橘分级标准可知,柑橘着色度为统计集中着色面,条红或者片红的程度。通过统计两帧图像中红色所占的比例,得出柑橘的着色度。
首先将RGB图转换成HSV图,然后选取红色的提取范围H(156~180)、S(43~256)、V(46~255)。经阈值处理后统计图像中白色像素点个数,按式(8)计算苹果的着色度。
式中:
C———着色度;
C1———第一帧苹果的着色度;
C2———第二帧苹果的着色度;
r1———第一帧图像阈值处理后白色像素点个数;
r2———第二帧图像阈值处理后白色像素点个数;
s1———第一帧整个苹果像素点个数;
s2———第二帧整个苹果像素点个数。
2.4.3 柑橘缺陷
柑橘在生长、采摘和运输过程中受天气、病害、虫害和碰伤等伤害产生疤痕。柑橘果锈是一种比较常见的苹果病害,特别是在中小果园种植的柑橘中最为常见,故将疤痕和果锈特征参数作为柑橘缺陷的判定依据。由于果梗处的颜色较深,比较容易被判定为疤痕,为了消除此影响,将除果梗处的苹果区域视为感兴趣区域。
为了提取柑橘疤痕和果锈特征,首先将采集到的柑橘图像由RGB空间转换到HSV空间,并且分离出图像的H(色相)、S(饱和度)和V(亮度)通道图像。
由图6、7可知,柑橘的疤痕和果锈的亮度较暗,故根据苹果HSV图像的亮度值对柑橘的疤痕和果锈进行特征提取。通过分析疤痕和果锈图像特点,将感兴趣区域中像素点在V∈(120~140)的区域视为疤痕区域,V∈(150~180)的区域视为果锈区域。按式(9)计算苹果疤痕和果锈。
式中:
S———疤痕面积,cm2;
G———果锈面积,cm2;
n1———V∈(120~140)像素点个数;
n2———V∈(150~180)像素点个数。
1.5 柑橘分级
由于SVM算法在小样本训练集上的分类效果相比于其他分类算法有较好的表现,可以提高模型的泛化能力,能够处理高维空间的数据,故选择SVM算法对苹果进行分类。但SVM算法最初是针对二分类问题提出的,并不能直接应用于多分类问题,由于试验将苹果分为多个等级,因此选择多分类SVM分类器对苹果进行分级。
SVM分类器的惩罚参数C与核参数σ对最后的分类结果影响非常大,所以需对其进行优化选取。而粒子群算法有着很好的全局寻优能力,可以有效解决非线性问题,收敛速度快,但容易陷入局部最优,故采用基于改进粒子群算法的SVM决策树的分类方法进行苹果分级工作,可以克服决策树本身对门限敏感和错误传递的缺陷。
对柑橘样本进行果径、着色度、疤痕和果锈特征的提取,然后将特征参数送入SVM决策树分级模型,通过分级模型将柑橘分为特级果、一级果、二级果和三级果。
function varargout = orangetest(varargin)
% ORANGETEST MATLAB code for orangetest.fig
% ORANGETEST, by itself, creates a new ORANGETEST or raises the existing
% singleton*.
%
% H = ORANGETEST returns the handle to a new ORANGETEST or the handle to
% the existing singleton*.
%
% ORANGETEST(‘CALLBACK’,hObject,eventData,handles,…) calls the local
% function named CALLBACK in ORANGETEST.M with the given input arguments.
%
% ORANGETEST(‘Property’,‘Value’,…) creates a new ORANGETEST or raises the
% existing singleton*. Starting from the left, property value pairs are
% applied to the GUI before orangetest_OpeningFcn gets called. An
% unrecognized property name or invalid value makes property application
% stop. All inputs are passed to orangetest_OpeningFcn via varargin.
%
% *See GUI Options on GUIDE’s Tools menu. Choose “GUI allows only one
% instance to run (singleton)”.
%
% See also: GUIDE, GUIDATA, GUIHANDLES
% Edit the above text to modify the response to help orangetest
% Last Modified by GUIDE v2.5 09-Apr-2021 12:28:30
% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct(‘gui_Name’, mfilename, …
‘gui_Singleton’, gui_Singleton, …
‘gui_OpeningFcn’, @orangetest_OpeningFcn, …
‘gui_OutputFcn’, @orangetest_OutputFcn, …
‘gui_LayoutFcn’, [] , …
‘gui_Callback’, []);
if nargin && ischar(varargin{1})
gui_State.gui_Callback = str2func(varargin{1});
end
if nargout
[varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:});
else
gui_mainfcn(gui_State, varargin{:});
end
% End initialization code - DO NOT EDIT
% — Executes just before orangetest is made visible.
function orangetest_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 orangetest (see VARARGIN)
% Choose default command line output for orangetest
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);
% UIWAIT makes orangetest wait for user response (see UIRESUME)
% uiwait(handles.figure1);
% — Outputs from this function are returned to the command line.
function varargout = orangetest_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 pushbutton1.
function pushbutton1_Callback(hObject, eventdata, handles)
% hObject handle to pushbutton1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
[filename,pathname]=uigetfile({‘.’;‘.bmp’;'.jpg’;‘.tif’;'.jpg’},‘选择图像’);
image=[pathname,filename];%合成路径+文件名
im=imread(image);%读取图像
im=im2double(im);
axes(handles.axes1);
imshow(im);%在坐标axes1显示原图像
title(‘原始图像’);
handles.X1=im;
guidata(hObject,handles);
% — Executes on selection change in popupmenu1.
function popupmenu1_Callback(hObject, eventdata, handles)
% hObject handle to popupmenu1 (see GCBO)
% eventdata reserved - to be defined in a future version of MATLAB
% handles structure with handles and user data (see GUIDATA)
% Hints: contents = cellstr(get(hObject,‘String’)) returns popupmenu1 contents as cell array
% contents{get(hObject,‘Value’)} returns selected item from popupmenu1
Val=get(hObject,‘Value’)
strl=get(hObject,‘string’)
switch strl{Val};
case ' 面积'
x1=handles.X1;
w=rgb2gray(x1);
L=medfilt2(w);
level=graythresh(L);
bw=im2bw(L,level);
bw=imfill(~bw,'holes');
axes(handles.axes2);
imshow(bw);
title('面积图像');
strNC=[num2str(bwarea(bw))];
set(handles.text9,'string',strNC);
strNC1=('一级果');
strNC2=('二级果');
strNC3=('三级果');
if bwarea(bw)>30000
set(handles.text14,'string',strNC1);
else if bwarea(bw)>1000&&bwarea(bw)<30000
set(handles.text14,'string',strNC2);
else
set(handles.text14 ,'string',strNC3);
end
end
% strNC1=('无');
% set(handles.text14,'string',strNC1);
case' 颜色'
x1=handles.X1;
hv=rgb2hsv(x1);
H=hv(:,:,1);
S=hv(:,:,2);
V=hv(:,:,3);
axes(handles.axes3);
imshow(H)
title('H分量图像');
level=graythresh(x1);
apple=im2bw(x1,level);
count=length(x1);
for i=1:count
red_ratio=length(find((H>1/24 & H<3/24) | H>21/24 & H<23/24))/length(find(apple==1));%%%%
end
r=red_ratio;
strNC=[num2str(red_ratio*100),'%'];
set(handles.text10,'string',strNC);
strNC1=('三级果');
strNC2=('二级果');
strNC3=('一级果');
if r>1
set(handles.text15,'string',strNC1);
else if r>0.8&&r<1
set(handles.text15,'string',strNC2);
else
set(handles.text15 ,'string',strNC3);
end
end
case' 圆形度'
x1=handles.X1;
I2=rgb2gray(x1);
J=im2bw(I2,0.75);
I=~J;
1 matlab版本
2014a
2 参考文献
[1]杜俊波,李文正.基于阈值分类器的水果识别系统设计[J].物联网技术. 2020,10(12)
3 备注
简介此部分摘自互联网,仅供参考,若侵权,联系删除