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, &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 获取