本示例通过Blob分析+拟合的方法,对矩形的边缘进行缺陷检测;并且通过同样的方法对同一张图像中的多个矩形进行边缘缺陷的检测。
示例代码如下:
* 读取图像
dev_update_off ()
read_image (Image, 'punched_holes')
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)
* Since the metal part is backlit, the processing speed can be increased
* significantly by constructing a ROI for the subpixel-precise edge extraction
* that is as small as possible. This can easily be achieved by thresholding and
* morphology.
* Blob分析之后,抠图
fast_threshold (Image, Region, 128, 255, 10)
* 获得边界区域
boundary (Region, Border, 'inner')
* 膨胀
dilation_rectangle1 (Border, EdgeROI, 7, 7)
* 抠图
reduce_domain (Image, EdgeROI, ImageReduced)
* 针对抠出的区域,进行亚像素轮廓提取,使用轮廓,然后拟合矩形,得到矩形的中心点、角度、半宽、半高等值
* Perform the edge extraction.
* 亚像素边缘提取
edges_sub_pix (ImageReduced, Edges, 'canny', 1.7, 40, 120)
* Remove edge fragments that are too short.
* 亚像素边缘特征提取,去掉一些短小的
select_shape_xld (Edges, RectangleEdges, 'contlength', 'and', 500, 100000)
* Fit rectangles to the holes' edges using the outlier suppression of Tukey.
* 亚像素轮廓拟合带方向的矩形
fit_rectangle2_contour_xld (RectangleEdges, 'tukey', -1, 0, 0, 3, 2, Row, Column, Phi, Length1, Length2, PointOrder)
* Create rectangles with the fitted parameters for visualization purposes.
* 通过上一步拟合矩形得到的参数生成带方向的矩形
gen_rectangle2_contour_xld (Rectangles, Row, Column, Phi, Length1, Length2)
dev_set_color ('yellow')
dev_display (Rectangles)
* Check whether the holes are OK.
* 如下的代码,循环依次检查各个矩形区域的轮廓
* 求解轮廓上的点和最小外界矩形上的点之间的距离
* 计算轮廓区域的个数
count_obj (RectangleEdges, Number)
for I := 0 to Number - 1 by 1
* 选择一个轮廓区域
select_obj (RectangleEdges, RectangleEdge, I + 1)
* Get the contour's coordinates.
* 获得该轮廓所有点的行坐标和列坐标
get_contour_xld (RectangleEdge, Rows, Cols)
* Create a rectangle with the appropriate rectangle parameters.
* 通过之前拟合的矩形的相关参数,生成亚像素轮廓矩形
gen_rectangle2_contour_xld (Rect, Row[I], Column[I], Phi[I], Length1[I], Length2[I])
* Get the coordinates of the rectangle's corners.
* 生成亚像素轮廓,此处的轮廓点是矩形四个角处的行列坐标
* 第一对行列坐标和最后一对行列坐标是同一个点的坐标
get_contour_xld (Rect, RowC, ColC)
* Calculate the distances of all the contour points to the four corners of the
* rectangle.
* 求拟合矩形所有边缘点与矩形四个顶点的距离
* 然后获得距离矩形四个顶点最近的距离的元组
* 此过程的处理,是为了判断矩形四个角位置是否有缺陷
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]))
* The distance of the contour points to the corners of the rectangle is given
* by the minimum of the four distances. This distance is used to exclude
* contour points that are too close to the corners from the check for errors.
DistCorner := min2(min2(D1,D2),min2(D3,D4))
* Calculate the distances of the contour points of the rectangle.
* 计算所有轮廓(contour)内的点到拟合矩形边的距离,就近的距离
* 此过程是检测矩形的四条边是否有缺陷
dist_rectangle2_contour_points_xld (RectangleEdge, 0, Row[I], Column[I], Phi[I], Length1[I], Length2[I], Dist)
* Check whether the hole is OK by examining the distances of the contour
* points to the rectangle. A hole is OK if all points that lie more than seven
* pixels from the corners have a distance of less than one pixel to the fitted
* rectangle. To do so, we could use the following code:
* RectangleOK := true
* for J := 0 to |Dist| - 1 by 1
* if (DistCorner[J] > 7.0 and Dist[J] > 1.0)
* RectangleOK := false
* break
* endif
* endfor
* A much faster way to do this in HDevelop is to generate a mask that
* contains 0 for all points that should not be taken into account and 1
* otherwise. To do so, we subtract the minimum distance of 7.0 from the
* distances to the corners and take the maximum of 0.0 and the resulting
* values. This sets all the distances that are too close to the corners to 0.
* To set all other values to 1, we can simply take the sign of the values.
* 如果DistCorner中的值有大于7.0并且Dist中的值有大于1.0的点
* 则认为该矩形存在缺陷
* 当同时满足这两个条件的时候,说明存在非顶点处的边缘点到拟合矩形的距离超过了设定的范围
* 说明边缘存在了缺陷
* 下面两句代码,效果和上面被注释的for循环是一样的
* 关于7.0和1.0这两个值,需要自己观察数据后选取
* sgn :如果大于0.0 则Mask=1 如果等于0 则Mask=0 如果小于0.0,则Mask=-1
Mask := sgn(max2(DistCorner - 7.0,0.0))
* We can now multiply the distances to the rectangle with the mask and
* check whether the maximum distance is smaller than the maximum allowed
* distance of 1.0.
RectangleOK := max(Dist * Mask) <= 1.0
* Display whether the hole is OK.
* 区分显示OK的矩形的存在缺陷的矩形
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
重点说明:
1. 拟合矩形使用的算子是fit_rectangle2_contour_xld,通过该算子,能得到拟合矩形的中心点行列坐标、角度、半宽半高,这些参数是后续我们进行各种计算的重要参数。
2. 拟合矩形的算子fit_rectangle2_contour_xld只能得到构成该矩形的参数,而gen_rectangle2_contour_xld算子则能通过这些参数生成一个矩形。因此这两个经常联合使用。
3. DistCorner := min2(min2(D1,D2),min2(D3,D4))此处代码所取的最小值,是依次取各个数组相同索引处四个数值的最小值然后依次存放到DistCorner 中。
4. dist_rectangle2_contour_points_xld该算子计算的是轮廓点到轮廓点拟合的直线之间的距离
5. 最后评判的标准,7.0和1.0,是我们自己选择的标准,如果你愿意,你也可以选择其他的值。
更多最新文章,请关注公众号:
执行流程:
待检测的图像
Blob分析后提取的亚像素轮廓:
拟合矩形后:
各个矩形依次检查的结果: