相关和卷积是两个相反的概念,卷积需要将模板矩阵旋转180°,当然可以相对地将原图像和模板重合部分做一个旋转,简化计算。
下面是C代码实现分别用相关和卷积实现滤波。
#include<stdio.h>
#include<malloc.h>
#define var int
#define v1_row 5
#define v1_col 5
#define v2_row 3
#define v2_col 3
void show(var **v, int m, int n) {
printf("-");
for (int j = 0; j < n; j++) {
printf("-------");
}
printf("\n");
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
printf("|%5d ", v[i][j]);
}
printf("|\n-");
for (int j = 0; j < n; j++) {
printf("-------");
}
printf("\n");
}
printf("\n");
}
/*计算A和B相关*/
var **corr2(var **A, var **B, int am, int an, int bm, int bn) {
int n1 = am + bm - 1;
int n2 = an + bn - 1;
var **result = (var**)malloc(n1 * sizeof(var*));
for (int i = 0; i < n1; i++) {
result[i] = (var*)malloc(n2 * sizeof(var*));
for (int j = 0; j < n2; j++) {
var sum = 0;
for (int m = 0; m < bm; m++) {
for (int n = 0; n < bn; n++) {
int rm = i-am/2+m;
int rn = j-an/2+n;
/*补0处理*/
if (rm >= 0 && rm<am&&rn >= 0 && rn<an)
sum += A[rm][rn] * B[m][n];
}
}
result[i][j] = sum;
}
}
return result;
}
/*计算A和B卷积*/
var **conv2(var **A, var **B,int am,int an,int bm,int bn) {
int n1 = am + bm - 1;
int n2 = an + bn - 1;
var **result = (var**)malloc(n1 * sizeof(var*));
for (int i = 0; i < n1; i++) {
result[i] = (var*)malloc(n2 * sizeof(var*));
for (int j = 0; j < n2; j++) {
var sum = 0;
for (int m = 0; m < bm; m++) {
for (int n = 0; n < bn; n++) {
int rm = i-m;
int rn = j-n;
/*补0处理*/
if (rm >= 0 && rm<am&&rn >= 0 && rn<an)
sum += A[rm][rn] * B[m][n];
}
}
result[i][j] = sum;
}
}
return result;
}
int main() {
int **v1=(var**)malloc(v1_row *sizeof(var*));
int **v2 = (var**)malloc(v2_row * sizeof(var*));
/*分配矩阵空间*/
for (int i = 0; i < v1_row; i++) {
v1[i] = (var*)malloc(v1_col * sizeof(var));
for (int j = 0; j < v1_col; j++) {
v1[i][j] = i * v1_col + j + 1;
}
}
for (int i = 0; i < v2_row; i++) {
v2[i] = (var*)malloc(v2_col * sizeof(var));
for (int j = 0; j < v2_col; j++) {
v2[i][j] = j + v2_col * i + 1;
}
}
show(v1, v1_row, v1_col);
show(v2, v2_row, v2_col);
var **corr = corr2(v1, v2, v1_row, v1_col, v2_row, v2_col);
var **conv = conv2(v1, v2, v1_row, v1_col, v2_row, v2_col);
printf("相关\n");
show(corr, v1_row + v2_row - 1, v1_col + v2_col - 1);
printf("卷积\n");
show(conv, v1_row + v2_row - 1, v1_col + v2_col - 1);
/*释放内存*/
for (int i = 0; i < v1_row; i++) {
free(v1[i]);
free(conv[i]);
free(corr[i]);
}
for (int i = 0; i < v2_row; i++) {
free(v2[i]);
}
free(v1);
free(v2);
free(conv);
free(corr);
return 0;
}
实现结果和matlab进行比对结果:
如果有错,欢迎指出。