0022_缺陷检测(3)

示例三:check_blister.hdev

blob分析+特征(定位)

该示例的主要内容是:检测各个药板上的药粒是否存在缺失或者药粒不正确的情况

该示例的实现的方法步骤如下:

1. 读取药粒样板的图像

2. 通过blob+定位等手段,获取药粒样板的区域以及其他相关数据

3. 循环读取待检测的药板图片进行处理

3.1获取药板的区域,并且对药板图像进行仿射变换的处理

3.2获取药板上的药粒区域

3.3将待检测的药粒区域与之前的药粒样板区域求交集,从而能分别判断各个药粒的面积和灰度值,从而能进行检测

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)
    * 获取三个不同的颜色通道
    decompose3 (ImageReduced, ImageR, ImageG, ImageB)
    * 通过本地均值和标准差分析进行二值化处理
    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 (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

猜你喜欢

转载自blog.csdn.net/ymj7150697/article/details/83043498
今日推荐