Halcon :Blob分析之Check_blister胶囊检测

该示例展示了制药行业的一个应用,通过图像处理技术检查自动填充的药丸板内容。首先,使用参考图像定位药丸室,并进行仿射变换以对后续图像进行对齐。然后,利用blob分析分割每个药丸室的内容,并根据形状特征进行分类。在循环检测每张图片时,对图像进行对齐、裁剪和分割,最后通过形状和面积等特征对药丸进行正确、错误和缺失的分类并显示统计结果。
摘要由CSDN通过智能技术生成

* This example demonstrates an application from the pharmaceutical industry.
* The task is to check the content of automatically filled blisters.
* The first image (reference) is used to locate the chambers within a blister shape as a reference model, which is then used to realign the subsequent images along to this reference shape. Using
blob analysis the content of each chamber is segmented and finally classified by a few shape features.
* 使用blob分析,每个腔室的内容被分割并最终通过一些形状特征进行分类。

*1)采集图像
dev_close_window ()
dev_update_off ()
read_image (ImageOrig, 'blister/blister_reference')
dev_open_window_fit_image (ImageOrig, 0, 0, -1, -1, WindowHandle)
*打开具有给定最小和最大范围的新图形窗口,以便保留给定图像大小的宽高比
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_draw ('margin')
dev_set_line_width (3)
 

* 2)定位(求标准位置,blob)
* In the first step, we create a pattern to cut out the chambers in the
* subsequent blister images easily.

access_channel (ImageOrig, Image1, 1) *获得一个灰度图像(第一个通道 的图像)
threshold (Image1, Region, 90, 255)
shape_trans (Region, Blister, 'convex')
orientation_region (Blister, Phi) *orientation_region计算区域的方向,这个算子是基于elliptic_axis 算子来的,elliptic_axis 是求取等效的椭圆,所以用算子orientation_region相当于把区域Blister转化为一个等效椭圆,计算这个椭圆的长轴在图像中的角度Phi
area_center (Blister, Area1, Row, Column)
vector_angle_to_rigid (Row, Column, Phi, Row, Column, 0, HomMat2D)#根据点对应关系和两个对应角度计算刚性仿射变换,即由旋转和平移组成的仿射变换
affine_trans_image (ImageOrig, Image2, HomMat2D, 'constant', 'false')*affine_trans_image - 对图像进行任意的2D仿射变换。ImageOrig:要进行仿射变换的图像;Image2:仿射变换之后的图像;HomMat2D:2D仿射变换矩阵;constant:进行仿射变换的方式,这个代表使用均值滤波器来防止混叠效应的发生。false:仿射变换后的图片超出现有图片大小的区域不被剪切掉;若为true则相反。
gen_empty_obj (Chambers)*生成一个空的对象Chambers,类似于list.append()

*画区域方块
for I := 0 to 4 by 1
    Row := 88 + I * 70
    for J := 0 to 2 by 1
        Column := 163 + J * 150
        gen_rectangle2 (Rectangle, Row, Column, 0, 64, 30)*生成一个可旋转的矩形; * * 前两个参数是区域中心坐标,第三个参数是矩形角度,后两个参数是矩形的宽高。
        concat_obj (Chambers, Rectangle, Chambers)*concat_obj (Chambers, Rectangle, Chambers) * concat_obj - 把两个对象融合在一起。 注意,这 个和union不一样,union是把两个对象整合成一个对象,整合后对象的元素个数为1; 而使用concat_obj 是把几个对象联合成一个对象,这个对象中的元素个数之和不变。
    endfor
endfor

affine_trans_region (Blister, Blister, HomMat2D, 'nearest_neighbor')*使用变换矩阵HomMat2D对Blister区域使用nearest_neighbor方法进行仿射变换,这里的Blister是仿射变换后的Blister。
difference (Blister, Chambers, Pattern)*求取区域Blister与区域Chambers的差集

union1 (Chambers, ChambersUnion)*将区域Chambers(有多个元素)联合成一个区域(一个元素)
orientation_region (Blister, PhiRef)
PhiRef := rad(180) + PhiRef
area_center (Blister, Area2, RowRef, ColumnRef)


* Each image read will be aligned to this pattern and reduced to the area of interest,
* which is the chambers of the blister

循环检测每一张图片
Count := 6
for Index := 1 to Count by 1
    read_image (Image, 'blister/blister_' + Index$'02')
    threshold (Image, Region, 90, 255)
    connection (Region, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 5000, 9999999)
    shape_trans (SelectedRegions, RegionTrans, 'convex')
    * 
    * Align pattern along blister of image
    orientation_region (RegionTrans, Phi)
    area_center (RegionTrans, Area3, Row, Column)
    vector_angle_to_rigid (Row, Column, Phi, RowRef, ColumnRef, PhiRef, HomMat2D)
    affine_trans_image (Image, ImageAffineTrans, HomMat2D, 'constant', 'false')
    * 
    * Segment pills
    reduce_domain (ImageAffineTrans, ChambersUnion, ImageReduced)*使用区域剪切图片,缩小图像处理定义域
    decompose3 (ImageReduced, ImageR, ImageG, ImageB)*将图片ImageReduced分成R/G/B三通道图像
    var_threshold (ImageB, Region, 7, 7, 0.2, 2, 'dark')*通过局部均值和标准差分析对图像进行阈值处理
    connection (Region, ConnectedRegions0)
    closing_rectangle1 (ConnectedRegions0, ConnectedRegions, 3, 3)*闭运算能够填平小湖(即小孔),弥合小裂缝,而总的位置和形状不变。
    fill_up (ConnectedRegions, RegionFillUp)
    select_shape (RegionFillUp, SelectedRegions, 'area', 'and', 1000, 99999)
    opening_circle (SelectedRegions, RegionOpening, 4.5)
    connection (RegionOpening, ConnectedRegions)
    select_shape (ConnectedRegions, SelectedRegions, 'area', 'and', 1000, 99999)
    shape_trans (SelectedRegions, Pills, 'convex')

    * 
    * Classify segmentation results and display statistics
    count_obj (Chambers, Number)
    gen_empty_obj (WrongPill)
    gen_empty_obj (MissingPill)
    for I := 1 to Number by 1
        select_obj (Chambers, Chamber, I)
        intersection (Chamber, Pills, Pill)
        area_center (Pill, Area, Row1, Column1)
        if (Area > 0)
            min_max_gray (Pill, ImageB, 0, Min, Max, Range)
            if (Area < 3800 or Min < 60)
                concat_obj (WrongPill, Pill, WrongPill)
            endif
        else
            concat_obj (MissingPill, Chamber, MissingPill)
        endif
    endfor
    * 
    dev_clear_window ()
    dev_display (ImageAffineTrans)
    dev_set_color ('forest green')
    count_obj (Pills, NumberP)
    count_obj (WrongPill, NumberWP)
    count_obj (MissingPill, NumberMP)
    dev_display (Pills)
    if (NumberMP > 0 or NumberWP > 0)
        disp_message (WindowHandle, 'Not OK', 'window', 12, 12 + 600, 'red', 'true')
    else
        disp_message (WindowHandle, 'OK', 'window', 12, 12 + 600, 'forest green', 'true')
    endif
    * 
    Message := '# Correct pills: ' + (NumberP - NumberWP)
    Message[1] := '# Wrong pills  :  ' + NumberWP
    Message[2] := '# Missing pills:  ' + NumberMP
    * 
    Colors := gen_tuple_const(3,'black')
    if (NumberWP > 0)
        Colors[1] := 'red'
    endif
    if (NumberMP > 0)
        Colors[2] := 'red'
    endif
    disp_message (WindowHandle, Message, 'window', 12, 12, Colors, 'true')
    dev_set_color ('red')
    dev_display (WrongPill)
    dev_display (MissingPill)
    if (Index < Count)
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
endfor

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值