Halcon形状模板匹配

总结:

(1)inspect_shape_model(Image : ModelImages, ModelRegions : NumLevels, Contrast : )        用于确定create_shape_model的Contrast和NumLevels参数,并显示图像效果,因此一般在create_shape_model之前使用。

(2)create_shape_model : 创建模板,其中参数MinContrast来过滤find_shape_models中找到的目标的中对比度小于阈值的目标,而使其忽略匹配

(3)get_shape_model_contours:用于观察create_shape_model模板的轮廓,生成位置在0点

(4)find_shape_model:查找模板,如果NumLevels参数设置为0则使用create_shape_model 中设置的NumLevels值。

(5)clear_shape_model (ModelID):关闭模板句柄

(6)dev_display_shape_matching_results:外部函数,展示所有查找到的目标的轮廓,但仅显示在底层金字塔的图像

(7)get_hom_mat2d_from_matching_result:外部函数,获取从模板轮廓初始生成位置移动到定位目标位置的变换矩阵

(8)write_shape_model:将模板写入文件

(9)其他:

read_shape_model;

create_scaled_shape_model;

create_shape_model_xld;

create_scaled_shape_model_xld;

set_shape_model_param;

get_shape_model_param;

find_shape_models;

find_scaled_shape_models;

案例一、align_measurements

* ------------------------------------------------------------------------------------------------
* This example program uses shape-based matching to align ROIs for the measure
* tool, which then inspects individual razor blades.
* The program can be run in two modes: (1) with the full affine transformation
*                                                                (2) using translate_measure
* Modify the next line to switch between the modes.
USING_TRANSLATE_MEASURE := 0
* ------------------------------------------------------------------------------------------------
* general configuration of HDevelopS
dev_update_window ('off')
* image acquisition and window size
read_image (ModelImage, 'razors1')
get_image_pointer1 (ModelImage, Pointer, Type, Width, Height)
dev_close_window ()
dev_open_window (0, 0, Width, Height, 'white', WindowHandle)
dev_set_part (0, 0, Height - 1, Width - 1)
dev_display (ModelImage)
* colors and other settings for the visualization
dev_set_color ('cyan')
dev_set_draw ('margin')
dev_set_line_width (2)
stop ()
* -------------------  start of the application  ----------------
* -> select the model object
Row1 := 46
Column1 := 57
Row2 := 79
Column2 := 94
gen_rectangle1 (ROIPart1, Row1, Column1, Row2, Column2)
gen_rectangle1 (ROIPart2, Row1 + 364, Column1 + 13, Row2 + 364, Column2 + 13)
union2 (ROIPart1, ROIPart2, ModelROI)
area_center (ModelROI, Area, CenterROIRow, CenterROIColumn)
dev_display (ModelImage)
dev_display (ModelROI)
stop ()
* -> create the model
reduce_domain (ModelImage, ModelROI, ImageROI)
*创建模板
create_shape_model (ImageROI, 4, 0, 0, 'auto', 'none', 'use_polarity', 30, 10, ModelID)
*该函数用于事先确定创建模板时的对比度Contrast参数,临时使用
inspect_shape_model (ImageROI, ShapeModelImage, ShapeModelRegion, 1, 30)
*得到模板的轮廓图,方便后面找到目标后进行观察,仅起到观察作用,生成位置在左上角像素为0的位置
*可设置金字塔层数
get_shape_model_contours (ShapeModel, ModelID, 1)
dev_clear_window ()
dev_set_color ('blue')
dev_display (ShapeModelRegion)
stop ()
* step 1: create variables describing  the measurement ROIs and display them
Rect1Row := 244
Rect1Col := 73
DistColRect1Rect2 := 17
Rect2Row := Rect1Row
Rect2Col := Rect1Col + DistColRect1Rect2
RectPhi := rad(90)
RectLength1 := 122
RectLength2 := 2
*生成两个矩形区域,用于显示检测的区域,仅用于观察
gen_rectangle2 (MeasureROI1, Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2)
gen_rectangle2 (MeasureROI2, Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2)
dev_display (ModelImage)
dev_set_color ('yellow')
dev_display (MeasureROI1)
dev_display (MeasureROI2)
* translate measurement ROIs to lie on XLD model (without clipping!)
get_system ('clip_region', OriginalClipRegion)
set_system ('clip_region', 'false')
*把矩形移动到和上面模板相同的位置,在相对位置上组成一个检测整体
*模板匹配用于定位,矩形用于跟随定位到位后执行检测
move_region (MeasureROI1, MeasureROI1Ref, -CenterROIRow, -CenterROIColumn)
move_region (MeasureROI2, MeasureROI2Ref, -CenterROIRow, -CenterROIColumn)
set_system ('clip_region', OriginalClipRegion)
DistRect1CenterRow := Rect1Row - CenterROIRow
DistRect1CenterCol := Rect1Col - CenterROIColumn
DistRect2CenterRow := Rect2Row - CenterROIRow
DistRect2CenterCol := Rect2Col - CenterROIColumn
if (USING_TRANSLATE_MEASURE != 0)
    * -> measure objects are created only once in advance and then translated later
    *(路径选项2)仿照上面的矩形生成实际的矩形测量工具,此时测量工具还不在目标位置
    gen_measure_rectangle2 (Rect1Row, Rect1Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1)
    gen_measure_rectangle2 (Rect2Row, Rect2Col, RectPhi, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2)
endif
stop ()
* step 2: find the objects in another image
read_image (SearchImage, 'razors2')
dev_display (SearchImage)
*根据模板定位到每一个目标,得到目标的位置
find_shape_model (SearchImage, ModelID, 0, 0, 0.8, 0, 0.5, 'least_squares', 0, 0.7, RowCheck, ColumnCheck, AngleCheck, Score)
if (|Score| > 0)
    for i := 0 to |Score| - 1 by 1
        * step 3: determine the affine transformation
        *将用于观察的模板轮廓移动到目标位置,用于观察
        vector_angle_to_rigid (0, 0, 0, RowCheck[i], ColumnCheck[i], AngleCheck[i], MovementOfObject)
        affine_trans_contour_xld (ShapeModel, ModelAtNewPosition, MovementOfObject)
        dev_display (ModelAtNewPosition)
        * step 4: measure width and distance of the teeth
        * -> display the moved ROIs
        *将用于观察的矩形轮廓移动到目标位置,用于观察
        affine_trans_region (MeasureROI1Ref, MeasureROI1AtNewPosition, MovementOfObject, 'constant')
        affine_trans_region (MeasureROI2Ref, MeasureROI2AtNewPosition, MovementOfObject, 'constant')
        dev_display (MeasureROI1AtNewPosition)
        dev_display (MeasureROI2AtNewPosition)
        affine_trans_pixel (MovementOfObject, DistRect1CenterRow, DistRect1CenterCol, Rect1RowCheck, Rect1ColCheck)
        affine_trans_pixel (MovementOfObject, DistRect2CenterRow, DistRect2CenterCol, Rect2RowCheck, Rect2ColCheck)
        if (USING_TRANSLATE_MEASURE != 0)
            * -> translate the already created measure objects
            *(路径选项2)把实际的测量矩形移动到目标位置
            translate_measure (MeasureHandle1, Rect1RowCheck, Rect1ColCheck)
            translate_measure (MeasureHandle2, Rect2RowCheck, Rect2ColCheck)
            measure_pairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1)
            measure_pairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2)
        else
            * -> create new measure objects and destroy them after the measurement
            *仿照上面的矩形生成实际的矩形测量工具
            RectPhiCheck := RectPhi + AngleCheck[i]
            gen_measure_rectangle2 (Rect1RowCheck, Rect1ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle1)
            gen_measure_rectangle2 (Rect2RowCheck, Rect2ColCheck, RectPhiCheck, RectLength1, RectLength2, Width, Height, 'bilinear', MeasureHandle2)
            * step 5: perform the measurement
            *启动测量
            measure_pairs (SearchImage, MeasureHandle1, 2, 25, 'negative', 'all', RowEdge11, ColEdge11, Amp11, RowEdge21, ColEdge21, Amp21, Width1, Distance1)
            measure_pairs (SearchImage, MeasureHandle2, 2, 25, 'negative', 'all', RowEdge12, ColEdge12, Amp12, RowEdge22, ColEdge22, Amp22, Width2, Distance2)
            close_measure (MeasureHandle1)
            close_measure (MeasureHandle2)
        endif
        * step 6: check for too short or missing teeth
        NumberTeeth1 := |Width1|
        NumberTeeth2 := |Width2|
        dev_set_color ('red')
        *判断是否缺少齿数
        if (NumberTeeth1 < 37)
            for j := 0 to NumberTeeth1 - 2 by 1
                if (Distance1[j] > 4.0)
                    RowFault := round(0.5 * (RowEdge11[j + 1] + RowEdge21[j]))
                    ColFault := round(0.5 * (ColEdge11[j + 1] + ColEdge21[j]))
                    disp_rectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4)
                    dev_open_window (0, Width + 20, 80, 80, 'black', WindowHandleZoom)
                    dev_set_part (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10)
                    dev_display (SearchImage)
                    disp_rectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4)
                    stop ()
                    dev_close_window ()
                    dev_set_part (0, 0, Height - 1, Width - 1)
                endif
            endfor
        endif
        if (NumberTeeth2 < 37)
            for j := 0 to NumberTeeth2 - 2 by 1
                if (Distance2[j] > 4.0)
                    RowFault := round(0.5 * (RowEdge12[j + 1] + RowEdge22[j]))
                    ColFault := round(0.5 * (ColEdge12[j + 1] + ColEdge22[j]))
                    disp_rectangle2 (WindowHandle, RowFault, ColFault, 0, 4, 4)
                    dev_open_window (0, Width + 20, 80, 80, 'black', WindowHandleZoom)
                    dev_set_part (RowFault - 10, ColFault - 10, RowFault + 10, ColFault + 10)
                    dev_display (SearchImage)
                    disp_rectangle2 (WindowHandleZoom, RowFault, ColFault, 0, 4, 4)
                    stop ()
                    dev_close_window ()
                    dev_set_part (0, 0, Height - 1, Width - 1)
                endif
            endfor
        endif
        dev_set_color ('yellow')
        stop ()
    endfor
endif
* -------------------  end of the application  -----------------
* clean up
if (USING_TRANSLATE_MEASURE != 0)
    close_measure (MeasureHandle1)
    close_measure (MeasureHandle2)
endif
dev_update_window ('on')
clear_shape_model (ModelID)

案例二、check_soft_cheese

* The following example shows a production line, which carries
* packages of soft cheese. The cheese packages consist of three
* types of flavor: cream, ham and paprika. During quality
* inspection each package is checked for its right content.
* Each has to contain 4 pieces of cream cheese ('Sahne'),
* 2 pieces of ham ('Schinken') and 2 pieces of paprika ('Paprika')
* - any deviation is reported otherwise. To obtain the number of
* each flavor, we use the shape-based matching feature. After we
* define the models, we count the occurrence of the models to
* get the actual number of the cheese flavors. Finally we give out
* the statistics for each inspection.
* 
dev_close_window ()
dev_update_off ()
read_image (Image, 'food/soft_cheese_01')
dev_open_window_fit_image (Image, 0, 0, -1, -1, WindowHandle)
set_display_font (WindowHandle, 14, 'mono', 'true', 'false')
dev_set_line_width (2)
* 
* 
* As a first step, determine the shape models for the three flavors
rgb1_to_gray (Image, GrayImage)
*生成填充的多边形区域
gen_region_polygon_filled (Paprika, [77,84,203], [306,405,347])
erosion_circle (Paprika, Paprika, 3.5)
PaprikaCount := 2
gen_region_polygon_filled (Cream, [94,171,210], [424,488,363])
erosion_circle (Cream, Cream, 3.5)
CreamCount := 4
gen_region_polygon_filled (Ham, [185,285,225], [496,492,367])
erosion_circle (Ham, Ham, 3.5)
HamCount := 2
* 
reduce_domain (GrayImage, Paprika, ImageReduced)
*inspect_shape_model (ImageReduced, ModelImages, ModelRegions, 1, 25) *用于确定模板的Contrast
create_shape_model (ImageReduced, 'auto', 0, rad(360), rad(1.5), ['point_reduction_high','no_pregeneration'], 'use_polarity', [25,50], 'auto', ModelID1)
*get_shape_model_contours (Contour, ModelID1, 1) *查看模板的轮廓
reduce_domain (GrayImage, Cream, ImageReduced)
create_shape_model (ImageReduced, 'auto', 0, rad(360), rad(1.5), ['point_reduction_high','no_pregeneration'], 'use_polarity', [25,50], 'auto', ModelID2)
reduce_domain (GrayImage, Ham, ImageReduced)
create_shape_model (ImageReduced, 'auto', 0, rad(360), rad(1.5), ['point_reduction_high','no_pregeneration'], 'use_polarity', [25,50], 'auto', ModelID3)
* 
* 
* Check for the occurrence of each cheese flavor by using the find model tool
ModelIDs := [ModelID1,ModelID2,ModelID3]
ColorIndex := ['red','magenta','yellow']
TypesIndex := ['P','C','H']
* 
NumImages := 18
for Index := 1 to NumImages by 1
    AnglesTypes := []
    Types := []
    read_image (Image, 'food/soft_cheese_' + Index$'02')
    rgb1_to_gray (Image, GrayImage)
    threshold (GrayImage, Region, 70, 255)
    fill_up (Region, RegionFillUp)
    opening_circle (RegionFillUp, RegionOpening, 3.5)
    reduce_domain (GrayImage, RegionOpening, ImageReduced)
    shape_trans (RegionOpening, Circle, 'outer_circle')
    find_shape_models (ImageReduced, ModelIDs, 0, rad(360), 0.5, 8, 0.5, 'least_squares', 0, 0.8, Row, Column, Angle, Score, ModelIndex)
    area_center (Circle, Area, RowObj, ColumnObj)
    * 
    * display found matches and all over statistics
    dev_clear_window ()
    dev_display (Image)
    if (|Score| == 0)
        disp_message (WindowHandle, 'No Model found!', true, 25, 20, 'black', 'true')
    else
        CountModels := [0,0,0]
        for I := 0 to |Score| - 1 by 1
            Types := [Types,TypesIndex[ModelIndex[I]]]
            dev_set_color (ColorIndex[ModelIndex[I]])
            CountModels[ModelIndex[I]] := CountModels[ModelIndex[I]] + 1
            get_shape_model_contours (Contour, ModelIDs[ModelIndex[I]], 1)
            vector_angle_to_rigid (0, 0, 0, Row[I], Column[I], Angle[I], HomMat2D)
            affine_trans_contour_xld (Contour, ContoursAffineTrans, HomMat2D)
            dev_display (ContoursAffineTrans)
            * 
            * remember order of flavors
            affine_trans_point_2d (HomMat2D, 0, 0, RowPiece, ColumnPiece)
            angle_lx (RowObj, ColumnObj, RowPiece, ColumnPiece, AngleTyp)
            if (deg(AngleTyp) > 0)
                AnglesTypes := [AnglesTypes,deg(AngleTyp)]
            else
                AnglesTypes := [AnglesTypes,360 + deg(AngleTyp)]
            endif
        endfor
        * 
        display_statistic (Circle, WindowHandle, CountModels, PaprikaCount, CreamCount, HamCount, AnglesTypes, Types)
        * 
    endif
    if (Index < NumImages)
        disp_continue_message (WindowHandle, 'black', 'true')
        stop ()
    endif
endfor

上一篇:基于Qt的OpenGL(三):QOpenGLShaderProgram和GLSL


下一篇:吴恩达深度学习-第二周编程作业