* This program shows how to calculate the pointwise
* distance of two contours to inspect the camera frame
* of a phone housing.
*
* It uses the operator distance_contours_xld to calculate
* the distance between the inner and outer contour of the
* frame and the operator segment_contour_attrib_xld
* to extract the defects for visualization.
*
* Set the thresholds for the allowed distances in pixels
MinWidth := 30
MaxWidth := 35
SmoothnessTolerance := .2
*
* Initialize visualization
dev_update_off ()
dev_close_window ()
read_image (Image, 'plastic_parts/phone_camera_frame_01')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
Colors := ['white','green','yellow','orange','red']
Legend[0] := 'Legend:'
Legend[1] := 'Extracted contours'
Legend[2] := 'Frame too narrow'
Legend[3] := 'Frame too wide'
Legend[4] := 'Contour defect'
*
* Main loop:
* Inspect the camera frame
*
NumImages := 2
for I := 1 to NumImages by 1
read_image (Image, 'plastic_parts/phone_camera_frame_' + I$'02')
*
* Extract frame edges
*
* Select the frame region
threshold (Image, Region, 100, 255)
dilation_rectangle1 (Region, RegionDilation, 15, 15)
reduce_domain (Image, RegionDilation, ImageReduced)
* Extract edges in the reduced image domain
edges_sub_pix (ImageReduced, Edges, 'canny', 0.7, 10, 60)
union_adjacent_contours_xld (Edges, UnionContours, 7, 7, 'attr_keep')
select_shape_xld (UnionContours, SelectedContours, 'contlength', 'and', 700, 99999)
count_obj (SelectedContours, Number)
* Select the inner and the outer contour
*获取轮廓的长度
length_xld (SelectedContours, Length)
*tuple_sort_index按升序对元组的所有元素进行排序,并按元素值从小到大的顺序返回相应元素在原来的元祖中的索引,元素值最小的索引为0,
tuple_sort_index (Length, Indices)
*选择最里面的轮廓,selected_obj的Index是从1开始的,素组的索引是从0开始的,所以需要加1
*Indices[1] = 0,轮廓长度最小,Index是从1开始的,所以Indices[1]得加1
select_obj (SelectedContours, InnerContour, Indices[1]+1 )
*选择最外面的轮廓
select_obj (SelectedContours, OuterContour, Indices[3]+1 )
* 先计算两个轮廓之间的距离
* Calculate the distances between the inner and outer contour.
* The distances are stored as an attribute to the output contour.
distance_contours_xld (InnerContour, OuterContour, OuterContourWithWidth, 'point_to_segment')
* Get the contour parts that lie outside of the tolerances
*分割提取出距离小于指定最小距离的轮廓部分
segment_contour_attrib_xld (OuterContourWithWidth, OuterContourPartToNarrow, 'distance', 'or', 0, MinWidth)
length_xld (OuterContourPartToNarrow, Length1)
*分割提取出距离大于指定距离的轮廓部分
segment_contour_attrib_xld (OuterContourWithWidth, OuterContourPartToWide, 'distance', 'or', MaxWidth, 10000)
length_xld (OuterContourPartToWide, Length2)
* 检查轮廓本身的平滑度
* Check, if the contours are sufficiently smooth by
* comparing each contour with a smoothed version of itself
smooth_contours_xld (OuterContour, OuterContourSmooth, 11)
smooth_contours_xld (InnerContour, InnerContourSmooth, 11)
distance_contours_xld (OuterContour, OuterContourSmooth, OuterContourWithDistance, 'point_to_segment')
distance_contours_xld (InnerContour, InnerContourSmooth, InnerContourWithDistance, 'point_to_segment')
* Get the contour parts that lie outside of the tolerances
segment_contour_attrib_xld (OuterContourWithDistance, OuterContourDefect, 'distance', 'or', SmoothnessTolerance, 100)
segment_contour_attrib_xld (InnerContourWithDistance, InnerContourDefect, 'distance', 'or', SmoothnessTolerance, 100)
*
* Get pointwise distances for debugging
get_contour_attrib_xld (OuterContourWithWidth, 'distance', FrameWidth)
get_contour_attrib_xld (OuterContourWithDistance, 'distance', InnerDistances)
get_contour_attrib_xld (InnerContourWithDistance, 'distance', OuterDistances)
*
* Display results
dev_display (Image)
disp_message (WindowHandle, 'Inspect frame of phone camera (image ' + I + '/' + NumImages + ')', 'window', 12, 12, 'black', 'true')
count_obj (OuterContourPartToNarrow, NumTooNarrow)
count_obj (OuterContourPartToWide, NumTooWide)
count_obj (OuterContourDefect, NumInnerDefects)
count_obj (InnerContourDefect, NumOuterDefects)
if (NumTooNarrow + NumTooWide + NumInnerDefects + NumOuterDefects == 0)
OK := 1
disp_message (WindowHandle, 'Frame OK', 'window', 50, 12, 'forest green', 'true')
else
OK := 0
disp_message (WindowHandle, 'Frame not OK', 'window', 50, 12, 'red', 'true')
endif
*
dev_set_line_width (1)
dev_set_color (Colors[1])
dev_display (OuterContour)
dev_display (InnerContour)
dev_set_line_width (5)
dev_set_color (Colors[2])
dev_display (OuterContourPartToNarrow)
dev_set_color (Colors[3])
dev_display (OuterContourPartToWide)
dev_set_color (Colors[4])
dev_display (OuterContourDefect)
dev_set_color (Colors[4])
dev_display (InnerContourDefect)
disp_message (WindowHandle, Legend, 'window', 500, 12, Colors, 'false')
if (I < NumImages)
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
endif
endfor
边缘缺陷检测
于 2023-02-09 15:40:55 首次发布