不调用opencv 加速实现NCC模板匹配
时间: 2023-10-30 14:04:50 浏览: 226
opencv python实现NCC旋转匹配
5星 · 资源好评率100%
以下是不使用OpenCV库,纯C++实现的NCC模板匹配的代码实现:
```cpp
#include <iostream>
#include <cmath>
#include <ctime>
#include <cstdlib>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <vector>
using namespace std;
const int MAXN = 1005;
const double PI = acos(-1.0);
int n, m;
double a[MAXN][MAXN], b[MAXN][MAXN];
double cosb, sinb;
// 对图像进行旋转变换
void rotate(double& x, double& y, double sinb, double cosb) {
double x1 = x * cosb + y * sinb;
double y1 = -x * sinb + y * cosb;
x = x1; y = y1;
}
// 计算图像的均值
double mean(double a[][MAXN], int n, int m) {
double sum = 0;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
sum += a[i][j];
return sum / (n * m);
}
// 计算归一化互相关系数
double NCC(int x, int y) {
double sum = 0, sum1 = 0, sum2 = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
double xx = i - x, yy = j - y;
rotate(xx, yy, sinb, cosb); // 对坐标进行旋转变换
if (xx >= 0 && xx < n && yy >= 0 && yy < m) {
sum += a[i][j] * b[int(xx)][int(yy)];
sum1 += a[i][j] * a[i][j];
sum2 += b[int(xx)][int(yy)] * b[int(xx)][int(yy)];
}
}
}
return sum / sqrt(sum1 * sum2);
}
// 计算最大匹配值及其位置
double match(int& x, int& y) {
double res = -1e9;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
double tmp = NCC(i, j);
if (tmp > res) {
res = tmp;
x = i; y = j;
}
}
}
return res;
}
int main() {
scanf("%d%d", &n, &m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
scanf("%lf", &a[i][j]);
int p, q;
scanf("%d%d", &p, &q);
for (int i = 0; i < p; i++)
for (int j = 0; j < q; j++)
scanf("%lf", &b[i][j]);
// 对模板图像进行均值化
double meanb = mean(b, p, q);
for (int i = 0; i < p; i++)
for (int j = 0; j < q; j++)
b[i][j] -= meanb;
// 对模板图像进行旋转变换
double theta = 2 * PI / 360;
double angle = -30;
sinb = sin(angle * theta), cosb = cos(angle * theta);
double x1 = 0, y1 = 0, x2 = p - 1, y2 = q - 1;
rotate(x1, y1, sinb, cosb);
rotate(x2, y2, sinb, cosb);
int np = ceil(max(max(x1, x2), double(p))), nq = ceil(max(max(y1, y2), double(q)));
for (int i = 0; i < np; i++) {
for (int j = 0; j < nq; j++) {
double x = i, y = j;
rotate(x, y, sinb, cosb);
if (x >= 0 && x < p && y >= 0 && y < q)
b[i][j] = b[int(x)][int(y)];
else b[i][j] = 0;
}
}
// 对搜索图像进行均值化
double meana = mean(a, n, m);
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
a[i][j] -= meana;
int x, y;
double res = match(x, y); // 计算最大匹配值及其位置
printf("最大匹配值:%lf\n", res);
// 在搜索图像中标记匹配位置
for (int i = x - p / 2; i <= x + p / 2; i++)
for (int j = y - q / 2; j <= y + q / 2; j++)
a[i][j] = 255;
for (int i = 0; i < n; i++)
for (int j = 0; j < m; j++)
printf("%.2lf%c", a[i][j], j == m - 1 ? '\n' : ' ');
return 0;
}
```
该代码实现了NCC模板匹配的核心算法,包括模板图像的旋转变换、归一化互相关系数的计算、最大匹配值及其位置的计算等。需要注意的是,该代码中使用了角度为-30°的旋转变换,可以根据需要进行调整。
由于该代码没有使用OpenCV库,因此在处理大尺寸图像和模板时可能会比较慢。可以使用多线程等技术来加速计算。
阅读全文