Halcon 应用仿射变换

应用仿射变换

affine_trans_image

作用​:将任意仿射变换矩阵(如刚性、缩放、错切)作用到图像(Image)上,生成变换后的新图像。
算子签名:affine_trans_image( Image : ImageAffinTrans : HomMat2D, Interpolation, AdaptImageSize : )

  • 输入参数:
    • Image(输入对象): 原始输入图像
  • 输出参数:
    • ImageAffineTrans(输出对象):变换后的输出图像。
  • 控制参数:
    • HomMat2D (输入控制): 仿射变换矩阵
    • Interpolation (输入控制):插值方式(如 'bilinear', 'constant')
    • AdaptImageSize(输入控制):是否自动调整输出图像尺寸('true'/'false')
方法 插值质量 速度 抗锯齿效果(缩放<1) 适用方法
nearest_neighbor 最低 极快 二值图像/实时
bilinear 标准中等(放大优) 通用变换
bicubic 最高(放大优) ❌ 无 高质量放大
constant 中等 中等 ✅ 均值滤波 抗锯齿缩小
weighted 最高(缩小优) 最慢 ✅ 高斯滤波 高质量缩小

AdaptImageSize = 'false'(默认)

  • 输出图像尺寸​​ 保持与原图相同
  • 超出原图边界的变换部分会被​ ​裁剪​​
  • 变换后空白区域用Grayval参数填充(默认为0)
  • 坐标系不变

AdaptImageSize = 'true'

  • 输出图像尺寸​​自动调整​​以完整包含变换后图像
  • 原图所有数据均保留(无裁剪)
  • 坐标系原点仍为(0,0),但图像宽高扩展
  • 原点移至新左上角
Hobject imgIn, imgOut;
affine_trans_image(imgIn, &imgOut, homMat, "bilinear", "true");
// 输出图像尺寸自动适配变换结果

affine_trans_region

作用​:将仿射变换矩阵作用到区域(Region)上,生成变换后的新区域。
算子签名:affine_trans_region( Regions : RegionAffineTrans : HomMat2D, Interpolate)

  • 输入参数:
    • Region(输入对象):输入区域(ROI)元组
  • 输出参数:
    • RegionAffineTrans(输出对象):变换后的输出区域元组。
  • 控制参数:
    • HomMat2D (输入控制): 仿射变换矩阵
    • Interpolation (输入控制):插值方式(如 'bilinear', 'constant')
Hobject regionIn, regionOut;
affine_trans_region(regionIn, &regionOut, homMat, "nearest_neighbor");
// 区域变换使用最近邻插值

affine_trans_contour_xld

作用​:处理亚像素精度的XLD轮廓(如边缘检测结果),保持原始精度。
算子签名:affine_trans_contour_xld(Contours : ContoursAffineTrans : HomMat2D)

  • 输入参数:
    • Contours(输入对象):输入轮廓(XLD)元组
  • 输出参数:
    • ContoursAffineTrans(输出对象):变换后的输出轮廓元组。
  • 控制参数:
    • HomMat2D (输入控制): 仿射变换矩阵
Hobject contoursIn, contoursOut;
affine_trans_contour_xld(contoursIn, &contoursOut, homMat);
// 轮廓变换保持原始精度

模板匹配

create_shape_model

作用:形状匹配模板创建的核心算子,基于输入图像的特征生成一个可用于后续匹配的模型
算子签名:create_shape_model(Template : : NumLevels, AngleStart, AngleExtent, AngleStep, Optimization, Metric, Contrast, MinContrast : ModelID)

  • 输入参数:

    • TemplateImage(输入对象):输入区域(Image)
  • 输出参数:

    • ModelID(输出对象):模型句柄
  • 控制参数:

    • NumLevels(输入控制):金字塔层数

    • AngleStart (输入控制):起始角度

    • AngleExtent(输入控制):角度范围

    • AngleStep(输入控制):角度步长("auto":Halcon 自动计算最优步长(推荐)

    • Optimization(输入控制):优化选项,减少模型内存占用并加速匹配,"auto"自动平衡

    • Metric(输入控制):控制匹配时如何处理图像边缘的灰度值极性,'use_polarity' (最严格模式)

    • Contrast(输入控制):对比度参数 特征点选择的梯度阈值,创建模型时,边缘梯度>=此值的点才会被纳入模型

    • MinContrast(输入控制):最小对比度,匹配时,图像边缘梯度>=此值才参与计算,MinContrast = max(10, 图像平均梯度 × 0.3)

    说明
    'use_polarity' 最严格模式:图像边缘明暗变化必须与模板完全一致
    'ignore_global_polarity' 忽略整体明暗反转:允许亮变暗/暗变亮的全局翻转
    'ignore_local_polarity' 忽略局部明暗反转:允许部分区域的明暗关系翻转
    'ignore_color_polarity' 彩色图像专用:允许单个颜色通道的极性翻转
// 必须是单通道灰度图像
HalconCpp::HObject imgGray = origImage.ConvertImageType("byte");
// 推荐使用 reduce_domain 裁剪出精确 ROI 区域
HalconCpp::HObject roi = imgGray.ReduceDomain(selectedROI);	 
HalconCpp::HTuple modelID;
CreateShapeModel(roi, ... , &modelID);

create_scaled_shape_model

作用:用于创建支持缩放的形状匹配模型

算子签名:create_scaled_shape_model(Template : : NumLevels, AngleStart, AngleExtent, AngleStep, ScaleMin, ScaleMax, ScaleStep, Optimization, Metric, Contrast, MinContrast : ModelID)

  • 输入参数:
    • Template(输入对象):区域图像(Image)
  • 输出参数:
    • ModelID(输出对象):模型句柄
  • 输入控制:
    • NumLevels(输入控制):金字塔层数

    • AngleStart (输入控制):起始角度

    • AngleExtent(输入控制):角度范围

    • AngleStep(输入控制):角度步长("auto":Halcon 自动计算最优步长(推荐)

    • ScaleMin(输入控制): 最小缩放比

    • ScaleMax(输入控制): 最大缩放比

    • ScaleStep(输入控制):缩放步长,设定缩放维度上的采样精度"auto":Halcon自动计算最优步长

    • Optimization(输入控制):优化选项,减少模型内存占用并加速匹配,"auto"自动平衡

    • Metric(输入控制):控制匹配时如何处理图像边缘的灰度值极性,'use_polarity' (最严格模式)

    • Contrast(输入控制):对比度参数 特征点选择的梯度阈值,创建模型时,边缘梯度>=此值的点才会被纳入模型

    • MinContrast(输入控制):最小对比度,匹配时,图像边缘梯度>=此值才参与计算,MinContrast = max(10, 图像平均梯度 × 0.3)

Optimization 优化选项:

优化选项 处理方式 内存占用 创建速度 匹配速度
"auto" 自动选择最优策略,推荐 中等 中等
"none" 无优化,完整生成所有变体 最高 最慢 最快
"no_pregeneration" 不预生成变换模型 最低 最快 最慢
"point_reduction_low" 轻度减少模型点数 较高 较慢 最高
"point_reduction_medium" 中度减少模型点数 中等 中等
"point_reduction_high" 高度减少模型点数 中等
"pregeneration" 预生成所有变换模型 最高 最慢 最快
// 最佳实践:提取精确ROI区域
HalconCpp::HObject roi = image.ReduceDomain(regionOfInterest);
HalconCpp::Emphasize(roi, &roiEnhanced, 7, 7, 1.5);  // 增强边缘对比度
HalconCpp::CreateScaledShapeModel(
    templateROI,           // 精确裁剪的ROI区域
    "auto",                 // 自动金字塔层级
    rad(-30), rad(60),      // ±30°旋转范围
    "auto",                 // 自动角度步进
    0.8, 1.2,               // 80%~120%缩放范围
    "auto",                 // 自动缩放步进
    "point_reduction_medium",// 中等优化
    "ignore_global_polarity",// 忽略全局明暗反转
    "auto",                 // 自动对比度阈值
    8,                      // 最小对比度
    &modelID
);
  • 清理资源:clear_shape_model (ModelID)

create_ncc_model

作用:创建基于​​归一化互相关​​的匹配模型,适用于光照变化但无几何形变的场景。匹配时通过计算图像与模板的归一化互相关值来定位目标。

算子签名:create_ncc_model(Template : : NumLevels, AngleStart, AngleExtent, AngleStep, Metric: ModelID)

  • 输入参数:

    • Template(输入对象):模板图像(灰度图像)
  • 输出参数:

    • ModelID(输出对象):模型句柄
  • 输入控制:

    • NumLevels(输入控制):金字塔层数

    • AngleStart (输入控制):起始角度

    • AngleExtent(输入控制):角度范围

    • AngleStep(输入控制):角度步长("auto":Halcon 自动计算最优步长(推荐)

    • Metric(输入控制):控制匹配时如何处理图像边缘的灰度值极性,'use_polarity' (最严格模式),'ignore_global_polarity'

  • 清理资源:clear_ncc_model (ModelID)

find_shape_model 基础形状匹配

作用:在输入图像中搜索模板,返回匹配结果。

算子签名:find_shape_model(Image : : ModelID, AngleStart, AngleExtent, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness : Row, Column, Angle, Score)

  • 输入参数:
    • Image(输入对象):待匹配图像(灰度图像)
    • ModelID(输入对象):模板模型句柄
  • 输入控制:
    • AngleStart (输入控制):起始角度
    • AngleExtent(输入控制):角度范围
    • MinScore(输入控制):最小匹配得分
    • NumMatches(输入控制):最大匹配数
    • MaxOverlap(输入控制):最大重叠度
    • subPixel(输入控制):是否使用亚像素精度
    • NumLevels(输入控制):金字塔层数
    • Greediness(输入控制):搜索策略,0~1,越大越保守,越小越宽松,0:完全随机搜索,1:完全全局搜索
  • 输出参数:
    • Row(输出对象):匹配结果的行坐标
    • Column(输出对象):匹配结果的列坐标
    • Angle(输出对象):匹配结果的旋转角度
    • Score(输出对象):匹配结果的得分

find_scaled_shape_model 可缩放形状匹配

作用:在输入图像中搜索模板,返回匹配结果。
算子签名:find_scaled_shape_model(Image : : ModelID, AngleStart, AngleExtent, ScaleMin, ScaleMax, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels, Greediness : Row, Column, Angle, Scale, Score)

  • 输入参数:
    • Image(输入对象):待匹配图像(灰度图像)
    • ModelID(输入对象):模板模型句柄
  • 输入控制:
    • AngleStart (输入控制):起始角度
    • AngleExtent(输入控制):角度范围
    • ScaleMin(输入控制): 最小缩放比
    • ScaleMax(输入控制): 最大缩放比
    • MinScore(输入控制):最小匹配得分
    • NumMatches(输入控制):最大匹配数
    • MaxOverlap(输入控制):最大重叠度
    • SubPixel(输入控制):是否使用亚像素精度(拥有众多选项,推荐使用'least_squares'
    • NumLevels(输入控制):金字塔层数
    • Greediness(输入控制):搜索策略,0~1,越大越保守,越小越宽松,0:完全随机搜索,1:完全全局搜索
  • 输出参数:
    • Row(输出对象):匹配结果的行坐标
    • Column(输出对象):匹配结果的列坐标
    • Angle(输出对象):匹配结果的旋转角度
    • Scale(输出对象):匹配结果的缩放比例
    • Score(输出对象):匹配结果的得分

find_ncc_model 灰度模板匹配

作用:在输入图像中搜索灰度模板,返回匹配结果。
算子签名:find_ncc_model(Image : : ModelID, AngleStart, AngleExtent, MinScore, NumMatches, MaxOverlap, SubPixel, NumLevels : Row, Column, Angle, Score)

  • 输入参数:
    • Image(输入对象):待匹配图像(灰度图像)
    • ModelID(输入对象):模板模型句柄
  • 输入控制:
    • AngleStart (输入控制):起始角度
    • AngleExtent(输入控制):角度范围
    • MinScore(输入控制):最小匹配得分
    • NumMatches(输入控制):最大匹配数
    • MaxOverlap(输入控制):最大重叠度
    • SubPixel(输入控制):是否使用亚像素精度(只有true和false)
    • NumLevels(输入控制):金字塔层数
  • 输出参数:
    • Row(输出对象):匹配结果的行坐标
    • Column(输出对象):匹配结果的列坐标
    • Angle(输出对象):匹配结果的旋转角度
    • Score(输出对象):匹配结果的得分

SubPixel参数在匹配中的作用

  • 'none'(或'false'):不使用亚像素精度,仅使用整数坐标
  • 'interpolation'(或'true'):插值亚像素,对分数函数插值
  • 'least_squares':使用最小二乘法拟合,精度高,但速度慢
  • 'least_squares_high':高精度最小二乘法拟合,速度慢,但精度高

inspect_shape_model 特征检查

作用:存储了从模板图像中提取的关键特征信息(主要是边缘或轮廓及其梯度方向),并根据设定的金字塔层级(NumLevels)构建了多尺度表示。

算子签名:inspect_shape_model(Image : ModelImages, ModelRegions : NumLevels, Contrast:)

  • 输入参数:
    • Image(输入对象):模板图像(灰度图像)
  • 输出参数:
    • ModelImages(输出对象) :输出的模型可视化图像,图像元组,每个元素对应一个有效的金字塔层级(从最低分辨率/最高层级开始)
    • ModelRegions(输出对象):输出的模型区域,区域元组,每个元素对应一个有效的金字塔层级,模型特征所覆盖的范围。
  • 输入控制:
    • NumLevels(输入控制):金字塔层数,这个参数必须与之前调用 create_shape_model 时使用的 NumLevels 参数完全一致。它告诉算子要生成多少个层级的可视化结果
    • Contrast(输入控制):对比度阈值,这个参数必须与之前调用 create_shape_model 时使用的 Contrast 参数(或 MinContrast)完全一致。它决定了哪些边缘梯度强度的点会被纳入模型。可视化结果直接反映了这个阈值的效果。

如何使用inspect_shape_model?

  • 创建形状模型: 首先,使用 create_shape_model 或 create_scaled_shape_model 等算子创建你的形状模型 (ModelID),并指定好 NumLevels 和 Contrast 参数。
read_image(Image, 'part_template.png')
// 定义ROI (Region of Interest)
gen_rectangle1(Rectangle, 100, 100, 300, 400)
reduce_domain(Image, Rectangle, TemplateImage)
// 创建模型,假设使用默认参数的一部分
create_shape_model(TemplateImage, 'auto', -0.39, 0.79, 'auto', 'auto', 'use_polarity', 'auto', 'auto', ModelID)
// 获取创建模型时实际使用的参数(可选,但推荐)
get_shape_model_params(ModelID, 'num_levels', UsedNumLevels)
get_shape_model_params(ModelID, 'contrast', UsedContrast)
  • 调用 inspect_shape_model: 使用创建模型时用的原始模板图像和完全相同的 NumLevels 和 Contrast 参数值。
// 使用原始模板图像和创建时记录的参数
inspect_shape_model(TemplateImage, ModelImages, ModelRegions, UsedNumLevels, UsedContrast)

get_shape_model_origin

作用:获取形状模型的参考点(原点)坐标。
算子签名:get_shape_model_origin(ModelID : Row, Column)

  • 输入参数:
    • ModelID(输入对象):模板模型句柄
  • 输出参数:
    • Row(输出对象):模型参考点的行坐标
    • Column(输出对象):模型参考点的列坐标

当你使用 find_shape_model 找到目标时,返回的位置 (Row, Column) 就是模型参考点在搜索图像中的坐标位置。
模型的所有内部表示(特征点、轮廓)的位置都是相对于这个参考点定义的。
变换轮廓: 当配合 get_shape_model_contours 获取模型轮廓时,需要知道参考点才能将这些轮廓(定义在模型坐标系中)正确地变换到搜索图像中的实际位置。

get_shape_model_contours

作用:获取形状模型的轮廓。
算子签名:get_shape_model_contours(Contours : ModelID, NumLevels)

  • 输入参数:
    • ModelID(输入对象):模板模型句柄
    • NumLevels(输入控制):金字塔层数
  • 输出参数:
    • Contours(输出对象):模型轮廓,轮廓元组,每个元素对应一个有效的金字塔层级,每个轮廓包含多个点,每个点包含两个坐标值。

可视化匹配结果:
在 find_shape_model 找到目标后,你可以获取模型轮廓,然后根据匹配到的位姿(位置 Row, Column 和角度 Angle)将这个轮廓变换到搜索图像上并绘制出来

案例展示

对模版进行匹配并展示匹配结果

// 读取图像
read_image (EraserFind, 'C:/Users/Administrator/Desktop/test/Eraser_Find.jpg')

// 初始特征检查(可选)
inspect_shape_model (EraserFind, ModelImages, ModelRegions, 1, 60)

// --- 1. 定义橡皮擦区域 ---
gen_rectangle1 (ROI_0, 1491.71, 1793.4, 1518.99, 1812.65)
gen_rectangle1 (TMP_Region, 1495.66, 776.635, 1503.63, 788.972)
union2 (ROI_0, TMP_Region, ROI)

// --- 2. 创建掩膜区域 ---
get_domain (EraserFind, Domain)
difference (Domain, ROI, RegionDifference)  // 从全图减去橡皮擦区域
reduce_domain (EraserFind, RegionDifference, ImageReduced)  // 限制图像域

// --- 3. 创建模板 ---
// 可选:检查掩膜后的特征
inspect_shape_model (ImageReduced, \
                     ModelImages1, ModelRegions1, 1, 60)
// 创建形状模板
create_shape_model (ImageReduced, 'auto', \
                    -0.39, 0.79, 'auto', 'auto', 'use_polarity', 80, 60, ModelID)

// 创建模型后获取实际参考点
get_shape_model_origin (ModelID, ModelOriginRow, ModelOriginCol)

// 获取模板轮廓(在模型坐标系下)
get_shape_model_contours (ModelContours, ModelID, 1)

// 循环读图片并搜索模板
list_files ('C:/Users/Administrator/Desktop/test', ['files','follow_links'], ImageFiles)
tuple_regexp_select (ImageFiles, ['\\.(tif|tiff|gif|bmp|jpg|jpeg|jp2|png|pcx|pgm|ppm|pbm|xwd|ima|hobj)$','ignore_case'], ImageFiles)
for Index := 0 to |ImageFiles| - 1 by 1
    read_image (Image, ImageFiles[Index])
    
    // 在掩膜图像上搜索模板 ---
    find_shape_model (Image, ModelID, -0.39, 0.78, 0.3, 1, 0.5, 
    'least_squares', 0, 0.9, Row, Column, Angle, Score)
    
    // 对每个匹配实例
    for i := 0 to |Score|-1 by 1     
        // 计算从模型原点(0,0)到匹配位置(Row,Column)的变换矩阵
        vector_angle_to_rigid (ModelOriginRow, ModelOriginCol, 0, Row, Column, Angle, HomMat2D)
        
        // 将模板轮廓变换到匹配位置
        affine_trans_contour_xld (ModelContours, ContoursAffinTrans, HomMat2D)
    endfor
endfor

注意事项

  • 在创建仿射变换矩阵时,如果参考点不对时,会导致轮廓匹配的位置出现偏差
  • 如何确定参考点?
    • Halcon的默认行为:当没有显示设置参考点时,create_shape_model 会自动选择图像域中心设置为(0,0)
    • 存在一定的风险,因此可以显式地获取参考点信息,并在后续操作中使用
    • 参考点信息可以通过 get_shape_model_origin 获取
posted @ 2025-09-03 14:04  一楼二栋  阅读(20)  评论(0)    收藏  举报