HALCON示例程序check_blister_mixed.hedv药品胶囊缺陷检测
示例程序源码(加注释)
- 读入图片与显示相关设置
dev_close_window ()
read_image (Image, ‘blister/blister_mixed_reference’)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, ‘mono’, ‘true’, ‘false’)
dev_update_off ()
dev_display (Image)
dev_set_draw (‘margin’) - 首先提取每个胶囊
disp_message (WindowHandle, ‘Train gmm classifier on pill types’, ‘window’, -1, -1, ‘black’, ‘true’) - 注意注意敲黑板,划重点。下边的这个函数是halcon函数的封装,里边代码有好多。内容是上一篇文章介绍过,大同小异,所以不理解的话看一下上一篇例子。下边的代码块是extract_pill_types里边的内容。
extract_pill_types (Image, Chambers, ChambersUnion, Classes, PhiRef, RowRef, ColumnRef, PillTypeCount)
threshold (Image, Region, 90, 255)
connection (Region, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 999999)
shape_trans (SelectedRegions, Blister, 'convex')
gen_empty_region (Chambers)
for I := 0 to 4 by 1Row := 107 + I * 70for J := 0 to 2 by 1Column := 177 + J * 150gen_rectangle2 (Rectangle, Row, Column, 0, 64, 30)concat_obj (Chambers, Rectangle, Chambers)endfor
endfor
difference (Blister, Chambers, Pattern)
union1 (Chambers, ChambersUnion)
orientation_region (Blister, PhiRef)
PhiRef := rad(180) + PhiRef
area_center (Blister, Area, RowRef, ColumnRef)* +++ Extract pattern for classification +++
select_shape (Chambers, PillType1, 'row', 'and', 1, 145)
union1 (PillType1, PillType1)
select_shape (Chambers, PillType2, 'row', 'and', 145, 270)
union1 (PillType2, PillType2)
select_shape (Chambers, PillType3, 'row', 'and', 270, 390)
union1 (PillType3, PillType3)* Extract color space of yellow pills
reduce_domain (Image, PillType1, ImageReduced)
decompose3 (ImageReduced, ImageR, ImageG, ImageB)
threshold (ImageB, Region, 60, 95)* Extract color space of red pills
reduce_domain (Image, PillType2, ImageReduced)
decompose3 (ImageReduced, ImageR, ImageG, ImageB)
* invert_image反转图像的灰度值
invert_image (ImageB, ImageInvert)
* hysteresis_threshold使用迟滞阈值操作
* 函数原型:hysteresis_threshold(Image : RegionHysteresis : Low, High, MaxLength : )
* Image :输入图像;RegionHysteresis :输出区域;Low:低于这个灰度不会被选中;High:高于这个灰度立刻被选中;
* MaxLength :在Low与High之间的根据MaxLength 对比度进行选择,和carry边缘类似。
hysteresis_threshold (ImageInvert, RegionHysteresis2, 190, 200, 5)* Extract color space of green pills
reduce_domain (Image, PillType3, ImageReduced)
decompose3 (ImageReduced, ImageR, ImageG, ImageB)
invert_image (ImageB, ImageInvert)
hysteresis_threshold (ImageInvert, RegionHysteresis3, 180, 200, 10)* 求两个区域的交集
intersection (Region, PillType1, PillType1)
intersection (RegionHysteresis2, PillType2, PillType2)
PillTypeCount := [3,6,6]
intersection (RegionHysteresis3, PillType3, PillType3)
concat_obj (PillType1, PillType2, Classes)
concat_obj (Classes, PillType3, Classes)
return ()
NumClasses := |PillTypeCount|
-
创建创建高斯混合模型
-
输入参数: NumDim:几个特征;NumClasses:样本分类个数;NumCenters:类中心的个数;CovarType:
-
协方差矩阵(‘Spherical’,‘diag’,‘full’);Preprocessing:预处理是否使用,及特征向量转换类型;
-
NumComponents:预处理参数,转换特征数;RandSend:迭代次数,初始化GMM;
-
输出参数:GMMHandle:高斯混合模型
create_class_gmm (3, 3, [1,5], ‘spherical’, ‘normalization’, 10, 42, GMMHandle) -
含义:增加训练样本(图片区),放入GMM 进行训练数据
-
输入参数:Image:训练的图像(多通道);ClassRegions:图像中用于训练的类区域;
-
GMMHandle:高斯混合模型;Randomize:高斯噪声标准差
add_samples_image_class_gmm (Image, Classes, GMMHandle, 0) -
含义:训练高斯混合模型
-
输入参数:GMMHandle:高斯混合模型;MixIter: 期望最大值算法中迭代最大数;
-
Threshold:期望误差阈值,超过此值,计算取消;
-
ClassPriors:类的先验概率类型;(‘training’,‘uniform’)'uniform’表示使用相同的权重,1/NumClasses;'training’表示类发生的概率是依据样本中的概率推断。
-
Regularize:调整值,为了防止计算中出现奇异协方差矩阵。增加到协方差矩阵的对角线上的一个很小的值
-
输出参数:Centers:每个类的中心个数
-
Iter:每个类的迭代次数
train_class_gmm (GMMHandle, 100, 0.001, ‘training’, 0.0001, Centers, Iter) -
检测胶囊
Count := 12
for FileIndex := 1 to Count by 1- 读入图片
read_image (Image, ‘blister/blister_mixed_’ + FileIndex$‘02’) - 阈值分割
threshold (Image, Region, 90, 255) - 分割连通域
connection (Region, ConnectedRegions) - 面积对区域筛选
select_shape (ConnectedRegions, SelectedRegions, ‘area’, ‘and’, 5000, 9999999) - 求取最大区域边缘
shape_trans (SelectedRegions, RegionTrans, ‘convex’) - 利用椭圆变换,得出区域角度
orientation_region (RegionTrans, Phi)
if (abs(Phi) > rad(90))
Phi := rad(180) + Phi
endif - 求取区域面积与中心坐标
area_center (RegionTrans, Area1, Row, Column) - 创建平移旋转变换矩阵
vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, PhiRef, HomMat2D) - 使用仿射变换矩阵进行任意仿射变换
affine_trans_image (Image, ImageAffinTrans, HomMat2D, ‘constant’, ‘false’) - 减少图像定义域
reduce_domain (ImageAffinTrans, ChambersUnion, ImageReduced) - 将图片分为rgb三通道图像
decompose3 (ImageAffinTrans, ImageR, ImageG, ImageB) - 对每个胶囊进行识别检测
- 含义:使用GMM分类一个图像
- 输入参数:Image:训练的图像(多通道);GMMHandle:GMM模型;
- RejectionThreshold:分类拒绝阈值,如果图像所有的像素概率低于此值将不会分类任何类。
- 输出参数:ClassRegions:分类的各个区域
classify_image_class_gmm (ImageReduced, ClassRegions, GMMHandle, 0.005) - 对ClassRegions进行计数
count_obj (ClassRegions, Number) - 生成空区域
gen_empty_obj (FinalClasses) - 分割连通域
connection (Chambers, ChambersRemaining)
for Index := Number to 1 by -1
dev_clear_window ()- 选择ClassRegions区域中的第Index个对象
select_obj (ClassRegions, Region, Index) - 求交集
intersection (ChambersRemaining, Region, Region) - 使用面积与宽度进行区域筛选
select_shape (Region, PillsOfOneType, [‘area’,‘width’], ‘and’, [200,40], [3000,68]) - 求取两个区域的差集
difference (ChambersUnion, PillsOfOneType, RegionDifference) - 分割连通域
connection (RegionDifference, ConnectedRegions) - 使用面积进行区域筛选
select_shape (ConnectedRegions, SelectedRegions, ‘area’, ‘and’, 0, 7868) - 求取区域的最大边缘
shape_trans (SelectedRegions, SelectedRegions, ‘convex’) - 联合区域
union1 (SelectedRegions, SelectedRegions) - 求取区域差集
difference (ChambersRemaining, SelectedRegions, ChambersRemaining) - 联合两个区域
concat_obj (SelectedRegions, FinalClasses, FinalClasses)
endfor
- 选择ClassRegions区域中的第Index个对象
- 得出结果进行处理得出结论
gen_empty_obj (MissingPills)
gen_empty_obj (WrongPills)
gen_empty_obj (WrongNumberOfPills)
difference (ChambersUnion, FinalClasses, LeftOvers)
area_center (LeftOvers, Area, Row1, Column1)
if (Area > 0)
connection (LeftOvers, LeftOvers)
count_obj (LeftOvers, Number)
for Index := 1 to Number by 1
select_obj (LeftOvers, ObjectSelected, Index)
intensity (ObjectSelected, ImageB, Mean, Deviation)
if (Deviation > 40)
concat_obj (WrongPills, ObjectSelected, WrongPills)
else
concat_obj (MissingPills, ObjectSelected, MissingPills)
endif
endfor
endif - Compute histogram
CountFinalClass := []
for Index := 1 to NumClasses by 1
select_obj (FinalClasses, ObjectSelected, Index)
connection (ObjectSelected, ObjectSelected)
count_obj (ObjectSelected, Size)
CountFinalClass := [CountFinalClass,Size]
endfor - Display classification results and output allover statistic
display_results (ImageAffinTrans, LeftOvers, FinalClasses, WrongPills, CountFinalClass, PillTypeCount, WindowHandle)
if (FileIndex < Count)
disp_continue_message (WindowHandle, ‘black’, ‘true’)
endif
stop ()
endfor
- 读入图片
-
Clear classifier handle
clear_class_gmm (GMMHandle)
处理思路
此例子使用GMM高斯分类器进行胶囊识别识别,因为一版药上有多个种类的药片。
后记
大家有什么问题可以向我提问哈,我看到了第一时间回复,希望在学习的路上多多结交良师益友。