该例程比较有代表性,属于Halcon里的分类方法之一,直接调用Halcon封装好的GMM分类器(高斯混合模型)对橘子和柠檬进行分类。GMM属于概率分类方法,属于P(Y|X),通过对样本的概率密度分布进行估计,然后对模型进行加权求和,并通过投影,最后选取概率最大的类所为判决结果,这种分类方法只在不同检测类之间有明显的区别(在两类物体圆度和面积有较大区别)的情况下适用。
具体原理可以详见有位大佬的解释说明,链接如下:
[原理]https://blog.csdn.net/weixin_42555080
后面我也会针对机器学习的相关方法进行分享,求点赞评论哦。
第一篇注释下,后面再写就只注释关键部分了。
*读取图片
read_image (Image, 'color/citrus_fruits_01')
*返回输入图像对象Image的第一个通道的Pointer(指示器)。另外,这个算子也返回图像类型和图像的大小(width和height)。
get_image_pointer1 (Image, Pointer, Type, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowHandle)
*用来设置当前窗口的字体属性,参数意思为字体大小为12,字体类型为“Courier New字体”,粗体,不倾斜。
set_display_font (WindowHandle, 12, 'mono', 'true', 'false')
* 定义region的填充模式, 如果参数DrawMode设置为'fill',region显示为填充,如果设置为'margin',则只显示轮廓。
dev_set_draw ('margin')
*设置线宽
dev_set_line_width (2)
*显示图片
dev_display (Image)
*其实以下几句可以写为一句dev_update_off ()
dev_update_window ('off')
dev_update_pc ('off')
dev_update_var ('off')
* 为特征量(区域的面积,圆度,和分类名)赋值
FeaturesArea := []
FeaturesCircularity := []
ClassName := ['orange','lemon']
* 创建GMM分类器(特征数量,样本分类个数,类中心的个数,协方差矩阵的形式,预处理的形式,转换特征数,随机种子初始化GMM,GMM句柄)
create_class_gmm (2, 2, 1, 'spherical', 'normalization', 10, 42, GMMHandle)
*
* 添加训练样本
for I := 1 to 4 by 1
read_image (Image, 'color/citrus_fruits_' + I$'.2d')
dev_display (Image)
* 自定义函数,将图片进行预处理,得到区域特征。
get_regions (Image, SelectedRegions)
*将彩色图片分离为三个单通道图片
(decompose3 (Image, ImageRed, ImageGreen, ImageBlue)
*用于区域对象的颜色设为白
dev_set_color ('white')
*对单通道图片进行阈值处理,得到灰度值在50-255区间的图片
threshold (ImageRed, Region, 50, 255)
*将区域进行填充
fill_up (Region, RegionFillUp)
*用来计算输入区域中的所有连通域
connection (RegionFillUp, ConnectedRegions)
*根据形状特征(这里是面积)对区域进行筛选,对于大于50小于999999的形状保留。
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 50, 999999)
return ())
dev_display (SelectedRegions)
*计算区域数量
count_obj (SelectedRegions, NumberObjects)
*对三个目标进行遍历,获取特征
for J := 1 to NumberObjects by 1
*从一个对象元组中选择一个区域,区域的排序索引应该是根据上面计算连通域的时候完成的。
select_obj (SelectedRegions, ObjectSelected, J)
*自定义函数,分别对圆度和面积进行计算,并返回区域中心点的坐标值。
get_features (ObjectSelected, WindowHandle, Circularity, Area, RowRegionCenter, ColumnRegionCenter)
(circularity (ObjectSelected, Circularity)
area_center (ObjectSelected, Area, Row, Column)
dev_set_color ('white')
return ())
* 对变量赋值
FeaturesArea := [FeaturesArea,Area]
FeaturesCircularity := [FeaturesCircularity,Circularity]
*将元组的数值转换为浮点型
FeatureVector := real([Circularity,Area])
*该方法已提前将样本分为两类,每类数量已提前设定好,橘子和柠檬各两张图片
if (I <= 2)
*将训练样本添加到训练数据中(GMM句柄,特征向量,类别ID为0,不添加高斯噪声)
add_sample_class_gmm (GMMHandle, FeatureVector, 0, 0)
*此过程在图形窗口“窗口句柄”中的位置(Row,Column)显示文本。(文本显示Add to Class加类名,行坐标,列坐标,黑色,box参数为ture,表示文本显示在橙色框中)
disp_message (WindowHandle, 'Add to Class:' + ClassName[0], 'window', RowRegionCenter, ColumnRegionCenter - 100, 'black', 'true')
else
*ID为1
add_sample_class_gmm (GMMHandle, FeatureVector, 1, 0)
disp_message (WindowHandle, 'Add to Class:' + ClassName[1], 'window', RowRegionCenter, ColumnRegionCenter - 100, 'black', 'true')
endif
endfor
*显示 'Press Run (F5) to continue' 在屏幕的右下角
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endfor
dev_clear_window ()
*
* 自定义函数,构建可视化空间,可以显示圆度和面积的二维坐标系,里面内容有点复杂,包括画坐标系,显示特征值两部分,有兴趣的同学可以仔细看看里面的代码来复现一遍,这里就不细述。两个特征变量里面分别有12个值,对应每个对象的特征值,将其放到坐标系中,橘子为深灰,柠檬为浅灰色。
visualize_2D_feature_space (Cross, Height, Width, WindowHandle, FeaturesArea[0:5], FeaturesCircularity[0:5], 'dim gray', 18)
* 'oranges', 40, 440
visualize_2D_feature_space (Cross, Height, Width, WindowHandle, FeaturesArea[6:11], FeaturesCircularity[6:11], 'light gray', 18)
* 'lemons', 70, 440
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* 训练分类器(句柄,最大迭代次数,阈值,计算方法,防止协方差矩阵异常的正则化值,类中心数量,每个类的迭代次数)这里就是halcon的便利之处,直接将大量的代码封装,我们只需要更改几个关键参数即可,但也要对GMM训练算法有所了解,后面会专门写一篇GMM算法的文章。
train_class_gmm (GMMHandle, 100, 0.001, 'training', 0.0001, Centers, Iter)
*
* 分类,下面的基本就是上面提取特征值的过程,没啥特殊的,就不每行注释了。
for I := 1 to 15 by 1
read_image (Image, 'color/citrus_fruits_' + I$'.2d')
dev_display (Image)
* 'Classify Image', 10, 10
get_regions (Image, SelectedRegions)
dev_display (SelectedRegions)
count_obj (SelectedRegions, NumberObjects)
for J := 1 to NumberObjects by 1
select_obj (SelectedRegions, ObjectSelected, J)
get_features (ObjectSelected, WindowHandle, Circularity, Area, RowRegionCenter, ColumnRegionCenter)
FeaturesArea := [FeaturesArea,Area]
FeaturesCircularity := [FeaturesCircularity,Circularity]
FeatureVector := real([Circularity,Area])
*应用上面训练的模型对测试数据的特征进行分类(句柄,特征向量,最佳类数(我的理解是指返回一种结果),分类结果(橘子是0,柠檬是1),后验概率,概率密度,归一化概率(通过这个概率进行判断))
classify_class_gmm (GMMHandle, FeatureVector, 1, ClassID, ClassProb, Density, KSigmaProb)
*显示信息
disp_message (WindowHandle, 'Class: ' + ClassName[ClassID], 'window', RowRegionCenter, ColumnRegionCenter - 100, 'black', 'true')
disp_message (WindowHandle, 'KSigmaProb: ' + KSigmaProb, 'window', RowRegionCenter + 30, ColumnRegionCenter - 100, 'black', 'true')
endfor
*如果测试图片数量不等于15,显示暂停。
if (I != 15)
disp_continue_message (WindowHandle, 'black', 'true')
endif
stop ()
endfor
* 清除分类器内存
clear_class_gmm (GMMHandle)
Halcon进行GMM分类的全过程包括以下几部分: