![](https://i-blog.csdnimg.cn/blog_migrate/a2b46a066360e2d14db13342cbdda47a.jpeg)
Coutours 属于XLD结构
a) 图 边缘覆盖在原始图像上
b)缩放 a)中的 矩形区域,凸显控制点
c)轮廓可以分割成线。圆。椭圆等,可以得出它们的 角度 中心 半径等
Basic Concept
![](https://i-blog.csdnimg.cn/blog_migrate/5f97274c6fdf715b82b81164ff05e219.png)
create XLD contours
最常用的方法是 用Extract Edges Or Lines方法,结果将转化为XLD
![](https://i-blog.csdnimg.cn/blog_migrate/f905a735c5924163c15bb19f322bee7f.jpeg)
Process XLD Contours
典型的情况 如 a)所示,只作用于指定的区域
许多时候 ROI选择过大 如图 b) ,这个时候要把 轮廓进行分割,只选择平行的部分 如图 c)
另外的原因,处理轮廓是因为包换了不希望得到的噪声,比如低对比度。
Perform Fitting
通过 fitting 操作,(a line, a rectangle, or a circular or elliptic arc,)来逼近(a line, a rectangle, or a circular or elliptic arc)。
Extract Features
From both raw contours and processed contour parts features can be determined. Some of these consider
the contour as a linear object. Others treat a contour as the outer boundary of an object. Obviously,
the center of gravity makes sense only for a closed object, whereas the curvature is a feature of a linear
object.
例子 提取公路
![](https://i-blog.csdnimg.cn/blog_migrate/16ebda3bbf96cc0e556ca57c1ed0a692.jpeg)
***************************************************************
* 1.lines_gauss 结果图a)所示 得到许多不想要的 小片段
* 2.select_contours_xld(Lines,LongContours,'contour_length',15,1000,0,0) 选择[15,1000]轮廓长度 这样就消除了小的轮廓
* 3.union_collinear_contours_xld (LongContours, UnionContours, 30, 2, 9, 0.7, 'attr_keep') 把共线的轮廓连接在一起。结果 如图b)
* 3.union_collinear_contours_xld (LongContours, UnionContours, 30, 2, 9, 0.7, 'attr_keep') 把共线的轮廓连接在一起。结果 如图b)
*
********************************************************
read_image(Image,'mreut4_3')
get_image_size(Image,Width,Height)
dev_close_window()
dev_open_window(0,0,Width,Height,'black',WindowID)
lines_gauss(Image,Lines,1.5,2,8,'light','true','bar-shaped','true')
select_contours_xld(Lines,LongContours,'contour_length',15,1000,0,0)
union_collinear_contours_xld (LongContours, UnionContours, 30, 2, 9, 0.7, \
'attr_keep')
read_image(Image,'mreut4_3')
get_image_size(Image,Width,Height)
dev_close_window()
dev_open_window(0,0,Width,Height,'black',WindowID)
lines_gauss(Image,Lines,1.5,2,8,'light','true','bar-shaped','true')
select_contours_xld(Lines,LongContours,'contour_length',15,1000,0,0)
union_collinear_contours_xld (LongContours, UnionContours, 30, 2, 9, 0.7, \
'attr_keep')
Extended Concept
![](https://i-blog.csdnimg.cn/blog_migrate/1e33bb2f06a92c8a5e9e1ff6affd295b.png)
1.Create XLD Contour
标准的方法是调用轮廓提取函数来创建轮廓。
边缘轮廓提取:edges_sub_pix, edges_color_sub_pix, or zero_crossing_sub_pix
线条提取:lines_gauss, lines_facet, or lines_color
亚像素blob分析:threshold_sub_pix
如果像素精度足够的话,可以用edge filter 如sobel_amp edges_image 或者 line filter 如bandpass_image
细化边缘然后转换XLD, gen_contours_skeleton_xld.
gen_contour_polygon_xld gen_contour_polygon_rounded_xld
draw_xld draw_xld_mod 交互式生成
gen_contour_region_xld 根据region生成轮廓
2.Process XLD Contours
segment_contours_xld 这个操作有多种模式:Splitting into line segments, linear and circular segments, or linear and elliptic segments.
select_obj 单独的一个可以用此得到。Perform Fitting 来做适配操作,比如趋近于圆的的轮廓。
get_contour_global_attrib_xld 得到轮廓趋近于什么属性如 线段,椭圆,圆等
split_contours_xld gen_polygons_xld 可以通过这个组合操作,得到自己想要的那部分轮廓,如只想要轮廓中的圆等等。
轮廓处理中很重要的一步,是抑制无关的轮廓,可以通过select_shape_xld(提供差不多30中形状特征)来完成。
通过制定单个或多个特征的最大值最小值,可以灵活的选择轮廓,
select_contours_xld。
select_xld_point 用鼠标交互式选择轮廓。
如果轮廓有缺口裂缝,分裂的小块将被作为独立的对象,这位后续的处理增加了难度。
union_collinear_contours_xld union_straight_contours_xld 合并线段
union_adjacent_contours_xld union_cocircular_contours_xld union_cotangential_contours_xld 合并相邻轮廓
shape_trans_xld With this operator you can, e.g., transform the contour into its surrounding circle, convex hull, or surrounding rectangle.
如果轮廓有缺口裂缝,分裂的小块将被作为独立的对象,这位后续的处理增加了难度。
union_collinear_contours_xld union_straight_contours_xld 合并线段
union_adjacent_contours_xld union_cocircular_contours_xld union_cotangential_contours_xld 合并相邻轮廓
shape_trans_xld With this operator you can, e.g., transform the contour into its surrounding circle, convex hull, or surrounding rectangle.
对于相交的轮廓
intersection_closed_contours_xld 两个轮廓的交叉部分。
difference_closed_contours_xld
两个轮廓不同的部分。
union2_closed_contours_xld 合并两个轮廓
3.Perform Fitting
With the operator fit_line_contour_xld you can determine the parameters of a line segment. The
operator provides different optimization methods, most of which are suppressing outliers. It returns the
coordinates of the start and the end point of the fitted line segment and the normal form of the line. To
visualize the results, you can use the operator gen_contour_polygon_xld.
operator provides different optimization methods, most of which are suppressing outliers. It returns the
coordinates of the start and the end point of the fitted line segment and the normal form of the line. To
visualize the results, you can use the operator gen_contour_polygon_xld.
To fit a rectangle into a contour, the operator fit_rectangle2_contour_xld can be used. It provides
various optimization methods as well. The returned parameters comprise mainly the center position, the
extent, and the orientation of the rectangle. To generate the obtained rectangle for a visualization, you
can use the operator gen_rectangle2_contour_xld.
For the fitting of circular and elliptic segments the operators fit_circle_contour_xld and
fit_ellipse_contour_xld are available. They also provide various optimization methods. For a
circular segment the center and the radius are returned together with the angle range of the visible part.
In addition, a second radius and the orientation of the main axis are returned for elliptic segments. To
visualize the results of both operators, you can use either the operator gen_ellipse_contour_xld or
the operator gen_circle_contour_xld.
4.Extract Features
HALCON offers various operators to access the feature values. Commonly used shape features are
calculated by area_center_xld, compactness_xld, convexity_xld, eccentricity_xld, di-
ameter_xld, and orientation_xld. The hulls of the contours can be determined with small-
est_circle_xld or smallest_rectangle2_xld. Features based on geometric moments are calcu-
lated, e.g., by moments_xld.
calculated by area_center_xld, compactness_xld, convexity_xld, eccentricity_xld, di-
ameter_xld, and orientation_xld. The hulls of the contours can be determined with small-
est_circle_xld or smallest_rectangle2_xld. Features based on geometric moments are calcu-
lated, e.g., by moments_xld.
5.Convert And Access XLD Contours
Finally, it might be necessary to access the raw data of the contours or to convert contours into another
data type, e.g., into a region.
You can access the coordinates of the control points with the operator get_contour_xld. It returns
the row and column coordinates of all control points of a contour in two tuples of floating-point val-
ues. In case of a contour array (tuple), you must loop over all the contours and select each one using
select_obj.
To convert contours to regions, simply call the operator gen_region_contour_xld. The operator
paint_xld paints the contour with anti-aliasing into an image.
The operators for edge and line extraction not only return the XLD contours but also so-called
attributes. Attributes are numerical values; they are associated either with each control point
(called contour attribute) or with each contour as a whole (global contour attribute). The operators
get_contour_attrib_xld and get_contour_global_attrib_xld enable you to access these val-
ues by specifying the attribute name. More information on this topic can be found in the description of
the step Determine Contour Attributes on page 74.
data type, e.g., into a region.
You can access the coordinates of the control points with the operator get_contour_xld. It returns
the row and column coordinates of all control points of a contour in two tuples of floating-point val-
ues. In case of a contour array (tuple), you must loop over all the contours and select each one using
select_obj.
To convert contours to regions, simply call the operator gen_region_contour_xld. The operator
paint_xld paints the contour with anti-aliasing into an image.
The operators for edge and line extraction not only return the XLD contours but also so-called
attributes. Attributes are numerical values; they are associated either with each control point
(called contour attribute) or with each contour as a whole (global contour attribute). The operators
get_contour_attrib_xld and get_contour_global_attrib_xld enable you to access these val-
ues by specifying the attribute name. More information on this topic can be found in the description of
the step Determine Contour Attributes on page 74.
例子:把轮廓分割成 线段和圆的形式 Example: solution_guide/basics/measure_metal_part.hdev
![](https://i-blog.csdnimg.cn/blog_migrate/ecb6231e75a59b4d2ce0975ae858bf1a.jpeg)
*****************************************************************************************
* 思路:edges_sub_pix 生成轮廓
* select_obj获取单个轮廓
* get_contour_global_attrib_xld获取该轮廓的属性,判断是线段还是圆
* fit_circle_contour_xld gen_ellipse_contour_xld 找出该轮廓最可能逼近的圆 生成圆
* fit_line_contour_xld gen_contour_polygon_xld 找出该轮廓最可能逼近的线段,生成线段。
*****************************************************************************************
read_image(Image,'metal-parts/metal-parts-01')
get_image_size(Image,Width,Height)
dev_update_window('off')
dev_close_window()
dev_open_window(0,0,Width,Height,'black',WindowID)
dev_display(Image)
* 提取轮廓
edges_sub_pix (Image, Edges, 'lanser2', 0.5, 40, 90)
segment_contours_xld (Edges, ContoursSplit, 'lines_circles', 5, 4, 2)
sort_contours_xld (ContoursSplit, SortedContours, 'upper_left', 'true', 'column')
count_obj(SortedContours,NumSegments)
NumCirCles :=0
NumLines :=0
for i :=1 to NumSegments by 1
select_obj(SortedContours,SingleSegment,i)
* Attrib = -1 线段 0 椭圆 1圆
get_contour_global_attrib_xld(SingleSegment,'cont_approx',Attrib)
if(Attrib =1)
NumCirCles :=NumCirCles +1
*对单个轮廓做 圆逼近
fit_circle_contour_xld (SingleSegment, 'atukey', -1, 0, 0, 3, 2, Row, Column, Radius, StartPhi, EndPhi, PointOrder)
*根据逼近结果生成一个圆轮廓
gen_ellipse_contour_xld (ContEllipse, Row, Column, 0, Radius, Radius, 0, 6.28318, 'positive', 1.5)
dev_set_color('white')
dev_display(ContEllipse)
set_tposition(WindowID,Row,Column)
write_string(WindowID,'Circle'+NumCirCles)
ResultText :='Cricle'+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])
distance_pp(RowBegin,ColBegin,RowEnd,ColEnd,Length)
dev_set_color('yellow')
dev_display(Line)
set_tposition(WindowID,(RowBegin + RowEnd)/2,(ColBegin +ColEnd)/2)
write_string(WindowID,'Line'+NumLines)
ResultText :='Line' + NumLines + ':Length=' + Length
endif
set_tposition(WindowID,300 +i*15,230)
write_string(WindowID,ResultText)
endfor
例子 Close garp in a contour Example: solution_guide/basics/close_contour_gaps.hdev
![](https://i-blog.csdnimg.cn/blog_migrate/0a23e0dd588d9b622892ca89914dc986.png)
dev_update_window('off')
dev_close_window()
*人为生成的一张图片,背景是是教深的灰度值,前景相对背景亮一点
*而且其中一部分做了中值处理。
gen_rectangle1 (Rectangle, 30, 20, 100, 100)
region_to_bin (Rectangle, BinImage, 130, 100, 120, 130)
rectangle1_domain(BinImage,ImageReduced,20,48,40,52)
mean_image(ImageReduced,SmoothedImage,15,15)
paint_gray(SmoothedImage,BinImage,Image)
*现在来找前景轮廓
*low = 22
*hight =30
*这两个值是梯度值,既边缘的梯度。本例中前景和背景的灰度差事30,既hight=30大于该值的
*边缘一直边缘,low=22 小于改值的边缘舍去,在此之间的边缘则看情况。
edges_sub_pix(Image,Edges,'lanser2',1.1,22,30)
*把轮廓分成 线段
segment_contours_xld (Edges, ContoursSplit, 'lines', 5, 4, 2)
*连接共线的 线段,达到封闭缺口的目的
union_collinear_contours_xld (ContoursSplit, UnionContours, 10, 1, 2, 0.1, 'attr_keep')
sort_contours_xld (UnionContours, SortedContours, 'upper_left', 'true', 'column')
dev_display(Image)
*依次显示线段 左上角 从左到右
count_obj(SortedContours,NumObjects)
Colors :=['yellow','white','white','yellow']
NumColors :=|Colors|
for i:=1 to NumColors by 1
select_obj(SortedContours,Line,i)
Color :=Colors[(i-1)%NumColors]
dev_set_color(Color)
dev_display(Line)
endfor
segment_contours_xld (Edges, ContoursSplit, 'lines', 5, 4, 2)
*连接共线的 线段,达到封闭缺口的目的
union_collinear_contours_xld (ContoursSplit, UnionContours, 10, 1, 2, 0.1, 'attr_keep')
sort_contours_xld (UnionContours, SortedContours, 'upper_left', 'true', 'column')
dev_display(Image)
*依次显示线段 左上角 从左到右
count_obj(SortedContours,NumObjects)
Colors :=['yellow','white','white','yellow']
NumColors :=|Colors|
for i:=1 to NumColors by 1
select_obj(SortedContours,Line,i)
Color :=Colors[(i-1)%NumColors]
dev_set_color(Color)
dev_display(Line)
endfor
例子 航拍图像中的公路提取
Example: hdevelop/Applications/Object-Recognition-2D/roads.hdev