0023_缺陷检测(4)

2019-07-14 11:30发布

示例四:measure_fill_level.hdev

此示例缺陷检测使用的方法是:模板匹配定位 + 测量   大体思路如下: 1. 采集图像 2. 通过模板匹配定位找到参考线 3. 用测量矩形找液面的边 4. 计算边缘和参考线之间的距离  

代码分析如下:

* 读取图像
dev_close_window ()
dev_update_off ()
read_image (Image, 'ampoules/ampoules_01')
get_image_size (Image, Width, Height)
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
dev_set_line_width (2)
dev_set_draw ('margin')
set_display_font (WindowHandle, 16, 'mono', 'true', 'false')

* Create a model for the ampoule head to align the measure handle
* 创建模板
gen_rectangle1 (Rectangle, 230, 280, 317, 330)
reduce_domain (Image, Rectangle, ImageModel)
create_shape_model (ImageModel, 'auto', 0, 0, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)

* Initialize the measure handle
* 生成一个初始的测量矩形,得到测量句柄
gen_measure_rectangle2 (0, 0, rad(90), 75, 20, Width, Height, 'bilinear', MeasureHandle)
Tolerance := 15

* Determine the fill level
NumImages := 8
for Index := 1 to NumImages by 1
    * 读取图像
    read_image (Image, 'ampoules/ampoules_' + Index$'.2d')
    ColumnEdges := []
    FillLevelHeight := []
    * 
    * 模板匹配,此步骤是为了定位每一个药瓶一个位置的中心点坐标
    * 为后续确定药水水平线的位置做准备

    find_shape_model (Image, ModelID, 0, 0, 0.7, 0, 0.1, 'least_squares', 0, 0.9, Row, Column, Angle, Score)
    * 对找到的所有,行坐标求平均值
    MeanRow := mean(Row)
    * 确定药水的水平线位置:以模板匹配获得的各个药水瓶的行坐标平均值为基准,
    * 获得药水线的基准参考位置

    RefLevel := MeanRow - 160
    * Display tolerance area
    dev_display (Image)
    dev_set_line_width (1)
    dev_set_color ('white')
    gen_rectangle2 (AcceptLevel, RefLevel, mean(Column), 0, 30 + (max(Column) - min(Column)) / 2, Tolerance)
    dev_display (AcceptLevel)
    dev_set_line_width (2)
    * 
    *  Determine fill level of each ampoule
    Errors := 0
    for Idx := 0 to |Score| - 1 by 1
        * 平移MeasureHandle句柄对应的测量对象
        translate_measure (MeasureHandle, MeanRow - 135, Column[Idx])
        * Search for the topmost edge
        * 通过测量的方式,得到药水线的位置
        measure_pos (Image, MeasureHandle, 2, 7, 'all', 'first', RowEdge, ColumnEdge, Amplitude, Distance)
        * 下面的代码作用:显示各个药水瓶的药水线的位置,并且标识出是OK还是NG
        * 判断的标准是:测量获得药水线高度坐标与药水线参考高度之间不能超过设置的
        * 容忍范围(此处容忍范围是15)。
        * 超过容忍范围,为NG

        FillLevelHeight := [FillLevelHeight,RowEdge]
        ColumnEdges := [ColumnEdges,ColumnEdge]
        gen_cross_contour_xld (Cross, RowEdge, ColumnEdge, 15, 0)
        gen_rectangle2 (FillLevel, RowEdge, ColumnEdge, 0, 28, 20)
        if (abs(FillLevelHeight[Idx] - RefLevel) >= Tolerance)
            gen_rectangle2 (ChamberSingle, MeanRow - 133, Column[Idx], 0, 35, 90)
            gen_cross_contour_xld (Cross, FillLevelHeight[Idx], ColumnEdges[Idx], 15, 0)
            gen_rectangle2 (FillLevel, FillLevelHeight[Idx], ColumnEdges[Idx], 0, 28, 20)
            Errors := Errors + 1
            dev_set_color ('red')
            dev_display (ChamberSingle)
            disp_message (WindowHandle, 'NG', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'red', 'false')
        else
            disp_message (WindowHandle, 'OK', 'image', FillLevelHeight[Idx] - 50, ColumnEdges[Idx] - 10, 'green', 'false')
            dev_set_color ('green')
        endif
        dev_display (FillLevel)
        dev_display (Cross)
    endfor
    * 
    * Check, whether the fill level is within the allowed range - does not deviate too much
    * from average fill level
    * 
    * Display statistics
    if (Errors > 0)
        disp_message (WindowHandle, Errors + ' BAD', 'window', 10, 12, 'red', 'true')
    else
        disp_message (WindowHandle, 'All OK', 'window', 10, 12, 'forest green', 'true')
    endif
    if (Index < NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

close_measure (MeasureHandle)
clear_shape_model (ModelID)   更多halcon和六轴机械臂算法干货公众号: