学习template算法以及其加速原理

学习template算法(template matching)以及其加速原理

参考https://en.wikipedia.org/wiki/Template_matching#Examples_of_Use

如果模板图像具有很强的特征,则可以考虑基于特征的方法。

而对于没有强特征的模板,或者当模板图像的大部分构成匹配图像时,基于模板的方法可能是有效的:

一、Template-based approach

由于基于模板的模板匹配可能潜在地需要对大量点进行采样,可以通过将搜索和模板图像的分辨率resolution,降低相同的比例factor,并对所得结果执行操作,来减少采样点的数量。生成的缩小后的downsized图像(多分辨率mutilresolution或金字塔pyramid),提供搜索图像内的数据点的搜索窗口,使得模板不必搜索每个可行的数据点。

二、运动跟踪与遮挡处理Motion tracking and occlusion handling

在模板可能不提供直接匹配的情况下,实现特征空间eigenspaces的使用可能是有用的,特征空间是在许多不同条件下详细描述匹配对象的模板,例如不同的透视图、照明、颜色对比或可接受的匹配对象姿态。例如,如果用户正在寻找面部,则特征空间可以包括在照相机的不同位置、在不同照明条件或具有不同表达的面部的图像(模板)。

匹配图像也可能被对象遮挡或遮挡;在这些情况下,提供多个模板来覆盖每个可能的遮挡是不合理的。例如,搜索图像可以是扑克牌,并且在一些搜索图像中,卡被拿着卡的人的手指、或者被上面的另一张卡或者相机前面的任何物体遮挡。在物体可延展或可姿态的情况下,运动也成为一个问题,并且涉及运动和遮挡的问题变得模糊。【8】在这些情况下,一种可能的解决方案是将模板图像分割成多个子图像,并在每个细分上执行匹配。

三、基于互相关cross correlation或绝对差和sum of absolute differences解释的基于模板的匹配

  • (1)基于互相关cross correlation

模板匹配的基本方法使用图像补丁(模板),该图像补丁(模板)针对我们想要检测的搜索图像的特定特征而定制。
互相关输出在图像结构与掩模结构匹配的地方最高。

  1. 首先选取搜索图像的一部分作为模板。我们将搜索图像Search image称为S(x,y),其中(x,y)表示搜索图像中每个像素的坐标。我们将模板图像template称为T(x t,y
    t),其中(xt,yt)表示模板中每个像素的坐标。

  2. 然后,我们简单地将模板T(x t,y t)的中心(或原点)移动到搜索图像中的每个(x,y)点上,计算搜索图像和模板图像之间系数的乘积和。

  3. 具有最大值的位置是最佳位置。这种方法有时被称为“线性空间滤波”Linear Spatial Filtering,而模板被称为filter mask。


  • (2)基于绝对差之和sum of absolute differences

使用模板匹配处理图像平移问题的另一种方法是使用SAD(绝对差之和)度量比较像素的强度。

扫描二维码关注公众号,回复: 3116512 查看本文章

搜索图像中坐标(xs,ys)的像素具有强度Is(xs,ys),模板中具有坐标(xt,yt)的像素具有强度It(xt,yt)。

某一个(对应)像素强度的绝对差定义为微分:

Diff(xs, ys, xt, yt) = | Is(xs, ys) – It(xt, yt) |.

搜索图像坐标(x,y)处的像素和整个模板图像之间的微分和可以表示为:
这里写图片描述

在搜索图像中遍历其行、列的所有(x,y),得到若干SAD:
这里写图片描述
上面公式中,Srows和Scols分别表示搜索图像的行和列,Trows和Tcols分别表示模板图像的行和列。

在该方法中,SAD最小值给出了搜索图像中模板的最佳位置的估计。
该方法简单易行,但却是最慢的方法之一。

三、算法实现及结果

- ① opencv2.4.9标准头文件模板:

include<opencv2/core/core.hpp>
include<opencv2/highgui/highgui.hpp>
include<opencv2/imgproc/imgproc.hpp>
include<iostream>

using namespace cv;

int main(){
    Mat test_image = imread("test.jpg");
    if (image.empty())
    {
        cout << "读取图片错误" << endl;
    }
    imshow("WindowName", test_image);
    waitKey(5000);
    return 0;
}

- ② 用opencv截取图像中的一部分区域

roi_img = src_img(Range(0,100),Range(50,200));

这里截取的就是原图src_img第0行至第99行,第50列至199列的区域图像。

P.S.

注意Range的两个参数范围分别为左包含右不包含。
如果操作利用Mat方法直接赋值获取的区域图像仍然会改变原图。若想直接复制出ROI区域,需要把原始图像进行clone即可。

- ③ namedWindow函数

void cv::namedWindow(
    const String &  winname,
    int   flags = WINDOW_AUTOSIZE
)

窗口的标识,可以填如下的值:

WINDOW_NORMAL设置了这个值,用户便可以改变窗口的大小
WINDOW_AUTOSIZE如果设置了这个值,窗口大小会自动调整以适应所显示的图像,并且不能手动改变窗口大小。
WINDOW_OPENGL 如果设置了这个值的话,窗口创建的时候便会支持OpenGL。

- ④ waitKey函数

int cv::waitKey(int delay = 0)

参数:等待的时间,单位:毫秒。0表示“永远”。

这个函数用来等待,读取和处理事件。当我们没有输入,只需要窗口停留,就可以将参数设为0。

- ⑤ opencv中的图像坐标系!
坐标系的坐标原点在图像的左上角。
OpenCV中坐标体系的X轴为图像水平从左往右;Y轴为图像矩形垂直从上往下。

在Point(x,y)和Rect(x,y)中,第一个参数x代表的是元素所在图像的列数,第二个参数y代表的是元素所在图像的行数。

在使用image.at(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at(Point(x2, x1))效果相同。



用上述模板匹配方法的缺点,代码如下,不具有尺度不变形!即在目标图像中只能抠出和模板图像一样大小尺度下最相似的块,但是实际上并不是最接近模板块比例的!
参考 https://blog.csdn.net/guduruyu/article/details/69231259 中minMaxLoc的用法,结合前面的截取图像的用法,得到匹配后的图像块:

#include <iostream>  
#include <opencv2/core/core.hpp>  
#include <opencv2/imgproc/imgproc.hpp>
#include<opencv2/highgui/highgui.hpp>  
using namespace cv;    
int main()
{
    Mat image_search = imread("reference.jpg");
    Mat image_template = imread("local1.jpg");
    Mat image_matched;
    //模板匹配
    matchTemplate(image_search, image_template, image_matched, TM_CCOEFF_NORMED);

    double minVal, maxVal;
    Point minLoc, maxLoc;
    //寻找最佳匹配的位置
    minMaxLoc(image_matched, &minVal, &maxVal, &minLoc, &maxLoc);

    Mat roi_image = image_search( Range(maxLoc.y, maxLoc.y + image_template.rows + 1), Range(maxLoc.x,  maxLoc.x + image_template.cols + 1) );
    namedWindow("SearchImage", WINDOW_NORMAL);
    namedWindow("TemplateImage", WINDOW_NORMAL);
    namedWindow("Template in SearchImage", WINDOW_NORMAL);
    imshow("SearchImage", image_search);
    imshow("TemplateImage", image_template);
    imshow("Template in SearchImage",roi_image);

    waitKey(0);
    return 0;
}


emmm这里考虑简化问题,先对模板图像进行缩放操作,再来匹配。

- 缩小图像操作函数

四、加快进程

猜你喜欢

转载自blog.csdn.net/petSym/article/details/82557259
今日推荐