halcon例程解析:数回收箱箱里的瓶子——check_bottle_crate

该博客介绍了如何使用Halcon算法来计数回收箱内的瓶子。通过漫射光照明,结合简单的阈值处理和形态学操作,能够有效地分割出瓶子和异物。首先,通过亮度阈值分割背景和瓶子区域,再去除大异物和噪声。接着,利用形状特征如宽、高、圆度进一步精确定位瓶子。最后,识别倒置的瓶子并进行结果显示。此方法对于倒置和横放的瓶子都有较好的识别能力。

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

This example counts bottles in bottle crates of returned empties. With diffuse front light, correctly inserted bottles can be segmented relatively easy with a simple thresholding operation, followed by some basic morphology operations. Bottles inserted upside-down are also detected and displayed in orange, while across lying bottles or big objects are marked as clutter and produce a warning.

这个例子数的是回收箱中的空瓶子。使用漫射前光,正确插入的瓶子可以相对容易地分割,只需简单的阈值操作,然后进行一些基本的形态学操作。倒插的瓶子也能被检测到,并显示为橙色,而横放的瓶子或大物体则被标记为杂物,并产生警告。

1. 效果展示

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2. 思路分析

这个问题比较简单,不需要太复杂的算法,只通过亮度等进行阈值分割、面积圆度等即可

经过漫射光的打光后,在表面的瓶口、瓶底及瓶身比较亮,当然回收箱的边缘也比较亮,这里我们只要通过亮度阈值分割;区域面积、宽、高、圆度即可区分出正常瓶子、数量、异物等

  1. 阈值分割出背景区域
  2. 阈值分割出瓶子区域
  3. 作差,优化瓶子区域
  4. 依靠宽、高提取大的异物;并做开运算去除箱体边缘等影响
  5. 有效区域减去异物
  6. 依靠宽、高去除其他影响,并填充剩余区域
  7. 依靠圆度分割出瓶子区域
  8. 依靠半径检测出较大的圆,即为倒放的瓶子
  9. 结果处理

2.1 初步检出瓶子区域

* 分割出背景区域
threshold (Image, BackgroundRegion, 50, 130)
opening_circle (BackgroundRegion, BackgroundRegion, 3.5)

* 分割出有效区域
threshold (Image, Region, 85, 255)

* 作差,优化有效区域
difference (Region, BackgroundRegion, Region)
connection (Region, ConnectedRegions)

blister_04_Pills

2.2 检测较大的异物

* 分割出较大的异物
select_shape (ConnectedRegions, Clutter, ['width','height'], 'or', [100,100], [500,400])
opening_circle (Clutter, Clutter, 8.5)

* 作差减去异物
difference (ConnectedRegions, Clutter, Region)
connection (Region, ConnectedRegions)

在这里插入图片描述
在这里插入图片描述

2.3 依靠宽、高去除其他影响,并填充剩余区域

* 有效区域的宽、高范围
select_shape (ConnectedRegions, Candidates, ['width','height'], 'and', [25,25], [100,100])

* 填充区域
fill_up (Candidates, FilledCandidates)

* 使用开运算去除小区域
opening_circle (FilledCandidates, FilledCandidates, 15.5)

在这里插入图片描述
在这里插入图片描述

2.4 依靠圆度分割出瓶子区域

* 圆度分割瓶子区域
select_shape (FilledCandidates, RoundCandidates, 'circularity', 'and', 0.87, 1)

* 依靠半径筛选大区域
select_shape (RoundCandidates, BigBottles, 'max_diameter', 'and', 75, 99999)

在这里插入图片描述

3. 全部代码

* This example counts bottles in bottle crates of returned empties.
* With diffuse front light, correctly inserted bottles can
* be segmented relatively easy with a simple thresholding operation,
* followed by some basic morphology operations.
* Bottles inserted upside-down are also detected and displayed
* in orange, while across lying bottles or big objects are
* marked as clutter and produce a warning.
* 
* init
get_system ('store_empty_region', StoreEmptyRegion)
set_system ('store_empty_region', 'false')
read_image (Image, 'bottles/bottle_crate_01')
dev_close_window ()
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')
dev_update_off ()
dev_set_draw ('margin')
* main loop
for Index := 1 to 24 by 1
    read_image (Image, 'bottles/bottle_crate_' + Index$'.02')
    * extract background
    threshold (Image, BackgroundRegion, 50, 130)
    opening_circle (BackgroundRegion, BackgroundRegion, 3.5)
    * extract bottle reflections
    threshold (Image, Region, 85, 255)
    difference (Region, BackgroundRegion, Region)
    connection (Region, ConnectedRegions)
    * large reflections are judged as clutter
    select_shape (ConnectedRegions, Clutter, ['width','height'], 'or', [100,100], [500,400])
    opening_circle (Clutter, Clutter, 8.5)
    difference (ConnectedRegions, Clutter, Region)
    connection (Region, ConnectedRegions)
    * ignore noise regions
    select_shape (ConnectedRegions, Candidates, ['width','height'], 'and', [25,25], [100,100])
    fill_up (Candidates, FilledCandidates)
    opening_circle (FilledCandidates, FilledCandidates, 15.5)
    * only 'round' reflections are from bottles
    select_shape (FilledCandidates, RoundCandidates, 'circularity', 'and', 0.87, 1)
    select_shape (RoundCandidates, BigBottles, 'max_diameter', 'and', 75, 99999)
    * display results
    dev_set_shape ('ellipse')
    count_obj (RoundCandidates, NumBottles)
    count_obj (Clutter, NumClutter)
    dev_display (Image)
    dev_set_line_width (5)
    dev_set_color ('lime green')
    dev_display (RoundCandidates)
    dev_set_color ('goldenrod')
    dev_display (BigBottles)
    dev_set_color ('red')
    dev_display (Clutter)
    dev_set_shape ('original')
    disp_message (WindowHandle, NumBottles + ' bottles found.', 'window', 12, 12, 'black', 'true')
    if (NumClutter > 0)
        disp_message (WindowHandle, 'Warning! Clutter detected!', 'window', 40, 12, 'red', 'true')
    endif
    if (Index < 24)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor
* restore original system settings
set_system ('store_empty_region', StoreEmptyRegion)
<think>好的,用户想用Halcon实现瓶子的功能,需要方法和示例代码。首先,我得回忆一下之前提供的引用内容,尤其是引用1和2,提到了瓶子和瓶盖的检测案例。引用1中,check_bottle_crate例程使用阈值和形态学操作分割正确插入的瓶子,还能检测倒插和杂物。引用2则是一个瓶盖识别的框架,需要考虑光照、形状多样性等因素。用户的需求是计,可能需要类似的方法。 首先,我得确定处理流程。通常图像处理步骤包括图像采集、预处理、分割、特征提取和计。根据引用1,正确的瓶子容易分割,可能用阈值处理。那可能需要先确保光照条件合适,比如使用漫射前光,减少反光和阴影的影响,这样阈值分割会更准确。 然后,分割后的区域可能需要形态学操作,比如闭运算,来连接邻近区域或填充空洞,确保每个瓶子被正确分割为一个区域。引用1中提到形态学操作,这可能用于去除噪声或分离粘连的物体。 接下来是特征提取,比如面积、形状等参,来区分瓶子和杂物。比如正确插入的瓶子可能有特定的面积范围,而倒插的瓶子可能形状不同,或者通过方向来判断。引用1中倒插的瓶子被标记为橙色,可能用的是颜色或形状特征。 另外,引用3提到多线程处理,但用户可能暂时不需要这部分,先关注基本图像处理步骤。代码结构方面,可能需要先读取图像,转灰度,然后阈值分割,形态学处理,最后计算区域量。 需要注意的问题包括光照不均匀、瓶子重叠或遮挡、不同姿态的瓶子(倒置、横放)等。引用2提到要考虑光照和形状多样性,可能需要动态调整阈值或使用更鲁棒的分割方法,比如基于边缘检测或模板匹配。 可能还需要考虑是否处理彩色图像,或者转换为HSV空间来利用颜色信息区分不同状态的瓶子。引用1中使用颜色标记不同状态,可能涉及到彩色分割。 最后,示例代码部分需要包括关键步骤,如读取图像、预处理、分割、形态学、区域分析等。可能需要使用Halcon的threshold、connection、select_shape等算子。同时,需要处理异常情况,比如杂物检测,可能需要设置面积或长宽比等筛选条件。 总结步骤:图像采集→预处理(滤波、增强)→分割(阈值)→形态学处理→区域分割→特征筛选→计和分类。现在需要将这些步骤转化为Halcon代码,并参考例程的结构。可能还需要测试不同的参,确保在不同情况下都能准确计。</think>根据Halcon在工业检测中的应用经验[^1][^4],瓶子的典型实现流程可分为图像采集、预处理、目标分割、形态学优化、特征筛选四个步骤。以下是具体实现方法和代码示例: ### 一、核心实现步骤 1. **图像采集方案** 使用**环形漫射前光**消除反光干扰,建议相机与瓶口平面呈45°夹角。通过`grab_image_async`实现连续采集: ```cpp open_framegrabber('USB3Vision', 0, 0, 0, 0, 0, 0, 'progressive', -1, 'default', -1, 'false', 'default', 'camera', 0, -1, AcqHandle) grab_image_async(Image, AcqHandle, -1) ``` 2. **预处理优化** 采用**同态滤波**增强瓶口边缘: ```cpp decompose3(Image, R, G, B) hom_mat3d_identity(HomMat3D) hom_mat3d_scale(HomMat3D, 0.8, 0.8, 1, 128, 128, 0, HomMat3DScaled) affine_trans_image(B, ImageAffineTrans, HomMat3DScaled, 'constant') ``` 3. **动态阈值分割** 结合**局部自适应阈值**处理光照不均: ```cpp mean_image(ImageAffineTrans, ImageMean, 31, 31) dyn_threshold(ImageAffineTrans, ImageMean, RegionDynThresh, 15, 'light') ``` 4. **形态学优化** 通过**椭圆结构元素**修正瓶口形状: ```cpp closing_circle(RegionDynThresh, RegionClosing, 3.5) connection(RegionClosing, ConnectedRegions) closing_ellipse(ConnectedRegions, RegionClosed, 5, 5) ``` 5. **特征筛选** 基于面积和圆度排除异物: ```cpp select_shape(RegionClosed, SelectedRegions, ['area','circularity'], 'and', [3500,0.75], [5500,1.0]) count_obj(SelectedRegions, NumBottles) ``` ### 二、异常检测增强 1. **倒置瓶检测** 通过**区域最小外接矩形方向**判断: ```cpp smallest_rectangle2(SelectedRegions, Row, Column, Phi, Length1, Length2) if (abs(Phi) > 0.5) dev_set_color('orange') // 标记异常 endif ``` 2. **异物检测** 基于**区域凸性缺陷**分析: ```cpp convexity(SelectedRegions, Convexity) if (Convexity < 0.92) dev_set_color('red') // 标记杂物 endif ``` ### 三、完整示例代码 ```cpp dev_update_off() read_image(Image, 'bottle_crate') * 预处理 rgb1_to_gray(Image, GrayImage) emphasize(GrayImage, ImageEmphasize, 7, 7, 1) * 动态阈值 mean_image(ImageEmphasize, ImageMean, 51, 51) dyn_threshold(ImageEmphasize, ImageMean, RegionDynThresh, 15, 'light') * 形态学优化 closing_circle(RegionDynThresh, RegionClosing, 3.5) opening_rectangle1(RegionClosing, RegionOpen, 3, 3) connection(RegionOpen, ConnectedRegions) closing_ellipse(ConnectedRegions, RegionClosed, 5, 5) * 特征筛选 select_shape(RegionClosed, Bottles, ['area','circularity','compactness'], 'and', [3500,0.75,0.8], [5500,1.0,1.0]) count_obj(Bottles, NumBottles) * 结果显示 dev_set_color('green') dev_display(Bottles) disp_message(3600, '检测到 '+NumBottles+' 个瓶子', 'window', 12, 12, 'black', 'true') ``` ### 四、工程优化建议 1. 光照方案:建议采用波长**850nm红外光**+**偏振滤光片**组合,可有效消除透明瓶体反光 2. 深度辅助:对于重叠瓶体,可集成**双目立体视觉**计算高度差,通过`disparity_to_distance`获取三维信息 3. 动态参:使用`determine_threshold`自动计算最佳阈值,适应不同生产批次
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值