halcon例程学习---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 HDevelop  HDevelop的一般配置
dev_update_window ('off')
 - image acquisition and window size
*获取图片存入ModelImage
read_image (ModelImage, 'razors1')
*获取图片指针,类型:byte 宽和高 在此处 只是用了宽和高
get_image_pointer1 (ModelImage, Pointer, Type, Width, Height)
*关闭现有的窗口
dev_close_window ()
 - 根据图片宽和高创建窗口  输出WindowHandle 窗口
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
*设置显示区域颜色 cyan 青色
dev_set_color ('cyan')
*定义区域的填充模式 margin 只有轮廓能显示
dev_set_draw ('margin')
*设置线宽
dev_set_line_width (2)
*停止 HDevelop 程序的连续程序执行
stop ()
 - -------------------  start of the application  ----------------
 - -> select the model object
Row1 := 46
Column1 := 57
Row2 := 79
Column2 := 94
 - 根据左上点坐标和右下点坐标 画出ROIPart1
gen_rectangle1 (ROIPart1, Row1, Column1, Row2, Column2)
 - 画出ROIPart2 
*ROIPart1和 ROIPart2 是作为刀片的两端的区域
gen_rectangle1 (ROIPart2, Row1 + 364, Column1 + 13, Row2 + 364, Column2 + 13)
*返回两个区域的并集 是并集 不是交集 返回的ModelRoi=ROIPart1+RoIPart2 (白色的区域)
union2 (ROIPart1, ROIPart2, ModelROI)
 - 获得ModelRoi的中心点 面积未用到
area_center (ModelROI, Area, CenterROIRow, CenterROIColumn)
*显示ModelImage 原图
dev_display (ModelImage)
*显示两端的感兴趣区域
dev_display (ModelROI)
stop ()
 - -> create the model
*将图像的定义域缩小到ModelROI 输出imageROI(是刀片两端的图片)。
reduce_domain (ModelImage, ModelROI, ImageROI)
*创建形状模板。 ImageROI:将用于创建模型的图像。图像金字塔的层数为4。角度旋转范围:0--0。
*AngleStep:默认值auto。'none'不进行优化,储存所有模型点。
*'use_polarity'具有相同对比度(模型是亮的物体在黑暗背景上,在原图上只有该物体同样比背景亮的情况下才会被找到)。
*30 模型点的对比度
create_shape_model (ImageROI, 4, 0, 0, 'auto', 'none', 'use_polarity', 30, 10, ModelID)
*在图片上创建形状模型的表示形式。
inspect_shape_model (ImageROI, ShapeModelImage, ShapeModelRegion, 1, 30)
*在模型轮廓中返回形状模型 ModelID 的表示形式,作为 XLD 轮廓
*得到刀片两头的模板 ShapeModel(中心坐标为(0,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
*输出区域。中心点ROW COL。角度。长度
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')
*CenterROIRow是两头刀片的中心坐标 -CenterROIRow, -CenterROIColumn是要移动的距离 不是移动到此处坐标。
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
    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)
*与模板匹配,找出刀头,输出匹配到的刀头的ROW和Column以及角度和匹配分数。
find_shape_model (SearchImage, ModelID, 0, 0, 0.8, 0, 0.5, 'least_squares', 0, 0.7, RowCheck, ColumnCheck, AngleCheck, Score)
*Score 匹配的分数>0
if (|Score| > 0)
    for i := 0 to |Score| - 1 by 1
        * step 3: determine the affine transformation
        *从原点(0,0)到位置(RowCheck[i], ColumnCheck[i])     得到变换矩阵 MovementOfObject
        vector_angle_to_rigid (0, 0, 0, RowCheck[i], ColumnCheck[i], AngleCheck[i], MovementOfObject)
        *输入ShapeModel模型(ShapeModel此时的中心坐标为(0,0)) 
        *根据仿射变换矩阵 MovementOfObject将ShapeModel(刀头) 移到新位置ModelAtNewPosition。
        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)
        *输入变换矩阵MovementOfObject 根据前面的差值获得两个新的黄条的中心坐标Rect1RowCheck, Rect1ColCheck
        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
            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]//90度
            *设定测量区域的大小 (黄条的大小)、通过算子gen_measure_rectangle2 生成MeasureHandle句柄,沿着切片方向计算平均灰度值
            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来进行计算
            *Transition=‘negitive’  沿测量矩形中轴线方向,第一个边缘点是 白-黑的点,第二个点是黑-白的点 具有这样特征的边缘将会组成边缘对;
            *RowEdge11 RowEdge21分别是边缘对的两条边缘的中心点
            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
        *|Width| 表示Width的数量
        NumberTeeth1 := |Width1|
        NumberTeeth2 := |Width2|
        dev_set_color ('red')
        *如果NumberTeeth<37 就是少齿
        if (NumberTeeth1 < 37)
            for j := 0 to NumberTeeth1 - 2 by 1
                *连续边缘对之间的距离 (两个齿之间的距离>4的 中间是缺齿了)
                if (Distance1[j] > 4.0)
                    RowFault := round(0.5 * (RowEdge11[j + 1] + RowEdge21[j]))//结果是齿中间空隙的中心点(下个齿的上边缘+齿的下边缘)/2
                    ColFault := round(0.5 * (ColEdge11[j + 1] + ColEdge21[j]))
                    *在WindowHandle指向的窗口上显示矩形。矩形的中心 RowFault, ColFault,矩形的长宽4, 4
                    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 显示矩形 
                    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)

halcon例程学习---align_measurements_第1张图片
这个例程的大概流程:

  • 创建模板(get_shape_model_contours )
  • 找出剩余的位置(find_shape_model )
  • 根据明暗边缘检测找出齿的个数(measure_pairs )
  • 根据各个齿的距离来检测是否少齿(measure_pairs )

有不对的地方欢迎指正 谢谢

你可能感兴趣的:(学习,计算机视觉,图像处理)