模板匹配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 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>(i)[j];
}
}
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>(i)[j];
p_variance += pow((temp - p_mean),2);
}
}
p_variance = sqrt(p_variance/pn);
//找到相似度最大的中心点坐标
int x, y;
int image_width = src.rows;
int image_height = src.cols;
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(x+i,y+j);
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(x+i,y+j);
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(x+i,y+j);
int temp2 = *pattern.ptr(i,j);
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:
版权声明:本文为xinyuLee404原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。