Halcon仿射变换如何实现效果?
摘要:应用仿射变换 affine_trans_image 作用:将任意仿射变换矩阵(如刚性、缩放、错切)作用到图像(Image)上,生成变换后的新图像。 算子签名:affine_trans_image( Image : ImageAffinTr
应用仿射变换
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, ®ionOut, 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 获取
