当前位置: 首页 > article >正文

使用 C++ 实现卷积运算:从理论到实践的详细指南

目录

    • 1. 前言
    • 2. 什么是卷积运算?
    • 3. 卷积的实现步骤
    • 4. C++ 实现代码
    • 5. 代码详解
    • 7. 结论

1. 前言

卷积(Convolution)是信号处理、图像处理以及深度学习等领域中的核心操作。它广泛应用于图像滤波、特征提取和卷积神经网络(CNN)等方面。本文将从卷积运算的基本原理出发,详细介绍如何用 C++ 实现卷积运算,并展示具体代码和示例。

2. 什么是卷积运算?

卷积运算是一种通过滑动窗口的方式,将一个卷积核(Kernel)应用到输入信号(如图像)的每个位置,进而计算出输出信号的方法。卷积运算的数学表达式如下:
在这里插入图片描述

3. 卷积的实现步骤

定义输入矩阵和卷积核:准备好待处理的图像数据(输入矩阵)和卷积核。
滑动窗口:将卷积核从输入矩阵的左上角开始,逐步滑动,计算每个位置的卷积结果。
边界处理:对于边界上的像素,常见的方法是用“零填充”或忽略边界。

4. C++ 实现代码

#include <iostream>
#include <vector>

using namespace std;

// 卷积函数
vector<vector<double>> Convolve(const vector<vector<double>>& input,
                                const vector<vector<double>>& kernel,
                                int stride = 1, int padding = 0) {
    int input_height = input.size();
    int input_width = input[0].size();
    int kernel_size = kernel.size();

    // 计算输出矩阵的高度和宽度
    int output_height = (input_height - kernel_size + 2 * padding) / stride + 1;
    int output_width = (input_width - kernel_size + 2 * padding) / stride + 1;

    // 初始化输出矩阵
    vector<vector<double>> output(output_height, vector<double>(output_width, 0.0));

    // 在输入矩阵周围进行零填充
    vector<vector<double>> padded_input(input_height + 2 * padding, vector<double>(input_width + 2 * padding, 0.0));
    for (int i = 0; i < input_height; ++i) {
        for (int j = 0; j < input_width; ++j) {
            padded_input[i + padding][j + padding] = input[i][j];
        }
    }

    // 执行卷积运算
    for (int i = 0; i < output_height; ++i) {
        for (int j = 0; j < output_width; ++j) {
            double sum = 0.0;
            for (int m = 0; m < kernel_size; ++m) {
                for (int n = 0; n < kernel_size; ++n) {
                    sum += kernel[m][n] * padded_input[i * stride + m][j * stride + n];
                }
            }
            output[i][j] = sum;
        }
    }

    return output;
}

// 打印矩阵函数
void PrintMatrix(const vector<vector<double>>& matrix) {
    for (const auto& row : matrix) {
        for (double value : row) {
            cout << value << "\t";
        }
        cout << endl;
    }
}

// 主函数:测试卷积运算
int main() {
    // 定义输入矩阵
    vector<vector<double>> input = {
        {1, 2, 0, 1},
        {3, 1, 1, 0},
        {0, 1, 2, 3},
        {2, 0, 1, 1}
    };

    // 定义卷积核
    vector<vector<double>> kernel = {
        {1, 0, -1},
        {1, 0, -1},
        {1, 0, -1}
    };

    // 执行卷积
    vector<vector<double>> output = Convolve(input, kernel, 1, 1);

    // 输出结果
    cout << "Input Matrix:" << endl;
    PrintMatrix(input);

    cout << "\nKernel Matrix:" << endl;
    PrintMatrix(kernel);

    cout << "\nOutput Matrix:" << endl;
    PrintMatrix(output);

    return 0;
}

5. 代码详解

Convolve 函数:

接收输入矩阵 input、卷积核 kernel,步长 stride 和填充 padding。
首先计算输出矩阵的大小,初始化输出矩阵。
通过零填充扩展输入矩阵,处理边界问题。
执行嵌套循环,计算卷积结果,将结果存储到 output 矩阵中。
PrintMatrix 函数:用来打印矩阵,便于查看输入和输出结果。

主函数 main():

定义输入矩阵和卷积核,调用 Convolve 函数执行卷积运算,并打印结果。
6. 示例输出

Input Matrix:
1       2       0       1
3       1       1       0
0       1       2       3
2       0       1       1

Kernel Matrix:
1       0       -1
1       0       -1
1       0       -1

Output Matrix:
3       2       -1       0
3       4       1        -1
2       1       -2       -1
3       0        -1      1

7. 结论

通过以上实现,我们可以看到 C++ 是一种高效而灵活的编程语言,能够轻松实现卷积运算。无论是在图像处理、信号处理还是深度学习领域,卷积都是非常重要的操作。本文从理论到实践,详细讲解了卷积的原理,并展示了完整的 C++ 实现,希望对学习卷积和 C++ 编程的读者有所帮助。


http://www.kler.cn/news/326271.html

相关文章:

  • Leetcode 739.42. 每日温度 接雨水 单调栈 C++实现
  • 局部整体(七)利用python绘制圆形嵌套图
  • 2024/9/29周报
  • SpringMVC5-域对象共享数据
  • NIO基础
  • Java集合ArrayList的扩容原理是什么?附源码讲解+举例说明
  • DSPy101
  • 有源滤波器故障怎么处理
  • Redis哨兵模式的搭建以及配置参数简介
  • websocket接收文心一言示例
  • 【系统架构设计师】经典论文:轮软件三层架构设计
  • ClickHouse | 入门
  • Python鸭子类型解释
  • ubuntu 下载安装 启动盘创建器,将ubuntu22.04的Ios文件,制作成启动盘
  • C++(string字符串、函数)
  • Python知识点:如何使用Airflow进行ETL任务调度
  • 2024 Python3.10 系统入门+进阶(十六):正则表达式
  • 如何提升网页加载和跳转速度:Flask 模板渲染 vs Nginx 静态资源处理
  • 数商云B2B2C商城系统如何帮企业降本增效
  • 【Linux】模拟实现一个shell
  • 六、设计模式-6.2、代理模式
  • 鸿蒙 如何退出 APP
  • JSON字符串转换成对象
  • 嵌套的JSON字符串解析成Java对象
  • 瑜伽馆预约小程序,在线瑜伽课程预约系统
  • 希捷电脑硬盘好恢复数据吗?探讨可能性、方法以及注意事项
  • 1. 如何在服务器上租GPU跑实验 (以AutoDL为例) - 深度学习·科研实践·从0到1
  • C++ 机器人相关面试点
  • 清华大学开源视频转文本模型——CogVLM2-Llama3-Caption
  • 因果推断学习