MARK识别脏污
常规的MARK点识别没什么好说的,对于脏污的MARK识别,大概处理了下,具体效果待验证。
例如这种。
灰度图是这样
比较麻烦的是,前景和背景区分不明显,自动二值化的话,无法很好地区分,手动设定二值化阈值,又不能保证每张图阈值都一样,有点难弄。
binary_threshold (ImageReduced, Region1, 'max_separability', 'light', UsedThreshold)
效果如下:
区域是这样的话,无论如何做图像处理,都无法找到合适的圆形区域。同时,卡尺找边缘,canny找边缘等方式,由于灰度变化不明显,效果都不好。
核心在于如何做好二值化。自动二值化。
其实从灰度直方图来看,差距还是很明显,暗区域基本集中在一块,只需要把第一个峰值区域刨开,剩下的就是MARK点区域了。
不知道halcon的自动二值化用的什么直方图切割方式,试了下其他threshold方法,也都效果不好。自己想了一个,效果还行
gray_histo (ROI_0, ImageReduced, AbsoluteHisto, RelativeHisto)
histo_to_thresh (AbsoluteHisto, 2, MinThresh, MaxThresh)
threshold(ImageReduced, Region, MaxThresh[0], 255)
二值化效果如下:
有这个效果,后面的就好处理了。
opening_circle(Region, RegionOpening, 3.5)
select_shape_std (RegionOpening, SelectedRegions, 'max_area', 70)
closing_circle (SelectedRegions, RegionClosing, 30)
boundary (RegionClosing, RegionBorder, 'inner')
skeleton (RegionBorder, Skeleton)
gen_contours_skeleton_xld (Skeleton, Contours, 1, 'filter')
intersection (RegionBorder, ROI_0, RegionIntersection)
fit_circle_contour_xld (Contours, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
gen_circle (Circle, Row, Column, Radius)
gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1)
shape_trans (RegionIntersection, RegionTrans, 'inner_circle')
*找到边缘所在区域,根据图像大小区别,也需要修改
dilation_circle (Circle, RegionDilation, 5)
erosion_circle (Circle, RegionErosion, 1.5)
difference (RegionDilation, RegionErosion, RegionDifference)
reduce_domain(Image1,RegionDifference,Imagetest)
*这个用来找边缘,根据图像变化,也是需要修改的
edges_sub_pix (Imagetest, Edges, 'canny', 1, 10, 20)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 2, 2, 2)
union_cocircular_contours_xld (ContoursSplit, UnionContours, 0.5, 0.1, 0.2, 30, 10, 10, 'true', 1)
*排除掉小轮廓
* 如图像变大,这块的参数是要修改的。
select_contours_xld (UnionContours, SelectedContours, 'contour_length', 4, 2000, -0.5, 0.5)
*这个是将轮廓连起来。有可能轮廓无法连接,或连接的轮廓太少,或连接出错,导致拟合出错
union_adjacent_contours_xld (SelectedContours, UnionContours1, 100, 1, 'attr_keep')
select_obj(UnionContours1, ObjectSelected, 1)
fit_circle_contour_xld (ObjectSelected, 'algebraic', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1)
dev_display(Image)
dev_display(ContCircle)
stop()
最终结果,目前来看效果还可以。原来常规方法处理不出来的都正确识别了。从轮廓表现上来看,精度也不错。不过这个适配性还是不高,详见注释。