Halcon学习---提取圆孔区域并测量圆孔直径

measure_ball_bond.hdev

 

dev_update_off ()
dev_close_window ()
FileName := 'bonds/ball_bond_ccd_'
read_image (Image, FileName + 1$'02')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_line_width (2)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_set_draw ('margin')
get_system ('store_empty_region', StoreEmptyRegion)
set_system ('store_empty_region', 'false')
* 
NumImages := 6
for Index := 1 to NumImages by 1
    read_image (Image, FileName + Index$'02')
    dev_display (Image)
    * 
    * Extract pads on chip
    *计时器开始
    count_seconds (S1)
    *利用阈值把白色底座提取出来
    threshold (Image, Region, 135, 255)
    *连通各区域
    connection (Region, ConnectedRegions)
    *利用长宽和面积特征去除无用区域
    select_shape (ConnectedRegions, SelectedRegions, ['width','height','area'], 'and', [115,115,5000], [130,130,15000])
    *填补区域内的漏洞
    fill_up (SelectedRegions, RegionFillUp)
    *变换区域形状,利用‘convex’凸包性,得到把目标区域包围起来的矩形
    shape_trans (RegionFillUp, Pads, 'convex')
    * 
    * Segment ball bonds on pad
    *差分
    difference (Pads, RegionFillUp, RegionDifference)
    *开操作
    opening_rectangle1 (RegionDifference, BondWire, 10, 10)
    *变换区域形状,利用内接圆
    shape_trans (BondWire, BallBonds, 'inner_circle')
    select_shape_proto (Pads, BallBonds, MissingBonds, 'overlaps_rel', 0, 0)
    count_seconds (S2)
    Time := (S2 - S1) * 1000
    * 
    * Get the contours of the pads with subpixel precision
    *在原半径上增加10,向外扩展圆
    dilation_circle (BallBonds, RegionDilation2, 10)
    *只保留区域2在区域1中的区域(前者区域1,中间区域2,后者为结果)
    intersection (RegionDilation2, BondWire, RegionIntersection)
    *向内扩散一个像素的区域
    boundary (RegionIntersection, RegionBorder, 'inner')
    *内外各以3.5的像素扩大区域
    dilation_circle (RegionBorder, RegionDilation, 3.5)
    *将区域合并返回
    union1 (RegionDilation, RegionUnion)
    *提取出区域(不是裁剪)
    reduce_domain (Image, RegionUnion, ImageReduced)
    *使用累计直方图计算两个阀值。凡是大于高阀值的一定是边缘; 凡是小于低阀值的一定不是边缘;
    *如果检测结果大于低阀值但又小于高阀值,那就要看这个像素的邻接像素中有没有超过高阀值的边缘像素:如果有的话那么它就是边缘了,否则他就不是边缘;
    *但我仍然有疑惑
    edges_sub_pix (ImageReduced, Edges, 'canny', 1, 20, 70)
    *合并轮廓,之前的轮廓由好几条线组成
    union_adjacent_contours_xld (Edges, UnionContours, 10, 1, 'attr_keep')
    *根据特征选择轮廓,上一步中还有多余的轮廓线
    select_contours_xld (UnionContours, SelectedContours, 'contour_length', 20, 20000, -0.5, 0.5)
    *根据轮廓线拟合一个圆,得到圆心坐标,半径
    fit_circle_contour_xld (SelectedContours, 'atukey', -1, 0, 0, 5, 7, CircleRow, CircleColumn, Radius, StartPhi, EndPhi, PointOrder)
    *根据圆心坐标和半径产生一个圆
    gen_circle_contour_xld (ContCircle, CircleRow, CircleColumn, Radius, 0, 6.28318, 'positive', 1)
    * 
    * Display the results obtained so far
    *计数
    count_obj (BondWire, NBonds)
    *创建一个空元组
    gen_empty_obj (MeasureArrows)
    * 
    * 
    dev_display (Image)
    dev_set_color ('cyan')
    dev_display (ContCircle)
    dev_set_color ('magenta')
    * 
    * Evaluate and display the results
    area_center (RegionDilation2, Area, Row, Column)
    area_center (MissingBonds, AreaM, RowM, ColumnM)
    select_shape_proto (Pads, BallBonds, BallTooClose, 'distance_contour', 0, 10)
    area_center (BallTooClose, AreaB, RowB, ColumnB)
    dev_set_color ('yellow')
    dev_display (Pads)
    if (|AreaM| > 0 or |AreaB| > 0)
        dev_set_color ('red')
        dev_display (MissingBonds)
        dev_display (BallTooClose)
        for IndexE := 0 to |AreaM| - 1 by 1
            NRow := RowM[IndexE]
            NCol := ColumnM[IndexE]
            disp_message (WindowHandle, 'Ball bond\nis missing', 'image', NRow - 150, NCol - 110, 'red', 'true')
        endfor
        for IndexE := 0 to |AreaB| - 1 by 1
            NRow := RowB[IndexE]
            NCol := ColumnB[IndexE]
            disp_message (WindowHandle, 'Ball bond is too\nclose to border', 'image', NRow - 150, NCol - 150, 'red', 'true')
        endfor
    endif
    for IndexM := 1 to NBonds by 1
        *选择其中一个对象
        select_obj (ContCircle, ObjectSelected, IndexM)
        *计算这个轮廓的外接矩形
        smallest_rectangle1_xld (ObjectSelected, minY, minX, maxY, maxX)
        * Draw arrow corresponding to the diameter of the fitted circle
        *计算轮廓的面积和中心坐标
        area_center_xld (ObjectSelected, Area1, Ybb, Xbb, PointOrder1)
        *根据中心坐标和外接矩形上边的中心点产生一个箭头
        gen_arrow_contour_xld (Arrow, Ybb, Xbb, minY, Xbb, 12, 12)
        *将箭头放进创建的元组对象里
        concat_obj (MeasureArrows, Arrow, MeasureArrows)
        *根据中心坐标和外接矩形下边的中心点产生一个箭头
        gen_arrow_contour_xld (Arrow, Ybb, Xbb, maxY, Xbb, 12, 12)
        *将箭头放进创建的元组对象里
        concat_obj (MeasureArrows, Arrow, MeasureArrows)
        dev_set_color ('green')
        dev_display (MeasureArrows)
        select_obj (ContCircle, ObjectSelected, IndexM)
        area_center_xld (ObjectSelected, Area2, Ybb, Xbb, PointOrder2)
        disp_message (WindowHandle, (2 * Radius[IndexM - 1])$'.2f' + ' px', 'image', Ybb - 15, Xbb + 75, 'green', 'false')
    endfor
    disp_message (WindowHandle, |Row| + ' Ball Bond(s) detected\nin ' + Time$'.2f' + ' ms', 'window', 12, 12, 'black', 'true')
    * 
    * Evaluate and display results
    if (Index != NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor
set_system ('store_empty_region', StoreEmptyRegion)

 

  • 3
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

枫呱呱

如果这篇博文对你有用,求打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值