算法与深度学习·

二维卷积原理和代码-动手学计算机视觉2

首发于 CSDN原文链接

本篇目录9 节

一、什么是二维卷积?

二维卷积(2D Convolution)是
图像处理
中最基础也最重要的操作之一,广泛应用于:
  • 图像模糊
  • 边缘检测
  • 卷积神经网络(CNN)特征提取
通俗地讲:
把一个小的“滤波器”(也叫“卷积核”)放在图像上一个位置,对应区域的值和卷积核每个位置相乘后加总,结果作为输出图像的一个像素值,然后不断滑动这个核,得到整张图的新图像。

二、卷积的操作步骤(滑动 + 乘加)

假设你有:
  • 原始图像(5×5)
  • 卷积核(3×3)
操作过程如下:
  1. 卷积核放在图像左上角,和 3x3 区域重叠
  1. 对应位置相乘,然后求和
  1. 得到的结果就是输出图像对应位置的像素值
  1. 卷积核向右移动一格,重复以上过程
  1. 到右边边缘后,向下一行移动,从左往右继续滑动

示例计算:

图像窗口:
1 2 3 4 5 6 7 8 9
卷积核:
1 0 -1 1 0 -1 1 0 -1
计算:
= 1×1 + 2×0 + 3×(-1) + 4×1 + 5×0 + 6×(-1) + 7×1 + 8×0 + 9×(-1) = 1 - 3 + 4 - 6 + 7 - 9 = -6
输出图像中对应位置的值就是 -6。

三、输出图像大小怎么计算?

若输入图像为 H × W,卷积核为 kH × kW,不加填充(padding),步幅(stride)为 1:
输出高 = H - kH + 1 输出宽 = W - kW + 1
举例:5×5 输入图像 + 3×3 卷积核 → 输出图像为 3×3。

四、卷积与相关运算的区别(细节)

数学上的卷积会对卷积核进行 180° 翻转,但在图像处理中(尤其是
CNN
)中,一般不翻转核,这种形式实际上是相关运算(correlation)。但业界仍普遍称其为“卷积”。

五、卷积能实现哪些操作?

卷积核类型
功能
均值核(全部 1)
模糊/平滑图像
Sobel 核
边缘检测
Laplacian
边缘锐化
自定义核
特征提取

六、代码实现

from matplotlib import pyplot as plt import numpy as np import cv2 import seaborn as sns class conv_2d(): def __init__(self, a, b): # 输入图像 self.a = a # 卷积核 self.b = b # 输入图像的坐标 self.ax = [i for i in range(self.a.shape[0])] self.ay = [i for i in range(self.a.shape[1])] # 卷积核的坐标 self.bx = [i for i in range(self.b.shape[0])] self.by = [i for i in range(self.b.shape[1])] def conv(self): # 对输入图像a和卷积核b进行数学上的卷积操作 c = cv2.filter2D(self.a, -1, self.b) return c def plot(self): a = self.a b = self.b c = self.conv() plt.figure(figsize=(12, 4)) # 输入图像 plt.subplot(1, 3, 1) plt.title('Input') # 灰度图 plt.imshow(a, cmap='gray') plt.axis('off') # 卷积核 plt.subplot(1, 3, 2) plt.title('Kernel') sns.heatmap(b, annot=False, cmap='Greens', cbar=False) plt.axis('off') # 输出图像 plt.subplot(1, 3, 3) plt.title('Output') plt.imshow(c, cmap='gray') plt.axis('off') plt.tight_layout() plt.show() # 冲击信号 img = cv2.imread('lenna.jpg') # 默认BGR格式 img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为灰度 # 二维冲击卷积核 # 这个卷积核的效果是: # 输出图像中的每个像素将是输入图像中对应位置像素的精确复制 # 实际上相当于对图像没有做任何改变(单位操作) # 因为卷积核只在中心有1,其他都是0,相当于只取源图像对应位置的像素值 size=15 # 创建了一个15×15的全零矩阵k1 k1=np.zeros((size,size)) # 计算中间位置mid = (15-1)//2 = 7 mid=(size-1)//2 # 在中间位置设置为1 k1[mid,mid]=1 # 计算卷积并绘图 cov = conv_2d(img, k1) cov.plot()
###
notion image

七、方波信号卷积

我们再来观察方波信号对图像进行卷积
# 冲击信号 img=cv2.imread('lenna.jpg',cv2.IMREAD_GRAYSCALE) # 计算机视觉最经典的一张图片Lenna # 二维冲击卷积核 # 这个卷积核的效果是: # 输出图像中的每个像素将是输入图像中对应位置像素的精确复制 # 实际上相当于对图像没有做任何改变(单位操作) # 因为卷积核只在中心有1,其他都是0,相当于只取源图像对应位置的像素值 size=15 # 创建了一个15×15的全零矩阵k1 k1=np.zeros((size,size)) # 因为二维的核函数的大小是n*n的,因此在实现方波信号时我们需要除以(size*size) k2=np.ones((size,size))/size** 2 # 计算中间位置mid = (15-1)//2 = 7 mid=(size-1)//2 # 在中间位置设置为1 k1[mid,mid]=1 # 计算卷积并绘图 # cov = conv_2d(img, k1) cov = conv_2d(img, k2) cov.plot()
notion image

八、总结

项目
内容说明
操作
二维卷积
输入
图像 + 卷积核
核心过程
滑动窗口 → 乘加 → 求和
输出
新图像(特征图)
实现语言
Python(手写)
实用场景
图像处理、深度学习、CNN 等

评论加载中…