blob分析+定位+特征
案例1:检测破碎的小饼干
check_hazeInut_wafers.hdev
这个例子就是利用区域的孔洞面积和矩形度两个特征来判断被测物是否合格的,这种非此即彼,而且带有比较主观性的方法,一般要求光照稳定,背景简单。
Halcon代码:
dev_get_window (WindowHandle)
dev_set_draw ('margin')
dev_set_line_width (3)
list_files ('./', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
threshold (Image, Regions, 56, 255)
opening_circle (Regions, RegionOpening, 8.5)
region_features (RegionOpening, 'area_holes', AreaHole)
region_features (RegionOpening, 'rectangularity', Rectangularity)
dev_display (Image)
if(AreaHole<300 and Rectangularity>0.92)
dev_set_color ('green')
dev_display (RegionOpening)
set_display_font (WindowHandle, 96, 'mono', 'true', 'false')
disp_message (WindowHandle, 'OK', 'image', 12, 12, 'green', 'false')
else
dev_set_color ('red')
dev_display (RegionOpening)
set_display_font (WindowHandle, 96, 'mono', 'true', 'false')
disp_message (WindowHandle, 'NG', 'image', 12, 12, 'red', 'false')
endif
set_display_font (WindowHandle, 26, 'mono', 'true', 'false')
disp_message (WindowHandle, '孔洞面积:'+AreaHole, 'image', 132, 12, 'black', 'true')
disp_message (WindowHandle, '矩形度:'+Rectangularity, 'image', 182, 12, 'black', 'true')
stop()
endfor
案例2:检测胶囊药粒
check_blister.hdev
这个案例是使用灰度值和区域面积来判断胶囊是否装错和是否是空的,但是最后一张图片倒数第三个胶囊,它的缺陷是比正常胶囊长度上短一点,使用面积筛选有点困难,所以又加上了一个区域的长度特征。
dev_set_line_width (3)
dev_get_window (WindowHandle)
dev_set_draw ('margin')
dev_set_color ('red')
dev_update_window ('off')
set_display_font (WindowHandle, 26, 'mono', 'true', 'false')
list_files ('./', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
read_image (Image,ImageFiles[0])
read_image (Image, ImageFiles[0])
access_channel (Image, Image1, 3)
threshold (Image1, Regions, 75, 255)
opening_circle (Regions, RegionOpening, 2.5)
shape_trans (RegionOpening, RegionTrans, 'convex')//凸性转换
area_center (RegionTrans, Area, RowRef, ColumnRef)
orientation_region (RegionTrans, Phi)
vector_angle_to_rigid (RowRef, ColumnRef, Phi, RowRef, ColumnRef, 0, HomMat2D)
affine_trans_region (RegionTrans, RegionAffineTrans, HomMat2D, 'nearest_neighbor')
affine_trans_image (Image1, ImageAffineTrans, HomMat2D, 'constant', 'false')
gen_empty_obj (Objects)
for I := 0 to 4 by 1
for J := 0 to 2 by 1
r:=87+72*I
c:=209+150*J
gen_rectangle2 (ROI_0, r, c, 0, 70, 34)
concat_obj (Objects, ROI_0, Objects)
endfor
endfor
union1 (Objects, RegionUnion)
for Index := 0 to |ImageFiles| - 1 by 1
dev_update_window ('off')
read_image (Image, ImageFiles[Index])
* 定位
access_channel (Image, Image1, 3)
threshold (Image1, Regions, 75, 255)
opening_circle (Regions, RegionOpening, 2.5)
closing_circle (RegionOpening, RegionClosing1, 2.5)
shape_trans (RegionClosing1, RegionTrans, 'convex')//凸性转换
area_center (RegionTrans, Area, Row, Column)
orientation_region (RegionTrans, Phi)
vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, 0, HomMat2D)
affine_trans_image (Image1, ImageAffineTrans, HomMat2D, 'constant', 'false')
* 检测
reduce_domain (ImageAffineTrans, RegionUnion, ImageReduced)
binary_threshold (ImageReduced, Region, 'max_separability', 'dark', UsedThreshold)
opening_circle (Region, RegionOpening1, 5.5)
closing_circle (RegionOpening1, RegionClosing, 5.5)
connection (RegionClosing, ConnectedRegions)
fill_up (ConnectedRegions, RegionFillUp)
shape_trans (RegionFillUp, RegionTrans1, 'convex')
select_shape (RegionTrans1, SelectedRegions, 'area', 'and', 2500, 6000)
sort_region (SelectedRegions, SortedRegions, 'character', 'true', 'row')
* 判断
count_obj (Objects, Number)
gen_empty_obj (MissObject)
gen_empty_obj (ErrorObject)
numError:=0
numMiss:=0
for Index1 := 1 to Number by 1
select_obj (Objects, ObjectSelected, Index1)
intersection (ObjectSelected, SortedRegions, RegionIntersection)
area_center (RegionIntersection, Area1, Row1, Column1)
* 最后一张图片倒数第三个胶囊要短一些,光靠区域面积很难筛选啊,所以加一个区域长度
region_features (RegionIntersection, 'width', widthValue)
if(Area1>0)
min_max_gray (RegionIntersection, ImageReduced, 0, Min, Max, Range)
if(Area1 < 3800 or Min<65 or widthValue<95)//这种依靠区域面积区分好坏的方法还是不够稳定
numError:=numError+1
concat_obj (ErrorObject, ObjectSelected, ErrorObject)
endif
else
numMiss:=numMiss+1
concat_obj (MissObject, ObjectSelected, MissObject)
endif
endfor
dev_update_window ('on')
dev_display (ImageAffineTrans)
dev_set_color ('red')
dev_display (MissObject)
dev_set_color ('blue')
dev_display (ErrorObject)
disp_message (WindowHandle, 'Miss:'+numMiss, 'image', 12, 12, 'black', 'true')
disp_message (WindowHandle, 'Error:'+numError, 'image', 52, 12, 'black', 'true')
disp_message (WindowHandle, 'Right:'+(15-numError-numMiss), 'image', 92, 12, 'black', 'true')
stop()
endfor
案例3:检查塑料网是否破损
novelty_detection_dyn_threshold.hdev
list_files ('./', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
dev_get_window (WindowHandle)
set_display_font (WindowHandle, 66, 'mono', 'true', 'false')
for Index := 0 to |ImageFiles| - 1 by 1
read_image (Image, ImageFiles[Index])
threshold (Image, Regions, 28, 105)
connection (Regions, ConnectedRegions)
select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 450, 10000)
boundary (SelectedRegions, RegionBorder, 'inner')
count_obj (RegionBorder, Number)
dev_display (Image)
dev_display (RegionBorder)
if(Number>1)
dev_set_color ('red')
disp_message (WindowHandle, 'NG', 'image', 12, 12, 'red', 'false')
else
dev_set_color ('green')
disp_message (WindowHandle, 'OK', 'image', 12, 12, 'green', 'false')
endif
dev_display(RegionBorder)
stop()
endfor
资源下载地址
https://download.csdn.net/download/weixin_38566632/18218221
对这方面技术感兴趣的小伙伴可以关注我,我会持续更新的。别忘了给我点赞哦!