Emgu 模板匹配函数MatchTemplate理解

简介
最近做一个识别护照护照号码OCR的项目,需要识别一张图像的护照号码,每张图片的号码的位置有些变化,这样就不好截取护照号码的图像,好在护照号码的以“ED”开头,长度,宽度固定.于是可以使用Emgu的模板匹配函数MatchTemplate来匹配字符串“ED”,以确定护照号码的开始位置,截取图片,然后使用Tesseract OCR来识别截取的图片中的护照号码.

MatchTemplate接口:
void MatchTemplate(IInputArray image, IInputArray templ, IOutputArray result, TemplateMatchingType method, IInputArray mask = null);
参数解释:
image-被匹配的图像矩阵(W*H)
templ-模板图像矩阵(w*h)
result-匹配结果矩阵((W-w)(H-h)):templ图像和image的卷积即temp在image图像上面从左到右,从上往下滑动,所以矩阵的大小是((W-w)(H-h)),result矩阵存放的数据是每个位置的图像的匹配度.
method-图像的匹配度计算方法:
method=TemplateMatchingType.Sqdiff,使用平方差的方法计算匹配度,很显然匹配度越高,平方差的和就越小,如果完全匹配,则平方差的和就为0,使用MinMaxLoc计算矩阵最大 最小值的时候,需要取最小值的位置坐标.
这里写图片描述

method=TemplateMatchingType.CcorrNormed,使用归一化相关系数匹配法计算匹配度.这个公式使用使用余弦相似度计算两个图像矩阵的相似度.详情参考(https://blog.csdn.net/u012160689/article/details/15341303),所以,匹配度越高,相关系数就越大,如果完全匹配,则相关系数为1(0度夹角的余弦值为1,完全相似),使用MinMaxLoc计算矩阵最大 最小值的时候,需要取最大值的位置坐标.
这里写图片描述
- 代码

        /// <summary>
        /// 获取匹配图像的位置
        /// </summary>
        /// <param name="Src">被匹配的源图像</param>
        /// <param name="Template">模板图像</param>
        /// <returns>匹配位置</returns>
        Rectangle GetMatchPos(Mat Src,Mat Template)
        {
            Mat MatchResult = new Mat();//匹配结果
            CvInvoke.MatchTemplate(Src, Template, MatchResult, Emgu.CV.CvEnum.TemplateMatchingType.CcorrNormed);//使用相关系数法匹配
            Point max_loc = new Point();
            Point min_loc = new Point();
            double max = 0, min = 0;
            CvInvoke.MinMaxLoc(MatchResult, ref min, ref max, ref min_loc, ref max_loc);//获得极值信息
            DisplayInfo("\r\nX:" + max_loc.X + " Y:" + max_loc.Y + " 最大相似度:" + max + " 最小相似度:" + min);
            return new Rectangle(max_loc,Template.Size);
        }

运行效果:
护照号码

就这样完成了一张图片的护照号码的截取,但是有时由于翻页的机构的问题,多翻了一页,导致图片里边没有护照号码,需要提示人工翻到资料页,这时就需要使用最大相似度max判断图片是否包含护照号码,经过多个样本测试,相似度小于0.98就表示该图片里边没有护照号码,翻页机构出问题了.

猜你喜欢

转载自blog.csdn.net/a906168402/article/details/80716337