Halcon例程学习:基于灰度值模板匹配vector_angle_to_rigid

* 
* online shape-based matching with adaptation to illumination changes
*基于形状的在线匹配,能够适应光照变化
* rotational invariant
* rotation/translation to "normalize" the input image
* 旋转不变,旋转/平移以“规范化”输入图像
* set online to true if you are using an image acquisition device
* if online is set to false, a virtual image acquisition device is opened which reads an image sequence from hard disk
* 
online := false
*设置未定义像素为黑色
VisUndefPixelBlack := 1
*关闭所有显示更新以提高性能
dev_update_window ('off')
dev_update_pc ('off')
dev_update_var ('off')
dev_update_time ('off')
if (online)
    * open the 'real' image acquisition device
    *获取真实图像获取设备的信息
    info_framegrabber ('1394IIDC', 'revision', RevisionInfo, RevisionInfoValues)
    *打开真实的图像采集设备
    open_framegrabber ('1394IIDC', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'default', 'default', -1, -1, AcqHandle)
else
    * open the virtual image acquisition device
    *获取真实图像获取设备的信息
    info_framegrabber ('File', 'general', Information, ValueList)
    *打开虚拟图像采集设备,读取存储在硬盘上的图像序列
    open_framegrabber ('File', 1, 1, 0, 0, 0, 0, 'default', -1, 'default', -1, 'default', 'pendulum/pendulum', 'default', -1, 1, AcqHandle)
endif
*获取一幅图
grab_image (Image, AcqHandle)
*获取图像的宽度和高度
get_image_size (Image, Width, Height)
dev_close_window ()
*打开新窗口用于显示旋转后的图像
dev_open_window (0, Width + 30, Width, Height, 'black', WindowRot)
*打开新窗口用于显示原始图像
dev_open_window (0, 0, Width, Height, 'black', WindowID)
*设置当前窗口及活动区域
dev_set_window (WindowID)
dev_set_part (0, 0, Height - 1, Width - 1)
*设置旋转窗口及旋转窗口活动区域
dev_set_window (WindowRot)
dev_set_part (0, 0, Height - 1, Width - 1)
*显示原始图像
dev_display (Image)
*设置原窗口文本的显示属性:字体大小16、字体类型momo、启用抗锯齿、不使用下划线
set_display_font (WindowID, 16, 'mono', 'true', 'false')
*输出一个恒等变换矩阵(这个矩阵通常用作其他仿射变换的基础)
hom_mat2d_identity (HomMat2DIdentity)
* disp_continue_message (WindowID, 'black', 'true')
* stop ()
* ------------------------
* select the model object
*选择模型对象
* ------------------------
if (online)
    * 
    * define template by drawing a rectangle
    * 定义模板区域
    dev_update_pc ('off')
    dev_set_window (WindowID)
    *设置绘图区域的边界及线宽
    dev_set_draw ('margin')
    dev_set_line_width (5)
    *从AcqHandle中获取图像
    grab_image (ImageTempl, AcqHandle)
    dev_set_window (WindowID)
    dev_display (ImageTempl)
    *在原窗口(12,12)位置处显示文本,并设置绘图颜色为green
    disp_message (WindowID, 'define the template', 'window', 12, 12, 'black', 'true')
    dev_set_color ('green')
    *在原窗口绘制一个旋转矩形,矩形的中心位于(RowTempl, ColumnTempl),旋转角度为PhiTempl,长度为Length1和Length2。
    draw_rectangle2 (WindowID, RowTempl, ColumnTempl, PhiTempl, Length1, Length2)
    *生成一个旋转矩形形状,其属性存储在变量Rectangle中。
    gen_rectangle2 (Rectangle, RowTempl, ColumnTempl, PhiTempl, Length1, Length2)
    dev_display (Rectangle)
    *根据旋转矩形Rectangle减少图像ImageTempl的定义域,生成新的图像ImageReduced。
    reduce_domain (ImageTempl, Rectangle, ImageReduced)
    *创建一个形状模型ModelID,金字塔层数4,模板旋转起始角度0,转角范围360,旋转步长auto,模板优化方法none,匹配方法
    *'use_polarity',对比度30,最小对比度10
    create_shape_model (ImageReduced, 4, 0, rad(360), 'auto', 'none', 'use_polarity', 30, 10, ModelID)
    *对图像ImageReduced进行强度标准化处理,得到灰度均值TemplMean和灰度偏差Deviation
    intensity (ImageReduced, Image, TemplMean, Deviation)
    dev_update_pc ('on')
else
    * 
    * load default object for virtual framegrabber
    * 加载虚拟图像采集设备的默认对象
    *定义了将要创建的形状的尺寸和方向。Length1和Length2是形状的两个长度参数,PhiTempl是形状的旋转角度
    *(以弧度为单位,-0.315弧度约等于-18度),RowTempl和ColumnTempl是形状中心的坐标。
    Length1 := 32.0
    Length2 := 12.5
    PhiTempl := -0.315
    RowTempl := 112.5
    ColumnTempl := 92.0
    *从(1,1)开始,将原始图像Image到ImageTempl
    copy_obj (Image, ImageTempl, 1, 1)
    *生成一个旋转矩形形状,其属性存储在变量Rectangle中。
    gen_rectangle2 (Rectangle, RowTempl, ColumnTempl, PhiTempl, Length1, Length2)
    *根据旋转矩形Rectangle减少图像ImageTempl的定义域,生成新的图像ImageReduced。
    reduce_domain (Image, Rectangle, ImageReduced)
    *创建一个形状模型ModelID,金字塔层数4,模板旋转起始角度0,转角范围360,旋转步长auto,模板优化方法none,匹配方法
    *'use_polarity',对比度30,最小对比度10
    create_shape_model (ImageReduced, 4, 0, rad(360), 'auto', 'none', 'use_polarity', 30, 10, ModelID)
    *对图像ImageReduced进行强度标准化处理,得到灰度均值TemplMean和灰度偏差Deviation
    intensity (ImageReduced, Image, TemplMean, Deviation)
endif
* RowRot := RowTempl
* ColumnRot := ColumnTempl
*设置旋转中心点
RowRot := Height / 2
ColumnRot := Width / 2
* ------------------------------------------
* visualize normalized input image
*可视化归一化输入图像
* ------------------------------------------
* Compensate for rotation and translation
*补偿旋转和位移

*将一个旋转中心(RowTempl, ColumnTempl)和旋转角度PhiTempl转换为一个仿射变换矩阵HomMat2DRotate。这个矩阵将用于后续的图像变换。
*参数RowRot和ColumnRot指定旋转后的图像的中心点坐标,但在这里它们没有被使用,因为最后一个参数0表示不使用这些值。
vector_angle_to_rigid (RowTempl, ColumnTempl, PhiTempl, RowRot, ColumnRot, 0, HomMat2DRotate)
*使用上一步得到的仿射变换矩阵HomMat2DRotate来变换图像,生成图像ImageAffineTrans,插值方法为'constant',
*false表示输出图像与输入图像大小相同,可能会发生剪切
affine_trans_image (ImageTempl, ImageAffineTrans, HomMat2DRotate, 'constant', 'false')
if (VisUndefPixelBlack == 1)
    *输出包含原始图像ImageAffineTrans的完整定义域的图像ImageFull
    full_domain (ImageAffineTrans, ImageFull)
    dev_set_window (WindowRot)
    dev_display (ImageFull)
else
    dev_set_window (WindowRot)
    dev_display (ImageAffineTrans)
endif
dev_set_window (WindowID)
*显示原始图像
dev_display (ImageTempl)
disp_message (WindowID, 'run the template matching', 'image', 20, 20, 'yellow', 'false')
disp_message (WindowID, 'run the template matching', 'image', 20, 20, 'yellow', 'false')
disp_message (WindowID, '(click left to start,', 'image', 50, 20, 'yellow', 'false')
disp_message (WindowID, 'right to stop)', 'image', 80, 20, 'yellow', 'false')
* disp_continue_message (WindowID, 'black', 'true')
* stop ()
*等待用户左键开始
Button := 0
while (Button != 1)
    *获取鼠标状态,左键按下时跳出循环
    get_mbutton (WindowID, dummy, dummy, Button)
endwhile
dev_update_pc ('off')
* ------------------------
* shape-based matching
*基于形状的匹配
* ------------------------
Button := 0
Exp := 1
while (Button != 4)
    if (online)
        grab_image_async (Image, AcqHandle, -1)
    else
        grab_image (Image, AcqHandle)
    endif
    *记录开始时间
    count_seconds (Seconds1)
    *在Image中搜索ModelID,匹配搜索范围为0-360,达到0.7才能被视为模型实例,返回一个最佳匹配,找到的目标
    *重叠,且重叠大于0.5时选择一个好的输出,计算精度:'least_squares',搜索时金字塔层数为0,贪婪度设置为0.7
    *输出匹配位置的坐标、角度、得分
    find_shape_model (Image, ModelID, 0, rad(360), 0.7, 1, 0.5, 'least_squares', 0, 0.7, Row, Column, Angle, Score)
    if (Score > 0.5)
        *生成一个旋转矩形形状,其属性存储在变量Rectangle中。
        gen_rectangle2 (Rectangle, Row, Column, PhiTempl + Angle, Length1, Length2)
        reduce_domain (Image, Rectangle, ImageReduced)
        intensity (ImageReduced, Image, Mean, Deviation)
        * Compensate for rotation and translation
        *补偿旋转和位移
        *将一个旋转中心(Row, Column)和旋转角度PhiTempl转换为一个仿射变换矩阵HomMat2DRotate。这个矩阵将用于后续的图像变换。
        *参数RowRot和ColumnRot指定旋转后的图像的中心点坐标,但在这里它们没有被使用,因为最后一个参数0表示不使用这些值。
        vector_angle_to_rigid (Row, Column, Angle, RowRot, ColumnRot, 0, HomMat2DRotate)
        *使用上一步得到的仿射变换矩阵HomMat2DRotate来变换图像,生成图像ImageAffineTrans,插值方法为'constant',
        *false表示输出图像与输入图像大小相同,可能会发生剪切
        affine_trans_image (Image, ImageAffineTrans, HomMat2DRotate, 'constant', 'false')
        *记录结束时间
        count_seconds (Seconds2)
        Time := round(1000 * (Seconds2 - Seconds1))
        if (VisUndefPixelBlack == 1)
            *将ImageAffineTrans全部显示在ImageFull里
            full_domain (ImageAffineTrans, ImageFull)
            *显示匹配的结果
            dev_set_window (WindowRot)
            dev_display (ImageFull)
        else
            dev_set_window (WindowRot)
            dev_display (ImageAffineTrans)
        endif
        *显示原图
        dev_set_window (WindowID)
        dev_display (Image)
        disp_message (WindowID, Time + ' ms', 'window', 12, 12, 'black', 'true')
        dev_set_color ('green')
        dev_display (Rectangle)
    else
        dev_display (Image)
    endif
    * --------------------------
    * Exit with mouse click
    *检测鼠标点击以退出循环
    * --------------------------
    *保存当前的错误变量状态到变量Error中
    dev_error_var (Error, 1)
    *禁用错误检查。这样可以确保接下来的操作不会因为错误而中断程序
    dev_set_check ('~give_error')
    *获取鼠标在窗口WindowID中的位置(行R和列C)以及点击状态Button。
    get_mposition (WindowID, R, C, Button)
    *恢复之前保存的错误变量状态。
    dev_error_var (Error, 0)
    *恢复错误检查。这样可以确保后续操作中如果发生错误,会正常抛出错误。
    dev_set_check ('give_error')
    *检查是否发生错误。如果Error不等于H_MSG_TRUE,表示获取鼠标位置时发生了错误鼠标置0
    if (Error != H_MSG_TRUE)
        Button := 0
    endif
endwhile
disp_continue_message (WindowID, 'black', 'true')
stop ()
close_framegrabber (AcqHandle)
dev_set_window (WindowRot)
dev_close_window ()
dev_update_pc ('on')
dev_update_var ('on')
dev_update_time ('on')
dev_update_window ('on')
dev_disp_text ('      End of program      ', 'window', 'bottom', 'right', 'black', [], [])

 使用到的主要相关算子详解:

 create_shape_model 中的参数及用法参考文章:Halcon算子—create_shape_model参数解析及优化_create shape model-CSDN博客
vector_angle_to_rigid中的参数及用法参考文章:

halcon模板匹配——算子vector_angle_to_rigid和affine_trans_contour_xld_halcon的vector-CSDN博客

affine_trans_image(Image : ImageAffineTrans : HomMat2D, Interpolation, AdaptImageSize : )

Image:输入的图片

ImageAffineTrans:变换后输出的图片

HomMat2D:仿射变换矩阵

Interpolation:要选择的插值方法。

AdaptImageSize:控制输出图片的大小,设为true则表示将调整图像大小,使右边或下边不发生剪切;设为false则表示目标图像将与输入图像大小相同,超出的位置会被自动剪切。其中

其中插值主要可选的方法有:

nearest_neighbor:最近邻插值: 根据最近像素的灰度值确定灰度值(可能质量较低,但速度很快)。

bilinear:双线性插值。灰度值是通过双线性插值法从四个最近的像素确定的。如果仿射变换包含比例因子小于 1 的缩放,则不会执行平滑处理,这可能会导致严重的混叠效应(中等质量和运行时间)。

bicubic:双三次插值。灰度值通过双三次插值从最近的像素确定。如果仿射变换包含比例因子小于 1 的缩放,则不执行平滑处理,这可能会导致严重的混叠效果(放大质量高,运行速度慢)。

constant:双线性插值。灰度值是通过双线性插值从最近的四个像素中确定的。如果仿射变换包含比例系数小于 1 的缩放,则会使用一种平均值滤波器来防止混叠效应(中等质量,运行时间长)。

weighted:双线性插值。灰度值是通过双线性插值从四个最近的像素确定的。如果仿射变换包含比例系数小于 1 的缩放,则会使用一种高斯滤波器来防止混叠效应(高质 量,慢速)

find_shape_model中的参数及用法参考文章:

[Halcon&算子] find_shape_model()详解和解决匹配函数耗时问题_findshapemodel-CSDN博客

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值