Halcon直线拟合的实现步骤和相关算子

1.提取采集图像的XLD
算子:threshold_sub_pix,edges_sub_pix


2.根据形状特征选择出有效的XLD
算子:select_shape_xld


3.分割XLD
算子:segment_contours_xld

例如:segment_contours_xld (SelectedXLD, ContoursSplit, 'lines_circles', 6, 4, 4)


4.计算XLD的回归直线
算子:regress_contours_xld


5.根据轮廓特征选择有限的XLD
算子:select_coutours_xld


6.合并直线XLD
算子:union_collinear_contours_xld


7.拟合出直线
算子:fit_line_contour_xld

8.生成区域直线

算子:gen_region_line

9.计算直线的方向

算子:line_orientation

举例:

*直线拟合的实现步骤
dev_set_draw ('fill')
read_image (Image, 'image/直线拟合的实现步骤.bmp')
*彩色转灰度图
count_channels (Image, Channels)
if (Channels == 3 or Channels == 4)
    rgb1_to_gray (Image, Image)
endif
get_image_size (Image, Width, Height)
threshold_sub_pix (Image, Border, 8)
segment_contours_xld (Border, ContoursSplit, 'lines', 5, 4, 2)
regress_contours_xld (ContoursSplit, RegressContours, 'median', 3)
select_contours_xld (RegressContours, SelectedContours, 'contour_length', 10, 20000, -0.5, 0.5)
union_collinear_contours_xld (SelectedContours, UnionContours, 10, 1, 2, 0.1, 'attr_keep')
fit_line_contour_xld (UnionContours, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, RowEnd, ColEnd, Nr, Nc, Dist)
gen_region_line (RegionLines, RowBegin, ColBegin, RowEnd, ColEnd)
line_orientation (RowBegin, ColBegin, RowEnd, ColEnd, Phi)
*弧度转角度
tuple_deg (Phi, Deg)
stop()

gen_contour_region_xld (RegionLines, Contours1, 'center')
smooth_contours_xld (Contours1, SmoothedContours, 5)
orientation_xld (Contours1, Phi1)
stop()

gen_contour_region_xld (RegionLines, Contours2, 'border')
stop()

gen_region_polygon (RegionLines2, RowBegin, ColBegin)
gen_contour_region_xld (RegionLines2, Contours3, 'center')
smooth_contours_xld (Contours3, SmoothedContours, 5)
stop()

官方文档的例子:

read_image (Image, 'pumpe')
edges_sub_pix (Image, Edges, 'canny', 1.5, 15, 40)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2)
count_obj (ContoursSplit, Number)
gen_empty_obj (Lines)
gen_empty_obj (Circles)
for I := 1 to Number by 1
  select_obj (ContoursSplit, Contour, I)
  get_contour_global_attrib_xld (Contour, 'cont_approx', Type)
  if (Type == -1)
      concat_obj (Lines, Contour, Lines)
  else
      concat_obj (Circles, Contour, Circles)
  endif
endfor
fit_line_contour_xld (Lines, 'tukey', -1, 0, 5, 2, RowBegin, ColBegin, \
                      RowEnd, ColEnd, Nr, Nc, Dist)
fit_circle_contour_xld (Circles, 'atukey', -1, 2, 0, 3, 2, Row, Column, \
                        Radius, StartPhi, EndPhi, PointOrder)

segment_contours_xld算子使用说明:

如果Mode ='lines',则将输入轮廓等高线划分为直线;如果Mode ='lines_circles',则将轮廓划分为直线和圆弧;如果Mode ='lines_ellipses',则将轮廓划分为直线和椭圆弧。分割的轮廓将在ContoursSplit中返回。通过全局轮廓属性'cont_approx'获得有关输出轮廓是表示直线还是圆弧或椭圆弧的信息(有关更多信息,请参见get_contour_global_attrib_xld)。如果'cont_approx'=-1,则轮廓最好以线段近似,如果'cont_approx'= 0,则为椭圆弧,如果'cont_approx'= 1,则为圆弧。

segment_contours_xld首先通过多边形近似输入轮廓。这样,轮廓在弯曲区域中被过度分割。此后,如果轮廓可以通过圆弧更好地近似,则相邻的线段分别用圆弧或椭圆弧替换。如果SmoothCont的值设置为> 0,则首先对输入轮廓进行平滑处理(请参见smooth_contours_xld)。这可能对于防止多边形逼近中的非常短的段以及实现与圆弧或椭圆弧的更鲁棒的拟合是必要的,因为平滑会抑制轮廓上的离群值。

初始多边形逼近是通过使用最大距离为MaxLineDist1的Ramer算法(请参见gen_polygons_xld)完成的。之后,将圆弧或椭圆弧拟合到相邻的线段中。如果生成的圆弧到轮廓的最大距离小于两个线段的最大距离,则将两个线段替换为圆弧。重复此过程,直到不再发生更改为止。

此后,再次用最大距离为MaxLineDist2的多边形近似对仍由线段近似的轮廓部分进行分割,并在可能的情况下将新创建的线段合并为圆弧或椭圆弧。显然,仅当MaxLineDist2 <MaxLineDist1时,这才更改输出。这种两步法比使用MaxLineDist2的单步法效率更高,因为在第一步中生成的线段较少,因此,圆或椭圆拟合的执行频率较低。因此,可以更有效地找到输入轮廓中可以由长弧近似的部分。在第二步中,找到可以由短弧近似的输入轮廓部分,并对长弧的末端部分进行细化。

所得轮廓的长度至少为3个像素,并且包含输入轮廓的至少6个连续点。长度小于3个像素或轮廓点少于6个的所有输入轮廓将被复制到输出轮廓,而无需进行修改。

---

获得轮廓属性的算子(各个属性的详情参见HDevelop帮助文档):

get_contour_attrib_xld (ObjectSelected, 'angle', Attrib)
get_contour_global_attrib_xld (ObjectSelected, 'cont_approx', Attrib1)

参考文献:

http://www.ihalcon.com/read-4490.html

发布了455 篇原创文章 · 获赞 535 · 访问量 324万+

猜你喜欢

转载自blog.csdn.net/libaineu2004/article/details/103736675