需求:计算下图中7个白色矩形的平均宽度大小
方法一:提取边白色矩形与背景的交界线,通过直线拟合,利用算子计算两直线距离。
代码:
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
dev_update_off ()
count_seconds (T1)
read_image (Image1, '图片的位置')
*判断图像的通道数,来决定是否将其转换为灰度图
count_channels (Image1, Channels)
if (Channels==3)
rgb1_to_gray (Image1, Image1)
endif
*将需要测量距离的地方提取出来
threshold (Image1, Region, 128, 255)
connection (Region, ConnectedRegions)
*形状选择
select_shape (ConnectedRegions, SelectedRegions, ['rect2_len1','rect2_len2'], 'and', [100,50], [150,80])
select_shape (SelectedRegions, SelectedRegions1, 'convexity', 'and', 0.8, 1)
*正确提取后应该有七个目标块
count_obj (SelectedRegions1, Number)
if (Number!=7)
stop ()
endif
*将七个目标块合并
union1 (SelectedRegions1, RegionUnion)
*裁剪出ROI
smallest_rectangle1 (RegionUnion, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1+30, Column1-10, Row2-30, Column2+10)
reduce_domain (Image1, Rectangle, ImageReduced)
*提取边
edges_sub_pix (ImageReduced, Edges, 'canny', 1, 20, 40)
*合并轮廓
union_adjacent_contours_xld (Edges, UnionContours, 10, 1, 'attr_keep')
select_shape_xld (UnionContours, SelectedXLD, 'contlength', 'and', 150, 99999)
*正确提取后应该有14个线段
count_obj (SelectedXLD, Number1)
if (Number1!=14)
stop ()
endif
*按列对轮廓进行排序
sort_contours_xld (SelectedXLD, SortedContours, 'upper_left', 'true', 'column')
*边缘遍历
a:=[]
for i := 1 to Number1 by 2
read_image (Image, 'printer_chip/printer_chip_01')
select_obj (SortedContours, Obj1, i)
*最小二乘拟合直线
fit_line_contour_xld (Obj1, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
*生成轮廓
gen_contour_polygon_xld (Contour1, [RowBegin,RowEnd], [ColBegin,ColEnd])
select_obj (SortedContours, Obj2, i+1)
fit_line_contour_xld (Obj2, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
gen_contour_polygon_xld (Contour2, [RowBegin,RowEnd], [ColBegin,ColEnd])
*求距离
distance_cc (Contour1, Contour2, 'point_to_point', DistanceMin, DistanceMax)
*存储所求距离的不同值
a:=[a,DistanceMin]
endfor
*求距离的平均值
tuple_mean (a, Mean)
count_seconds (T2)
T:=T2-T1
dev_display (Image1)
disp_message (WindowHandle, Mean, 'window', 0, 0, 'black', 'true')
disp_message (WindowHandle, T+'秒', 'window', 50, 0, 'black', 'true')
方法二:通过灰度投影形成函数,找出“明暗”交界线的两个点的横坐标做差,便可求得矩形宽度。
代码:
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
dev_update_off ()
count_seconds (T1)
read_image (Image1, '图片的位置')
dev_close_window ()
dev_open_window (0, 0, 512, 512, 'black', WindowHandle)
dev_update_off ()
*开始时间
count_seconds (T1)
*读取图像
read_image (Image1, '图片的位置')
dev_display (Image1)
*生成空区域
gen_empty_obj (rect)
*生成7个矩形区域
for i := 1 to 7 by 1
dev_set_line_width(3)
dev_set_draw ('margin')
draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)
gen_rectangle1 (Rectangle, Row1, Column1, Row2, Column2)
concat_obj (rect, Rectangle, rect)
endfor
stop ()
*结果数组
a:=[]
for Index := 1 to 7 by 1
*选择区域
select_obj (rect, ObjectSelected, Index)
*裁剪
reduce_domain (Image1, ObjectSelected, ImageReduced)
*计算竖直方向上的灰度投影
gray_projections (ObjectSelected, ImageReduced, 'simple', HorProjection, VertProjection)
*通过一个一维数组创建一个离散一维函数
create_funct_1d_array (VertProjection, Function)
*平滑一维函数
smooth_funct_1d_gauss (Function, 2, SmoothedFunction)
*一阶导数
derivate_funct_1d (SmoothedFunction, 'first', Derivative)
*平滑函数,获得函数的极值点
smooth_funct_1d_gauss (Derivative, 2, SmoothedFunction1)
*获取所有波峰波谷对应的x值
local_min_max_funct_1d (SmoothedFunction1, 'strict_min_max', 'true', Min, Max)
x:=[Min,Max]
*获取所有x值对应的y值
get_y_value_funct_1d (SmoothedFunction1, x, 'constant', Y)
*找出最大值、最小值
result:=[]
for i := 0 to |x|-1 by 1
if (abs(Y[i])>10)
result:=[result,x[i]]
endif
endfor
*计算宽度
d:=abs(result[0]-result[1])
a:=[a,d]
stop ()
endfor
*求平均值
tuple_mean (a, Mean)
disp_message (WindowHandle, Mean, 'window', 0, 0, 'black', 'true')
注:这段代码“draw_rectangle1 (WindowHandle, Row1, Column1, Row2, Column2)”执行时需要从左至右框选七个矩形。矩形大小以刚好框柱白色矩形但又含有边缘交界为宜,如下图所示。