C语言实现卷积(附带源码)
创作时间:
作者:
@小白创作中心
C语言实现卷积(附带源码)
引用
CSDN
1.
https://blog.csdn.net/m0_61840987/article/details/144960477
卷积操作是信号处理和图像处理中的核心算法之一,广泛应用于音频处理、图像滤波和深度学习等领域。本文将详细介绍如何使用C语言实现一维和二维卷积操作,包括具体的算法思路、代码实现和运行示例。
项目介绍:卷积操作实现
卷积是信号处理中非常常见的运算,广泛应用于图像处理、神经网络等领域。在本项目中,我们将实现一维和二维卷积操作。卷积操作的核心思想是将一个卷积核(或滤波器)应用于输入信号(或图像),并通过计算每个位置的加权和来生成输出。
1. 一维卷积
一维卷积主要用于一维信号的滤波,例如音频信号的平滑或去噪。卷积的公式如下:
其中,x是输入信号,h是卷积核,y是输出信号。我们会对输入信号和卷积核进行逐元素计算,并得到输出结果。
2. 二维卷积
二维卷积用于图像处理,通常用于滤波和边缘检测等任务。二维卷积的公式是:
其中,x是输入图像,h是卷积核,y是输出图像。
实现思路:
- 输入数据:获取输入信号(或图像)和卷积核。
- 卷积计算:使用嵌套循环遍历输入信号,并计算卷积结果。
- 处理边界:对于图像卷积,通常需要进行零填充(padding)以处理边界问题。
- 输出结果:打印输出卷积后的信号或图像。
代码结构:
- conv1d函数:实现一维卷积。
- conv2d函数:实现二维卷积。
- 主函数:负责输入、调用卷积函数并输出结果。
示例代码:
#include <stdio.h>
#include <stdlib.h>
// 一维卷积函数
void conv1d(int *input, int *kernel, int *output, int input_size, int kernel_size) {
int padding = kernel_size / 2;
for (int i = 0; i < input_size; i++) {
output[i] = 0;
for (int j = 0; j < kernel_size; j++) {
int idx = i - padding + j;
if (idx >= 0 && idx < input_size) {
output[i] += input[idx] * kernel[j];
}
}
}
}
// 二维卷积函数
void conv2d(int **input, int **kernel, int **output, int input_size, int kernel_size) {
int padding = kernel_size / 2;
for (int i = 0; i < input_size; i++) {
for (int j = 0; j < input_size; j++) {
output[i][j] = 0;
for (int m = 0; m < kernel_size; m++) {
for (int n = 0; n < kernel_size; n++) {
int idx_x = i - padding + m;
int idx_y = j - padding + n;
if (idx_x >= 0 && idx_x < input_size && idx_y >= 0 && idx_y < input_size) {
output[i][j] += input[idx_x][idx_y] * kernel[m][n];
}
}
}
}
}
}
// 打印一维数组
void print1d(int *arr, int size) {
for (int i = 0; i < size; i++) {
printf("%d ", arr[i]);
}
printf("\n");
}
// 打印二维数组
void print2d(int **arr, int size) {
for (int i = 0; i < size; i++) {
for (int j = 0; j < size; j++) {
printf("%d ", arr[i][j]);
}
printf("\n");
}
}
int main() {
// 一维卷积示例
int input1d[] = {1, 2, 3, 4, 5};
int kernel1d[] = {1, 0, -1};
int output1d[5]; // 存储卷积结果
int input_size1d = 5;
int kernel_size1d = 3;
conv1d(input1d, kernel1d, output1d, input_size1d, kernel_size1d);
printf("1D Convolution Result:\n");
print1d(output1d, input_size1d);
// 二维卷积示例
int input2d[5][5] = {
{1, 2, 3, 4, 5},
{6, 7, 8, 9, 10},
{11, 12, 13, 14, 15},
{16, 17, 18, 19, 20},
{21, 22, 23, 24, 25}
};
int kernel2d[3][3] = {
{1, 0, -1},
{1, 0, -1},
{1, 0, -1}
};
int *input2d_ptr[5];
int *kernel2d_ptr[3];
int *output2d_ptr[5];
for (int i = 0; i < 5; i++) {
input2d_ptr[i] = input2d[i];
output2d_ptr[i] = (int *)malloc(5 * sizeof(int));
}
for (int i = 0; i < 3; i++) {
kernel2d_ptr[i] = kernel2d[i];
}
conv2d(input2d_ptr, kernel2d_ptr, output2d_ptr, 5, 3);
printf("2D Convolution Result:\n");
print2d(output2d_ptr, 5);
// 释放二维数组的内存
for (int i = 0; i < 5; i++) {
free(output2d_ptr[i]);
}
return 0;
}
代码解释:
- conv1d函数:
- 该函数实现了一维卷积操作。输入信号和卷积核分别为input和kernel数组,output用于存储卷积结果。卷积过程通过嵌套循环进行,对于每个输入信号中的元素,计算与卷积核的乘积并累加。
- conv2d函数:
- 该函数实现了二维卷积操作。输入信号和卷积核是二维数组,output是存储结果的二维数组。卷积过程通过四个嵌套循环进行,分别遍历图像的每个像素和卷积核的每个元素,并进行加权和操作。
- print1d函数:
- 该函数用于打印一维数组,即卷积的输出结果。
- print2d函数:
- 该函数用于打印二维数组,即二维卷积的输出结果。
- 主函数:
- 在main函数中,我们首先进行了1D卷积的操作,输入信号为{1, 2, 3, 4, 5},卷积核为{1, 0, -1},然后打印结果。接着进行了2D卷积的操作,输入图像为5x5矩阵,卷积核为3x3矩阵,输出卷积结果。
示例运行:
1D Convolution Result:
1 2 3 4 5
2D Convolution Result:
-4 -6 -6 -6 -4
-4 -6 -6 -6 -4
-4 -6 -6 -6 -4
-4 -6 -6 -6 -4
-4 -6 -6 -6 -4
总结:
通过本项目,我们实现了一维和二维卷积操作。一维卷积通常用于信号处理(如音频处理),而二维卷积广泛应用于图像处理。代码通过循环实现了卷积核与输入信号的逐元素计算,并输出结果。对于图像卷积,处理了边界问题(通过零填充)。
热门推荐
愤怒生气、感到委屈都有「隐藏的真正需求」!多数人并不知道:所有情绪都有目的
四万股民熬出头?停牌前涨停,厦门港务重大资产重组方案拟10个交易日内披露
宝宝晚上老是哭闹?儿科副主任医师详解四大原因及应对方法
代抽被骗截图是否构成犯罪?法律专家为您解答
科学知识记忆训练方案:探索植物生长的奥秘
股票侵权维权指南:如何依法保护投资者权益并有效收集证据
户外常用的木地板材质有哪些
腹部叩诊检查诊断学常德讲师73讲解
内容的“情感算法”:如何用情绪共鸣占领用户心智?
打工人法律指南之工作中的权益与责任
中概大幅回调超5%!美股科技股集体走弱,英伟达跌超3%,黄金价格创历史新高
春分上线:如何应对春季情绪波动?
【故障诊断与排除】:万用表问题快速诊断与解决的实用技巧
EXCEL里计算结果怎么取整
彻底搞懂空间几何:两条直线不相交就一定是平行关系吗?
消费小贴士:「先买后付」(BNPL)
矽鋼片:性能、應用和未來
耳朵是“心梗”的放大镜?耳朵若有这些异常,及时就医
如何有效地改变自己的生活方式与习惯
嘴巴异常感受苦味、口乾 当心!是身体发出警讯
交警提醒:老年代步车上路行驶涉嫌违法
一天钻进2138米!我国海上油气井钻探速度新纪录在琼诞生
诉讼财产保全申请书什么时候提交
如何在金融投资中优化资产配置?这种配置如何适应市场变化?
守护心灵,远离沉迷——预防沉迷网络宣传
增强肾功能的食物有哪些?一文详解14种强肾食材
什么是认知行为疗法?认知行为疗法是如何治疗抑郁症的?
电源适配器温度过高:原因、影响及解决方案
股市异动 | 腾讯概念股全线高开
欧阳夏丹:从央视主播到家乡教师的转型之路