本文介绍了一种利用Halcon库创建形状模型的方法,通过提取刹车盘图像中的圆形孔洞并建立形状模型,实现对特定几何特征的有效定位。文章详细展示了如何从XLD轮廓创建圆形模型,并进一步利用这些模型进行形状匹配。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

* This example program shows the creation of shape models
* from XLD contours.
* In this example, the possibility to create a shape model from
* XLD contours is used to incorporate knowledge about the
* object's geometry. The objective is to find the four medium-sized
* holes. It is known that these holes are circular and that they have
* the same size.
* To use this knowledge, the holes are extracted from the image.
* Then, circles are fitted into the contours that represent the holes.
* In the next step, one circular XLD contour is created using the
* mean radius of the four fitted circles. Finally, this XLD contour is
* used to create the shape model.
*
* In the second part of the example program, we use the additionally
* available knowledge that the circles are arranged in a square.
* Therefore, we create four circular contours arranged in a square
* that has the same size as the quadrilateral enclosed by the extracted
* circles. These contours are used as input for the shape model creation.
*
* Read the image of the brake disc and determine the size of the holes.
read_image (Image, 'brake_disk/brake_disk_part_01')
dev_update_off ()
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, 640, 640, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

*设置输出颜色为石灰绿
dev_set_color ('lime green')
*设置线宽为3
dev_set_line_width (3)

*使用自动阈值来分割图像
bin_threshold (Image, Region)
dev_display(Region)

*获取图像范围
get_domain (Image, Domain)
dev_display(Domain)

*Domain去除Region后的图像,存入RegionComplement
difference (Domain, Region, RegionComplement)
dev_display(RegionComplement)
*将得到的闭合的hole
connection (RegionComplement, Holes)
dev_display(Holes)

*选择面积大于5000小于10000的洞
select_shape (Holes, SmallHoles, 'area', 'and', 5000, 10000)

*获取边界线
boundary (SmallHoles, RegionBorder, 'inner_filled')
dev_display(RegionBorder)

*膨胀操作
dilation_circle (RegionBorder, RegionBorderDilation, 3.5)
dev_display(RegionBorderDilation)


union1 (RegionBorderDilation, ROI)
dev_display(ROI)

*从Image中裁剪出ROI,存入ImageReduced中
reduce_domain (Image, ROI, ImageReduced)
dev_display(ImageReduced)

*提取亚像素精度边缘
edges_sub_pix (ImageReduced, Edges, 'canny', 0.5, 20, 40)

*用圆标出轮廓
fit_circle_contour_xld (Edges, 'algebraic', -1, 0, 0, 3, 2, RowCenter, ColumnCenter, Radius, StartPhi, EndPhi, PointOrder)
dev_display (Image)
dev_display (Edges)
disp_message (WindowHandle, 'Extracted edges', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Create the circular XLD contour.
dev_clear_window ()
disp_message (WindowHandle, 'First example:\nCreate a shape model from one circular contour', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
MeanRadius := mean(Radius)
*创建一个圆轮廓   6.28318是360°对应的弧度制,halcon中角度都是用弧度值表示的
gen_circle_contour_xld (ContCircle, 300, 300, MeanRadius, 0, 6.28318, 'positive', 1)
dev_clear_window ()
dev_display (ContCircle)
disp_message (WindowHandle, 'Circular XLD contour from which the\nshape model is created that will be used\nto find individual circles:', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Create the shape model.
*创建模型形状轮廓
create_shape_model_xld (ContCircle, 'auto', 0, 0, 'auto', 'auto', 'ignore_local_polarity', 10, ModelID)

*获取轮廓参数
get_shape_model_params (ModelID, NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Metric, MinContrast)
*
* Try to find the holes in the brake disc.

find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
*
* Determine which of the found matches represent the desired holes,
* i.e., which of the circles have a brighter interiour.
IsHole := []
SeamWidth := 5
for Index := 0 to |Row|-1 by 1
    polar_trans_image (Image, ImagePolar, Row[Index]+0.5, Column[Index]+0.5, 1, MeanRadius+SeamWidth+1)
    tuple_gen_sequence (round(MeanRadius)-SeamWidth, round(MeanRadius)-1, 1, SequenceInner)
    get_grayval (ImagePolar, SequenceInner, gen_tuple_const(|SequenceInner|,0), GrayvalInner)
    tuple_gen_sequence (round(MeanRadius)+1, round(MeanRadius)+SeamWidth, 1, SequenceOuter)
    get_grayval (ImagePolar, SequenceOuter, gen_tuple_const(|SequenceOuter|,0), GrayvalOuter)
   
    *if 和endif 语句,用来设置条件语句,endif是结束条件语句
    if (mean(GrayvalInner) > mean(GrayvalOuter))
        IsHole := [IsHole,true]
    else
        IsHole := [IsHole,false]
    endif
endfor
HoleIndices := find(IsHole,true)
NoHoleIndices := find(IsHole,false)
*
* Vizualize results.
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', subset(Row,HoleIndices), subset(Column,HoleIndices), Angle, 1.0, 1.0, 0)
dev_display_shape_matching_results (ModelID, 'red', subset(Row,NoHoleIndices), subset(Column,NoHoleIndices), Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Undesired result\ndue to missing\npolarity information', 'image', Row[NoHoleIndices[0]]-2*MeanRadius, Column[NoHoleIndices[0]]+1.1*MeanRadius, 'red', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Determine the polarity information from one correct match.
vector_angle_to_rigid (0, 0, 0, Row[HoleIndices[0]], Column[HoleIndices[0]], Angle[HoleIndices[0]], HomMat2D)
set_shape_model_metric (Image, ModelID, HomMat2D, 'use_polarity')
find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Results using the polarity information', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Results on further test images.
for Index := 2 to 9 by 1
    read_image (Image, 'brake_disk/brake_disk_part_'+Index$'02d')
    count_seconds (Seconds1)
    find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
    count_seconds (Seconds2)
    dev_display (Image)
    dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
    disp_message (WindowHandle, |Row|+' Matches found in '+((Seconds2-Seconds1)*1000.0)$'.1f'+' ms', 'window', -1, -1, 'lime green', 'false')
    disp_continue_message (WindowHandle, 'black', 'true')
    stop ()
endfor
clear_shape_model (ModelID)
*
* Create four circular contours arranged in a square with the
* same area as the quadrilateral formed by the four holes.
dev_clear_window ()
disp_message (WindowHandle, 'Second example:\nCreate a shape model from four circular\ncontours that are arranged in a square', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
read_image (Image, 'brake_disk/brake_disk_part_01')
line_orientation (gen_tuple_const(|RowCenter|,mean(RowCenter)), gen_tuple_const(|ColumnCenter|,mean(ColumnCenter)), RowCenter, ColumnCenter, Phi)
Phi := atan2(gen_tuple_const(|RowCenter|,mean(RowCenter))-RowCenter,gen_tuple_const(|ColumnCenter|,mean(ColumnCenter))-ColumnCenter)
Indices := sort_index(Phi)
gen_contour_polygon_xld (Contour, subset(RowCenter,Indices), subset(ColumnCenter,Indices))
area_center_xld (Contour, Area, Row, Column, PointOrder)
orientation_xld (Contour, Phi)
SideLength := sqrt(Area)
gen_circle_contour_xld (ContCircles, [0,0,1,1]*SideLength+300, [0,1,0,1]*SideLength+300, gen_tuple_const(4,MeanRadius), 0, 6.283180236816, 'positive', 1)
dev_clear_window ()
dev_display (ContCircles)
disp_message (WindowHandle, 'Circular XLD contours from which the\nshape model is created that will be used\nto find four circles arranged in a square:', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Create the shape model.
create_shape_model_xld (ContCircles, NumLevels, 0, rad(90), 'auto', 'auto', 'ignore_local_polarity', 10, ModelID)
*
* Try to find the four holes in the brake disc.
count_seconds (Seconds1)
find_shape_model (Image, ModelID, 0, rad(90), 0.5, 1, 0.5, 'least_squares', 0, 0.5, Row, Column, Angle, Score)
count_seconds (Seconds2)
dev_clear_window ()
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, |Row|+' Match found in '+((Seconds2-Seconds1)*1000.0)$'.1f'+' ms\n(without using the polarity information)', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Determine the polarity information from one correct match.
vector_angle_to_rigid (0, 0, 0, Row, Column, Angle, HomMat2D)
set_shape_model_metric (Image, ModelID, HomMat2D, 'use_polarity')
count_seconds (Seconds1)
find_shape_model (Image, ModelID, 0, rad(90), 0.5, 1, 0.5, 'least_squares', 0, 0.5, Row, Column, Angle, Score)
count_seconds (Seconds2)
dev_clear_window ()
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, |Row|+' Match found in '+((Seconds2-Seconds1)*1000.0)$'.1f'+' ms\n(using the polarity information)', 'window', -1, -1, 'lime green', 'false')
disp_continue_message (WindowHandle, 'black', 'true')
stop ()
*
* Results on further test images.
for Index := 2 to 9 by 1
    read_image (Image, 'brake_disk/brake_disk_part_'+Index$'02d')
    count_seconds (Seconds1)
    find_shape_model (Image, ModelID, 0, rad(90), 0.5, 1, 0.5, 'least_squares', 0, 0.5, Row, Column, Angle, Score)
    count_seconds (Seconds2)
    dev_display (Image)
    dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
    disp_message (WindowHandle, |Row|+' Match found in '+((Seconds2-Seconds1)*1000.0)$'.1f'+' ms', 'window', -1, -1, 'lime green', 'false')
    disp_continue_message (WindowHandle, 'black', 'true')
    stop ()
endfor
dev_display (Image)
dev_display_shape_matching_results (ModelID, 'lime green', Row, Column, Angle, 1.0, 1.0, 0)
disp_message (WindowHandle, 'Press \'Run\' to clear model', 'window', 480, 270, 'black', 'true')
stop ()
dev_display (Image)
clear_shape_model (ModelID)
dev_update_on ()

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值