图片文件
链接:https://pan.baidu.com/s/1nhv2EvknO4pmdxUp6D0kdQ
提取码:8nj1
处理流程
1、获取连通域 外边缘
2、计算边缘点 到四个角点的最短距离
3、计算边缘点 到对应最小外接矩形的距离
4、忽略四个角附近的点,其它点 距离外接矩形 >1.0判断为NG
完整代码
* 穿孔检测外接矩形与连通域点距离 检测产品
**** 1、读取图片 *********************************
dev_update_off ()
read_image (Image, './punched_holes.png')
get_image_size (Image, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_display (Image)
**** 2、获取产品外接矩形 *********************************
* 二值化
fast_threshold (Image, Region, 128, 255, 10)
* 内部环状区域
boundary (Region, Border, 'inner')
* 矩形膨胀
dilation_rectangle1 (Border, EdgeROI, 7, 7)
* 聚焦边缘区域
reduce_domain (Image, EdgeROI, ImageReduced)
* canny算法 获取边缘
edges_sub_pix (ImageReduced, Edges, 'canny', 1.7, 40, 120)
* 通过长度过滤边缘
select_shape_xld (Edges, RectangleEdges, 'contlength', 'and', 500, 100000)
* 边缘拟合外接矩形
fit_rectangle2_contour_xld (RectangleEdges, 'tukey', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
* 生成外接矩形
gen_rectangle2_contour_xld (Rectangles, Row, Column, Phi, Length1, Length2)
dev_set_color ('yellow')
dev_display (Rectangles)
**** 3、循环处理边缘 *********************************
count_obj (RectangleEdges, Number)
for I := 0 to Number - 1 by 1
*** a、获取区域边缘坐标点、外接矩形、四个角点坐标 *********
* 选择区域的边缘
select_obj (RectangleEdges, RectangleEdge, I + 1)
* 获取连通域的坐标点
get_contour_xld (RectangleEdge, Rows, Cols)
* 生成对应的外接矩形
gen_rectangle2_contour_xld (Rect, Row[I], Column[I], Phi[I], Length1[I], Length2[I])
* 获取外接矩形 四个角点坐标
get_contour_xld (Rect, RowC, ColC)
* gen_cross_contour_xld (Cross, RowC, ColC, 20, 0)
* dev_display (Cross)
*** b、计算所有边缘点与四个角点 最小距离 ********************
* 所有连通域点与四个角点距离计算
D1 := sqrt((Rows - RowC[0]) * (Rows - RowC[0]) + (Cols - ColC[0]) * (Cols - ColC[0]))
D2 := sqrt((Rows - RowC[1]) * (Rows - RowC[1]) + (Cols - ColC[1]) * (Cols - ColC[1]))
D3 := sqrt((Rows - RowC[2]) * (Rows - RowC[2]) + (Cols - ColC[2]) * (Cols - ColC[2]))
D4 := sqrt((Rows - RowC[3]) * (Rows - RowC[3]) + (Cols - ColC[3]) * (Cols - ColC[3]))
* ((连通域左上点最近,连通域与右上点最近的点)(距离左下点最近,距离右下最近点))
* 获取所有连通域点 到四个角点 最近的距离 (一维数组 使用最近的距离填入)
DistCorner := min2(min2(D1,D2),min2(D3,D4))
*** C、计算连通域点 与 外接矩形的距离
dist_rectangle2_contour_points_xld (RectangleEdge, 0, Row[I], Column[I], Phi[I], Length1[I], Length2[I], Dist)
*** d、忽略距离角点近的点,通过边缘点距离判断 OK NG ********************
* RectangleOK := true
* for J := 0 to |Dist| - 1 by 1
* 过滤距离四个角点距离7的点 并且 连通域点距离外接矩形 > 1.
* if (DistCorner[J] > 7.0 and Dist[J] > 1.0)
* 检测结果为NG
* RectangleOK := false
* break
* endif
* endfor
* 距离小于7 置0,符号判断 (-1.0, 0, 1.0)
Mask := sgn(max2(DistCorner - 7.0,0.0))
* mask 凸出外接矩形 -1, 近四角 0, 其它 1.0
* 最大偏离置 > 1.0 以此判断OK NG
RectangleOK := max(Dist * Mask) <= 1.0
*** e、显示结果 ********************
if (RectangleOK)
dev_set_color ('green')
get_string_extents (WindowHandle, 'OK', Ascent, Descent, Width, Height)
set_tposition (WindowHandle, Row[I] - Height / 2, Column[I] - Width / 2)
write_string (WindowHandle, 'OK')
else
dev_set_color ('red')
get_string_extents (WindowHandle, 'Not OK', Ascent, Descent, Width, Height)
set_tposition (WindowHandle, Row[I] - Height / 2, Column[I] - Width / 2)
write_string (WindowHandle, 'Not OK')
endif
endfor