C简单实现矩阵相关和卷积

相关和卷积是两个相反的概念,卷积需要将模板矩阵旋转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进行比对结果:

如果有错,欢迎指出。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值