Halcon Review Topics-Chapter 5-Fitting and Measurement

Chapter 5 - Fitting

Fit

All operators at the beginning of fit are operators related to fitting

In general measurement, the area is usually obtained through blob analysis and then the measurement rectangle is set, or the measurement rectangle is directly set through the assistant. Here is a special method to directly fit the target into a geometric figure , and then calculate it according to the parameters of the geometric figure. Measuring distance

Fitting process:

  1. Capture images,
  2. Pretreatment,
  3. Edge extraction,
  4. Contour joint segmentation
  5. Fitting to obtain geometric parameters
  6. Find the target distance according to the fitting result

Halcon fitting exemplified in ctrl + E method : edge extraction ( sub-pixels ) & Geometry Measurement

Through fitting, you can obtain the geometric representation of the corresponding figure, which is more convenient to find the distance, area, and other parameters, and then according to the calibration board or pixel size conversion to obtain the actual measured distance

Contour union and segmentation

Example 1: Fitted circle

Fit 3 circles⭕️, extract a section of the circle contour

The fitting result is as shown in the arc
* circles.hdev
* The edges in the image are segmented into lines and circles.
* For the edges that are part of a circle, the circle parameters
* are estimated and the resulting circle is displayed.
read_image (Image, 'double_circle')
* 
* Init window
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
* 
* Segment a region containing the edges
fast_threshold (Image, Region, 0, 120, 7)
// 对区域求边缘
boundary (Region, RegionBorder, 'inner')
//裁剪区域
clip_region_rel (RegionBorder, RegionClipped, 5, 5, 5, 5)
dilation_circle (RegionClipped, RegionDilation, 2.5)
reduce_domain (Image, RegionDilation, ImageReduced)
* 
* In the subdomain of the image containing the edges,
* extract subpixel precise edges.
edges_sub_pix (ImageReduced, Edges, 'canny', 2, 20, 60)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 3)
count_obj (ContoursSplit, Number)
dev_display (Image)
dev_set_draw ('margin')
dev_set_color ('white')
dev_update_window ('off')
for I := 1 to Number by 1
    select_obj (ContoursSplit, ObjectSelected, I)
    get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib)
    * Fit a circle to the line segment that are arcs of a circle
    if (Attrib > 0)
        fit_circle_contour_xld (ObjectSelected, 'ahuber', -1, 2, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
        gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1.0)
        dev_display (ContCircle)
    endif
endfor
dev_set_colored (12)
dev_set_line_width (3)
dev_display (ContoursSplit)

Step analysis

1. Blob analysis, get the target area

read_image (Image, 'double_circle')
* 
* Init window
dev_close_window ()
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width, Height, 'black', WindowHandle)
* 
* Segment a region containing the edges
fast_threshold (Image, Region, 0, 120, 7)
// 对区域求边缘
boundary (Region, RegionBorder, 'inner')
//裁剪区域
clip_region_rel (RegionBorder, RegionClipped, 5, 5, 5, 5)
dilation_circle (RegionClipped, RegionDilation, 2.5)
reduce_domain (Image, RegionDilation, ImageReduced)

Introduction to Operators

clip_region_rel(Region输入区域,
				RegionClipped输入裁剪结果,
				Top, 
				Bottom, 
				Left,
				Right)

2. Sub-pixel edge extraction

edges_sub_pix (ImageReduced目标区域图片,
			     Edges输出亚像素边缘轮廓, 
			     'canny'边缘检测算法, 
				 2, 平滑系数(canny算子平滑系数越大越平滑,其他相反)
				 20, 边缘差分阈值
				 60)

3. Contour segmentation

The above outline needs to be fitted into three circles,

/segment_contours_xld(Contours输入轮廓,
					 ContoursSplit输出分割的轮廓,
					 Mode分割模式, 即你想要分割成直线lines还是几个圆lines_circles或者椭圆lines_ellipses
					 SmoothCont, 用来平滑轮廓的点数
					 MaxLineDist1, 第一次迭代轮廓到多边形的距离阈值
					 MaxLineDist2第二次迭代轮廓到多边形的距离阈值)
/
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 3)

4. Determine what to fit

Don’t forget that the graphics array starts at subscript 1 .

The purpose of fitting is to obtain the parameters of the geometric object obtained by fitting, such as center, radius, length, etc.

// 计算圆弧的数量
count_obj (ContoursSplit, Number)
dev_display (Image)
dev_set_draw ('margin')
dev_set_color ('white')
dev_update_window ('off')
for I := 1 to Number by 1
//选择图形算子
    select_obj (ContoursSplit, ObjectSelected, I)
//自动判断拟合对象算子,你不知道到底拟合成什么比较好,所以这个算子就是告诉你答案的
//Attrib一般是0,-1或者1, 1是圆, 
/get_contour_global_attrib_xld (ObjectSelected输入轮廓, 
								'cont_approx'判断算法, 
								Attrib输出结果)
/
    get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib)

5. Start fitting circle, arc

 * Fit a circle to the line segment that are arcs of a circle
    if (Attrib > 0)
/拟合圆的算子
/*fit_circle_contour_xld(Contours,输入轮廓
						Algorithm,拟合算法,如最小二乘法
						MaxNumPoints,拟合时采用轮廓最多的点数,-1表示全部参与
						MaxClosureDist,是指Maximum distance between the end points of a contour to be considered as 'closed'用来区分拟合成圆还是圆弧 ,就是要拟合的最后一个点和被认为把轮廓封闭的点,这两个点距离
						ClippingEndPoints,拟合时忽略轮廓开始和结束点的数量
						Iterations,拟合迭代的最大次数
						ClippingFactor,离群值的裁剪因子,越小离群值越多
						Row, 输出圆的坐标
						Column,
						Radius,输出圆半径
						StartPhi,输出圆开始角度
						EndPhi,输出圆终止角度
						PointOrder边界点正反向)
*/
        fit_circle_contour_xld (ObjectSelected, 'ahuber', -1, 2, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
//根据拟合结果生成拟合的几何图形
        gen_circle_contour_xld (ContCircle, Row, Column, Radius, 0, rad(360), 'positive', 1.0)
        dev_display (ContCircle)
    endif
endfor
dev_set_colored (12)
dev_set_line_width (3)
dev_display (ContoursSplit)

Example 2: Fit a straight line

* measure_metal_part.hdev: inspects metal part by fitting lines and circles
* 
dev_close_window ()
dev_update_window ('off')
* ****
* step: acquire image
* ****
read_image (Image, 'metal-parts/metal-parts-01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Width, WindowID)
set_display_font (WindowID, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Image)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: create contours
* ****
edges_sub_pix (Image, Edges, 'lanser2', 0.5, 40, 90)
dev_display (Edges)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: process contours
* ****
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 6, 4, 4)
sort_contours_xld (ContoursSplit, SortedContours, 'upper_left', 'true', 'column')
dev_clear_window ()
dev_set_colored (12)
dev_display (SortedContours)
disp_continue_message (WindowID, 'black', 'true')
stop ()
* ****
* step: perform fitting
* ****
ROI := [115,225,395,535]
dev_open_window (0, round(Width / 2), (ROI[3] - ROI[1]) * 2, (ROI[2] - ROI[0]) * 2, 'black', WindowHandleZoom)
dev_set_part (round(ROI[0]), round(ROI[1]), round(ROI[2]), round(ROI[3]))
set_display_font (WindowHandleZoom, 14, 'mono', 'true', 'false')
count_obj (SortedContours, NumSegments)
dev_display (Image)
NumCircles := 0
NumLines := 0
for i := 1 to NumSegments by 1
    select_obj (SortedContours, SingleSegment, i)
    get_contour_global_attrib_xld (SingleSegment, 'cont_approx', Attrib)
    if (Attrib == 1)
        NumCircles := NumCircles + 1
        fit_circle_contour_xld (SingleSegment, 'atukey', -1, 2, 0, 5, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
        gen_ellipse_contour_xld (ContEllipse, Row, Column, 0, Radius, Radius, 0, rad(360), 'positive', 1.0)
        dev_set_color ('white')
        dev_display (ContEllipse)
        set_tposition (WindowHandleZoom, Row - Radius - 10, Column)
        write_string (WindowHandleZoom, 'C' + NumCircles)
        ResultText := 'C' + NumCircles + ': radius = ' + Radius
    else
        NumLines := NumLines + 1
        fit_line_contour_xld (SingleSegment, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
        gen_contour_polygon_xld (Line, [RowBegin,RowEnd], [ColBegin,ColEnd])
        dev_set_color ('yellow')
        dev_display (Line)
        distance_pp (RowBegin, ColBegin, RowEnd, ColEnd, Length)
        set_tposition (WindowHandleZoom, (RowBegin + RowEnd) / 2 - Nr * 10, (ColBegin + ColEnd) / 2)
        write_string (WindowHandleZoom, 'L' + NumLines)
        ResultText := 'L' + NumLines + ': length = ' + Length
    endif
    set_tposition (WindowHandleZoom, 275 + i * 10, 230)
    write_string (WindowHandleZoom, ResultText)
endfor
disp_continue_message (WindowID, 'black', 'true')
stop ()
dev_set_window (WindowHandleZoom)
dev_close_window ()
dev_clear_window ()

Contour sorting

sort_contours_xld (ContoursSplit, SortedContours, 'upper_left', 'true', 'column')

Fitted line

/*fit_line_contour_xld(Contours,输入轮廓
					Algorithm,拟合算法
					MaxNumPoints,最大参与拟合点数量
					ClippingEndPoints, 拟合时忽略轮廓开始和结束点的数量
					Iterations, 迭代次数
					ClippingFactor,离群值因子
					RowBegin, 直线起点坐标
					ColBegin, 
					RowEnd, 直线重点坐标
					ColEnd, 
					Nr, 直线的normal vector法向量的row坐标
					Nc, 直线的normal vector法向量的column坐标
					Dist直线延长线和原点0,0的垂直距离)
*/
fit_line_contour_xld (SingleSegment, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)

Contour union

There are mainly three types of union, one is collinear, one is adjacent, and the other is co-circle.

union_adjacent_contours_xld(Contours : UnionContours : MaxDistAbs, MaxDistRel, Mode : )
union_cocircular_contours_xld(Contours : UnionContours : MaxArcAngleDiff, MaxArcOverlap, MaxTangentAngle, MaxDist, MaxRadiusDiff, MaxCenterDist, MergeSmallContours, Iterations : )
union_collinear_contours_xld(Contours : UnionContours : MaxDistAbs, MaxDistRel, MaxShift, MaxAngle, Mode : )
union_collinear_contours_ext_xld(Contours : UnionContours : MaxDistAbs, MaxDistRel, MaxShift, MaxAngle, MaxOverlap, MaxRegrError, MaxCosts, WeightDist, WeightShift, WeightAngle, WeightLink, WeightRegr, Mode : )

The above are all based on the contour segmentation and then the segmentation of the small contours.

Here is how the contours are combined

* close_contour_gaps.hdev: closes gaps in extracted straight contours
* 
dev_close_window ()
dev_update_window ('off')
* ****
* step: create synthetic image
* ****
gen_rectangle1 (Rectangle, 30, 20, 100, 100)
// 转换区域成二值图像,注意这一并非只有0和1,可以是任意两个灰度值,只要只存在两种就行
/*region_to_bin(Region输入要转换的区域,
			   BinImage输出二值图像,
			   ForegroundGray前景灰度值, 
				BackgroundGray,背景灰度值
				 Width, Height输出宽高 )
*/
region_to_bin (Rectangle, BinImage, 130, 100, 120, 130)

/裁剪一个矩形出来,以前的reduce_domain()是裁剪一个固定的区域,这里的是裁剪一个设计好的矩形
/
rectangle1_domain (BinImage, ImageReduced, 20, 48, 40, 52)
// 均值滤波算子(输入图片,kernel,kernel尺寸)
mean_image (ImageReduced, SmoothedImage, 15, 15)
paint_gray (SmoothedImage, BinImage, Image)
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, Width, Height, WindowID)
dev_set_draw ('margin')
dev_set_line_width (3)
dev_display (Image)
stop ()
* ****
* step: create contours
* ****
rectangle1_domain (Image, ImageReduced, 5, 5, 125, 115)
// 输出xld亚像素轮廓,注意是轮廓没有像素值哦
edges_sub_pix (ImageReduced, Edges, 'lanser2', 1.1, 22, 30)
dev_display (Image)
dev_display (Edges)
stop ()
* ****
* step: process contours
* ****
// 分割边缘
segment_contours_xld (Edges, LineSegments, 'lines', 5, 4, 2)
//计算回归线到XLD轮廓线的参数
/regress_contours_xld(Contours带拟合轮廓,
						RegressContours输出xld轮廓,
						Mode离群值处理方法,
						Iterations迭代拟合次数)
/

regress_contours_xld (LineSegments, RegressContours, 'no', 1)
// 联合共线轮廓
/union_collinear_contours_xld(Contours输入轮廓,
						UnionContours输出合并轮廓,
						MaxDistAbs两个轮廓之间的绝对距离,这里参考帮助窗口
						MaxDistRel, 
						MaxShift, 
						MaxAngle, 
						Mode)
/
union_collinear_contours_xld (RegressContours, UnionContours, 10, 1, 2, 0.1, 'attr_keep')
//轮廓排序
sort_contours_xld (UnionContours, SortedContours, 'upper_left', 'true', 'column')
dev_display (Image)
colored_display (SortedContours, ['yellow','white','white','yellow'])
dev_update_window ('on')

Measurement fitting practice one

Use measurement assistant

* Measure 05: Code generated by Measure 05
*利用测量助手工具实现
*1采集图像
dev_close_window ()
read_image (Image, 'D://gongjian.bmp')
get_image_size (Image, Width, Height)
dev_open_window (0, 0, Width / 2, Height / 2, 'black', WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_display (Image)
disp_continue_message (WindowHandle, 'black', 'true')

AmplitudeThreshold := 40
RoiWidthLen2 := 28.5
set_system ('int_zooming', 'true')
* Measure 05: Coordinates for line Measure 05 [0]
LineRowStart_Measure_05_0 := 263.191
LineColumnStart_Measure_05_0 := 63.9394
LineRowEnd_Measure_05_0 := 283.792
LineColumnEnd_Measure_05_0 := 1036.39
* Measure 05: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_05_0+LineRowEnd_Measure_05_0)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_05_0+LineColumnEnd_Measure_05_0)
TmpCtrl_Dr := LineRowStart_Measure_05_0-LineRowEnd_Measure_05_0
TmpCtrl_Dc := LineColumnEnd_Measure_05_0-LineColumnStart_Measure_05_0
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 05: Create measure for line Measure 05 [0]
* Measure 05: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 1280, 960, 'nearest_neighbor', MsrHandle_Measure_05_0)
* Measure 05: Coordinates for line Measure 05 [1]
LineRowStart_Measure_05_1 := 164.307
LineColumnStart_Measure_05_1 := 529.66
LineRowEnd_Measure_05_1 := 559.843
LineColumnEnd_Measure_05_1 := 506.228
* Measure 05: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_05_1+LineRowEnd_Measure_05_1)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_05_1+LineColumnEnd_Measure_05_1)
TmpCtrl_Dr := LineRowStart_Measure_05_1-LineRowEnd_Measure_05_1
TmpCtrl_Dc := LineColumnEnd_Measure_05_1-LineColumnStart_Measure_05_1
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 05: Create measure for line Measure 05 [1]
* Measure 05: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 1280, 960, 'nearest_neighbor', MsrHandle_Measure_05_1)
* Measure 05: Coordinates for line Measure 05 [2]
LineRowStart_Measure_05_2 := 364.135
LineColumnStart_Measure_05_2 := 664.397
LineRowEnd_Measure_05_2 := 380.616
LineColumnEnd_Measure_05_2 := 892.864
* Measure 05: Convert coordinates to rectangle2 type
TmpCtrl_Row := 0.5*(LineRowStart_Measure_05_2+LineRowEnd_Measure_05_2)
TmpCtrl_Column := 0.5*(LineColumnStart_Measure_05_2+LineColumnEnd_Measure_05_2)
TmpCtrl_Dr := LineRowStart_Measure_05_2-LineRowEnd_Measure_05_2
TmpCtrl_Dc := LineColumnEnd_Measure_05_2-LineColumnStart_Measure_05_2
TmpCtrl_Phi := atan2(TmpCtrl_Dr, TmpCtrl_Dc)
TmpCtrl_Len1 := 0.5*sqrt(TmpCtrl_Dr*TmpCtrl_Dr + TmpCtrl_Dc*TmpCtrl_Dc)
TmpCtrl_Len2 := RoiWidthLen2
* Measure 05: Create measure for line Measure 05 [2]
* Measure 05: Attention: This assumes all images have the same size!
gen_measure_rectangle2 (TmpCtrl_Row, TmpCtrl_Column, TmpCtrl_Phi, TmpCtrl_Len1, TmpCtrl_Len2, 1280, 960, 'nearest_neighbor', MsrHandle_Measure_05_2)
* Measure 05: ***************************************************************
* Measure 05: * The code which follows is to be executed once / measurement *
* Measure 05: ***************************************************************
* Measure 05: The image is assumed to be made available in the
* Measure 05: variable last displayed in the graphics window
copy_obj (Image, Image, 1, 1)
* Measure 05: Execute measurements
measure_pairs (Image, MsrHandle_Measure_05_0, 1, 40, 'all', 'all', Row1_Measure_05_0, Column1_Measure_05_0, Amplitude1_Measure_05_0, Row2_Measure_05_0, Column2_Measure_05_0, Amplitude2_Measure_05_0, Width_Measure_05_0, Distance_Measure_05_0)
measure_pairs (Image, MsrHandle_Measure_05_1, 1, 40, 'all', 'all', Row1_Measure_05_1, Column1_Measure_05_1, Amplitude1_Measure_05_1, Row2_Measure_05_1, Column2_Measure_05_1, Amplitude2_Measure_05_1, Width_Measure_05_1, Distance_Measure_05_1)
measure_pairs (Image, MsrHandle_Measure_05_2, 1, 40, 'all', 'all', Row1_Measure_05_2, Column1_Measure_05_2, Amplitude1_Measure_05_2, Row2_Measure_05_2, Column2_Measure_05_2, Amplitude2_Measure_05_2, Width_Measure_05_2, Distance_Measure_05_2)
* Measure 05: Do something with the results
* Measure 05: Clear measure when done
disp_line (WindowHandle, Row1_Measure_05_0, Column1_Measure_05_0, Row2_Measure_05_0,Column2_Measure_05_0)
* 当前图形窗口右键菜单设置:

* 图形窗口右键菜单设置结束
disp_line (WindowHandle, Row1_Measure_05_1, Column1_Measure_05_1, Row2_Measure_05_1,Column2_Measure_05_1)
disp_line (WindowHandle, Row1_Measure_05_2, Column1_Measure_05_2, Row2_Measure_05_2,Column2_Measure_05_2)
m_width1:=Column2_Measure_05_0-Column1_Measure_05_0
m_width2:=Row2_Measure_05_1-Row1_Measure_05_1
m_width3:=Column2_Measure_05_2-Column1_Measure_05_2
disp_message (WindowHandle, '长  ' + m_width1, 'image', 0, 0, 'red', 'false')
disp_message (WindowHandle, ' 宽 ' + m_width2, 'image', 100, 0, 'red', 'false')
disp_message (WindowHandle, '直径  ' + m_width3, 'image', 200, 0, 'red', 'false')
close_measure (MsrHandle_Measure_05_0)
close_measure (MsrHandle_Measure_05_1)
close_measure (MsrHandle_Measure_05_2)

Use fitting methods

//1. 图片预处理
*识别拟合求距离
rgb1_to_gray(Image,Imagegray)
*预处理(定位)
dev_set_draw ('fill')
*threshold (Imagegray, Region, 100, 255)
threshold (Imagegray, Regions, 0, 114)
connection(Regions,Regionsconnect)
select_shape (Regionsconnect, SelectedRegions, 'area', 'and', 207798, 275688)
area_center (SelectedRegions, AreaRegion, RowCenterRegion, ColumnCenterRegion)
orientation_region (SelectedRegions, OrientationRegion)

//进行显示
dev_display (SelectedRegions)
dev_display (Image)
disp_message (WindowHandle, 'Center Row: ' + RowCenterRegion$'.5', 'window', 20, 10, 'blue', 'false')
disp_message (WindowHandle, 'Area: ' + AreaRegion + ' pixel', 'window', 20, 300, 'blue', 'false')
disp_message (WindowHandle, 'Center Column:  ' + ColumnCenterRegion$'.5', 'window', 60, 10, 'blue', 'false')
disp_message (WindowHandle, 'Orientation: ' + OrientationRegion$'.3' + ' rad', 'window', 60, 300, 'blue', 'false')

disp_cross (WindowHandle, RowCenterRegion, ColumnCenterRegion, 15, 0)
disp_arrow (WindowHandle, RowCenterRegion, ColumnCenterRegion, RowCenterRegion - 60 * sin(OrientationRegion), ColumnCenterRegion + 60 * cos(OrientationRegion), 2)


*reduce_domain (Imagegray, SelectedRegions, ImageReduced)

*select_shape_std (ConnectedRegions, RectangleRegions, 'rectangle2', 80)
*intersection_lines

//2. 提取边缘并拟合
//2.1 提取目标垂直边缘
edges_sub_pix (Imagegray, Edges, 'canny', 0.6, 20, 40)
// 选择需要的xld轮廓
// 这里往往是利用特征直方图工具,选择特征选项来插入代码,需要选择xld_width,xld_height
select_shape_xld (Edges, SelectedXLD, ['height','width'], 'and', [100,600], [500,1000])
segment_contours_xld(SelectedXLD, ContoursSplit, 'lines_circles', 5, 4, 2)
dev_set_colored (12)

select_shape_xld (ContoursSplit, SelectedXLD1, ['height','width'], 'and', [200,0], [400,30])
sort_contours_xld(SelectedXLD1, SortedContour1, 'character', 'true', 'row')
fit_line_contour_xld(SortedContour1, 'tukey', -1, 0, 5, 2, RowBegin0, ColBegin0, RowEnd0, ColEnd0, Nr, Nc, Dist)
gen_contour_polygon_xld(line1, [RowBegin0[0],RowEnd0[0]], [ColBegin0[0],ColEnd0[0]])

gen_contour_polygon_xld(line2, [RowBegin0[1],RowEnd0[1]], [ColBegin0[1],ColEnd0[1]])


//2.2提取目标水平边缘
//也是通过特征检测工具得到的
select_shape_xld (ContoursSplit, SelectedXLD1_2, ['height','width'], 'and', [0,600], [50,1000])
sort_contours_xld(SelectedXLD1_2, SortedContour2, 'character', 'true', 'row')
fit_line_contour_xld(SortedContour2, 'tukey', -1, 0, 5, 2, RowBegin1, ColBegin1, RowEnd1, ColEnd1, Nr1, Nc1, Dist1)
gen_contour_polygon_xld(line3, [RowBegin1[0],RowEnd1[0]], [ColBegin1[0],ColEnd1[0]])

gen_contour_polygon_xld(line4, [RowBegin1[1],RowEnd1[1]], [ColBegin1[1],ColEnd1[1]])

//2.3计算距离
distance_pl(RowBegin0[0], ColBegin0[0], RowBegin0[1], ColBegin0[1], RowEnd0[1], ColEnd0[1], Distance1)
disp_message (WindowHandle, '竖直边的距离 ' +Distance1, 'window',300, 10, 'blue', 'false')


distance_pl(RowBegin1[0], ColBegin1[0], RowBegin1[1], ColBegin1[1], RowEnd1[1], ColEnd1[1], Distance1)
disp_message (WindowHandle, '水平边的距离 ' +Distance1, 'window',360, 10, 'blue', 'false')


//2.4提取目标内部圆形边缘并计算半径等距离
edges_sub_pix(Imagegray, Edges3, 'canny', 1, 20, 30)
*select_shape_xld (Edges3, SelectedXLD2, 'width', 'and', 34.86, 640.37)
select_shape_xld (Edges3, SelectedXLD2, ['width','circularity'], 'and', [34.86,0.12752], [640.37,1])
* select_shape_xld (Edges3, SelectedXLD3, ['width','circularity'], 'and', [0,0.35], [120,0.5])


union_cocircular_contours_xld (SelectedXLD2, UnionContours, 1.6, 0.9, 0.9, 30, 40, 40, 'true', 1)


fit_circle_contour_xld(UnionContours, 'algebraic', -1, 0, 0, 3, 2, Row1, Column1, Radius1, StartPhi1, EndPhi1, PointOrder1)
gen_circle_contour_xld(ContCircle1, Row1, Column1, Radius1, 0, 6.28318, 'positive', 1)

distance_pl(Row1, Column1, RowBegin0[0], ColBegin0[0], RowEnd0[0], ColEnd0[0], DistanceR_left)
disp_message (WindowHandle, '圆心到左边直线的距离 ' +DistanceR_left+'半径'+Radius1, 'window',400, 10, 'blue', 'false')



distance_pp(Row1, Column1, RowEnd1[0], ColEnd1[0],DistanceR_upendpoint)
angle_ll(RowBegin0[1],ColBegin0[1],RowEnd0[1],ColEnd0[1],RowBegin1[0],ColBegin1[0],RowEnd1[0],ColEnd1[0],m_angle)
disp_message (WindowHandle, '圆心到上边直线末尾点(左边点)的距离 ' +DistanceR_upendpoint+'半径'+Radius1, 'window',460, 10, 'blue', 'false')

 

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/Mrsherlock_/article/details/109652003