模板匹配NCC

公式

c++代码实现

只做了一层,速度非常慢
需要加速的话,采用金字塔策略
因为太慢了所以自己划了个roi

/*
 * Created by Xinyu-Lee on 2020/4/19
 * 模板匹配NCC算法
 * 原理:
 * 1.相似数值计算:pattern 与测试图片的归一化后相似度量向量内积的绝对值
 * 2.pattern遍历图像找到相似数值最大处
 */
#include<opencv2/opencv.hpp>
#include <iostream>
#include <ctime>
using namespace cv;
using namespace std;
int main() {
    clock_t startTime,endTime;
    startTime = clock();//计时开始
    Mat pattern = imread("/home/xylee/Images/pattern.bmp",1);
    Mat src = imread("/home/xylee/Images/IMAGEB28.bmp",1);
    src =  src(Rect(320,200,320,240)).clone();
    //  算出pattern的平均值和平方差
    int p_height = pattern.rows;
    int p_width = pattern.cols;
    int image_height= src.rows;
    int image_width = src.cols;
    int p_mean, p_variance = 0;
    int pn = p_height * p_width;
    double sum = 0;
    //计算pattern所有像素灰度值的平均值
    for (int i = 0; i < p_width; ++i) {
        for (int j = 0; j < p_height; ++j) {
            sum += pattern.ptr<uchar>(j)[i];
        }
    }
    p_mean = sum / pn;
    //计算pattern的平方差
    for (int i = 0; i < p_width; ++i) {
        for (int j = 0; j < p_height; ++j) {
            int temp = pattern.ptr<uchar>(j)[i];
            p_variance += pow((temp - p_mean),2);
        }
    }
    p_variance = sqrt(p_variance/pn);
    //找到相似度最大的中心点坐标
    int x, y;

    double result, max = 0;
    int mx = 0, my = 0;
    double sum1,sum2,mean,variance;
    for (x = 0; x < image_width-p_width+1; ++x) {
        for (y = 0; y < image_height - p_height + 1; ++y) {
            sum1 = 0,variance = 0,sum2 = 0;
            for (int i = 0; i < p_width; ++i) {
                for (int j = 0; j < p_height; ++j) {
                    int temp = *src.ptr(y+j,x+i );
                    sum1 += temp;
                }
            }
            mean = sum1/pn;//求平均值
            for (int i = 0; i < p_width; ++i) {
                for (int j = 0; j < p_height; ++j) {
                    int temp = *src.ptr(y+j,x+i);
                    variance += pow(temp-mean,2);
                }
            }
            variance =sqrt(variance/pn);
            for (int i = 0; i < p_width; ++i) {
                for (int j = 0; j < p_height; ++j) {
                    int temp1 = *src.ptr(y+j,x+i);
                    int temp2 = *pattern.ptr(j,i);
                    sum2 +=(temp1 - mean) *(temp2 - p_mean)/variance;
                }
            }
            result = abs(sum2/pn/p_variance);
            if (result > max) {
                max = result;
                mx = x;
                my = y;
            }
        }
    }
    cout << mx+320<< " " << my+200 << endl;
    rectangle(src,Point(mx,my),Point(mx+p_width,my+p_height),Scalar(0,20,100),2);
    imshow("result", src);
    endTime = clock();//计时结束
    cout << "The run time is: " <<(double)(endTime - startTime) / CLOCKS_PER_SEC << "s" << endl;
    waitKey(0);
    return 0;
}

结果

pattern:

src:

)

posted @ 2020-04-30 15:08  XinyuLee  阅读(2017)  评论(0编辑  收藏  举报