定位--药品胶囊检测

对应示例程序:
check_blister.hdev

目标:对药品胶囊进行检测,包括错件和缺件

思路为:
      1.读取图像,并根据偏转角度,对图像进行仿射变换校正
      2.根据先验知识,生成多个矩形框,用于裁剪ROI
      3.裁剪感兴趣区域,并通过Blob分析,借助区域面积和灰度值,确定缺件和错件位置
      4.进行显示,并输出结果到桌面

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

代码:

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)
* 
* 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)
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')
*************************************************
*******************有规律的提取出每个腔体*****************
gen_empty_obj (Chambers)
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)
    endfor
endfor

********************************************************
affine_trans_region (Blister, Blister, HomMat2D, 'nearest_neighbor') //对最外面的边框也进行仿射变换 居中
difference (Blister, Chambers, Pattern)  //计算边界与腔体的差异
union1 (Chambers, ChambersUnion)
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, ImageAffinTrans, HomMat2D, 'constant', 'false')
    * ********************************************************
    
    
    * Segment pills  分离腔体
    reduce_domain (ImageAffinTrans, ChambersUnion, ImageReduced)  //一次性裁剪出全部的ROI
    decompose3 (ImageReduced, ImageR, ImageG, ImageB)  //分离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)  //用于存放 NG腔体
    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 (ImageAffinTrans)
    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', 10, 10 + 600, 'red', 'true')
    else
        disp_message (WindowHandle, 'OK', 'window', 10, 10 + 600, 'forest green', 'true')
    endif
    disp_message (WindowHandle, '# correct pills: ' + (NumberP - NumberWP), 'window', 10, 10, 'black', 'true')
    disp_message (WindowHandle, '# wrong pills  :  ' + NumberWP, 'window', 10 + 25, 10, 'black', 'true')
    if (NumberWP > 0)
        disp_message (WindowHandle, NumberWP, 'window', 10 + 25, 10 + 180, 'red', 'true')
    endif
    disp_message (WindowHandle, '# missing pills:  ' + NumberMP, 'window', 10 + 50, 10, 'black', 'true')
    if (NumberMP > 0)
        disp_message (WindowHandle, NumberMP, 'window', 10 + 50, 10 + 180, 'red', 'true')
    endif
    dev_set_color ('red')
    dev_display (WrongPill)
    dev_display (MissingPill)
    if (Index < Count)
        disp_continue_message (WindowHandle, 'black', 'true')
    endif
    stop ()
endfor


用到的几个算子:
      orientation_region—计算区域的方向
      difference–计算两个区域的差异
      intersection–计算两个区域的交集
      count_obj–统计Obj的数量
      vector_angle_to_rigid–从点和角度计算刚性仿射变换(6个参数输入,一个矩阵输出)

参考资料:
[1]:https://blog.csdn.net/lixianjun913/article/details/13510779
[2]:https://blog.csdn.net/cashmood/article/details/90639705

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值