halcon模板匹配和旋转矫正

1.前言

1.1什么是模板匹配和旋转矫正

在常见的很多项目中,经常会使用手动绘制ROI的情况,但是实际产品的位置往往不是固定的,可能出现在视野上的各种地方和各种角度,所以就需要使用到旋转矫正。将产品放置在视野的中央,并且使得图像呈现出我们所需要的角度。

1.2halcon实现方式

先预先定义一个固定的带角度的矩形ROI,角度为我们所需要修正的角度的方向,然后进行生成和创建模板,然后匹配模板,并将匹配成功的横纵坐标与角度进行图像旋转即可

2.C#程序

2.1C#程序

#region // 模板匹配和旋转矫正(初始创建的ROI角度应该使用序列化参数进行保存)
/// <summary>
/// 模板匹配和旋转矫正
/// </summary>
/// <param name="image">输入图像</param>
/// <param name="NewTemplate">是否创建新模板</param>
/// <param name="Row">输入矩形ROI的横坐标</param>
/// <param name="Column">输入矩形ROI的列坐标</param>
/// <param name="Phi">输入矩形ROI的角度</param>
/// <param name="Length1">输入矩形ROI的一边长</param>
/// <param name="Length2">输入矩形ROI的一边宽</param>
/// <param name="ModelAddress">输入模板存放的位置,文件后缀为.shm</param>
/// <param name="imageAffineTrans">输出旋转后的图像</param>
/// <returns></returns>
public static bool TemplateSpin(HObject image,bool NewTemplate,
            HTuple Row,HTuple Column,HTuple Phi,HTuple Length1,HTuple Length2,string ModelAddress,
            out HObject imageAffineTrans)
{
    HOperatorSet.GenEmptyObj(out imageAffineTrans);
    try
    {
        HTuple modelID = new HTuple();
        if (NewTemplate)
        {
            Module.CreatTemplate(image, Row, Column, Phi, Length1,Length2, 0.8, 1.2, out modelID);
            HOperatorSet.TupleLength(modelID, out HTuple length);
            if (length==0)
            {
                return false;
            }
            HOperatorSet.WriteShapeModel(modelID, ModelAddress);
        }
        else
        {
            if (!System.IO.File.Exists(ModelAddress))
            {
                return false;
            }
            HOperatorSet.ReadShapeModel(ModelAddress, out modelID);
        }
        Module.FindTemplate(image, modelID, 0.3, out HTuple resultRow, out HTuple resultCloumn, out HTuple resultAngle, out HTuple resultScore);
        HOperatorSet.TupleLength(resultRow, out HTuple length1);
        if (length1==0)
        {
            return false;
        }
        HOperatorSet.GetImageSize(image, out HTuple width, out HTuple height);
        HOperatorSet.VectorAngleToRigid(resultRow, resultCloumn, resultAngle+Phi, height/2, width/2 ,  0, out HTuple homMat2D);
        HOperatorSet.AffineTransImage(image, out imageAffineTrans, homMat2D, new HTuple("constant"), new HTuple("false"));
        return true;
    }
    catch (Exception)
    {
        return false;
    }
}

#endregion

    #region // 模板匹配
    

    /// <summary>
    /// 查找模板
    /// </summary>
    /// <param name=“Image”>输入图像</param>
    /// <param name=“ModelID”>输入模板</param>
    /// <param name=“MinScore”>输入最小匹配分数</param>
    /// <param name=“ResultRow”>输出匹配中心的横坐标</param>
    /// <param name=“ResultCloumn”>输出匹配中心列坐标</param>
    /// <param name=“ResultAngle”>输出匹配模型角度</param>
    /// <param name=“ResultScore”>输出匹配分数</param>
    /// <returns>匹配成功返回true,匹配失败返回false</returns>
    static public bool FindTemplate(HObject Image, HTuple ModelID, HTuple MinScore, out HTuple ResultRow, out HTuple ResultCloumn,
    out HTuple ResultAngle, out HTuple ResultScore)
    {
    ResultRow = -1;
    ResultCloumn = -1;
    ResultAngle = -1;
    ResultScore = -1;
    try
    {
    HOperatorSet.GetShapeModelParams(ModelID, out HTuple numLevels, out HTuple angleStart, out HTuple angleExtent,
    out HTuple angleStep, out HTuple scaleMin, out HTuple scaleMax, out HTuple scaleStep, out HTuple metric,
    out HTuple minContrast);
    HOperatorSet.FindScaledShapeModel(Image, ModelID, angleStart, angleExtent, scaleMin, scaleMax, MinScore, new HTuple(1),
    new HTuple(0.5), new HTuple(“least_squares”), numLevels, new HTuple(0.9), out ResultRow, out ResultCloumn,
    out ResultAngle, out HTuple Scale, out ResultScore);
    HOperatorSet.TupleLength(ResultScore,out HTuple length);
    if (length > 0)
    {
    return true;
    }
    else { return false; }

    <span class="token punctuation">}</span>
    <span class="token keyword">catch</span> <span class="token punctuation">(</span><span class="token class-name">Exception</span> ex<span class="token punctuation">)</span>
    <span class="token punctuation">{<!-- --></span>
        <span class="token keyword">return</span> <span class="token boolean">false</span><span class="token punctuation">;</span>
    <span class="token punctuation">}</span>
    

    }

    /// <summary>
    /// 创建模板
    /// </summary>
    /// <param name=“Image”>输入图像</param>
    /// <param name=“Row”>矩形中心横坐标</param>
    /// <param name=“Column”>矩形中心列坐标</param>
    /// <param name=“Phi”>矩形ROI角度</param>
    /// <param name=“Length1”>矩形一条边的长</param>
    /// <param name=“Length2”>矩形另一条边的长</param>
    /// <param name=“ScaledMin”>模板最小缩放比例</param>
    /// <param name=“SacledMax”>模板最大缩放比例</param>
    /// <param name=“ModelID”>输出模板</param>
    /// <returns>创建成功返回true,创建失败返回false</returns>
    static public bool CreatTemplate(HObject Image, HTuple Row, HTuple Column, HTuple Phi,
    HTuple Length1, HTuple Length2, HTuple ScaledMin, HTuple SacledMax, out HTuple ModelID)
    {
    ModelID = -1;
    try
    {
    HOperatorSet.GenRectangle2(out HObject ROI, Row, Column, Phi, Length1, Length2);
    HOperatorSet.ReduceDomain(Image, ROI, out HObject imageReduced);
    HOperatorSet.CreateScaledShapeModel(imageReduced, 8, (new HTuple(0)).TupleRad(), (new HTuple(360)).TupleRad(), new HTuple(“auto”),
    ScaledMin, SacledMax, new HTuple(“auto”), new HTuple(“none”), new HTuple(“ignore_global_polarity”), new HTuple(“auto”),
    new HTuple(“auto”), out ModelID);
    HOperatorSet.TupleLength(ModelID, out HTuple length);
    if (length==0)
    {
    return false;
    }
    return true;
    }
    catch (Exception ex)
    {
    return false;
    }

    }
    #endregion

      3.测试过程

      在这里插入图片描述
      在这里插入图片描述

      4.总结

      实际上模板匹配和旋转矫正时非常简单的事情。需要在旋转矫正时加上预先设定的ROI角度即可。

      转载自:https://blog.csdn.net/m0_51559565/article/details/136698905
      • 0
        点赞
      • 0
        收藏
        觉得还不错? 一键收藏
      • 0
        评论
      评论
      添加红包

      请填写红包祝福语或标题

      红包个数最小为10个

      红包金额最低5元

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

      抵扣说明:

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

      余额充值