二维卷积原理和代码-动手学计算机视觉2
二维卷积是图像处理的核心操作,通过滑动窗口对图像局部区域与卷积核进行乘加运算,生成新特征图。文章详细介绍了卷积原理(包括输入输出尺寸计算)、与相关运算的区别,以及模糊、边缘检测等常见应用场景。通过Python代码演示了单位卷积核和均值滤波的实现效果,展示了不同卷积核对图像处理的作用差异。该技术是计算机视觉和深度学习的基础,广泛应用于特征提取、图像增强等领域。
·
一、什么是二维卷积?
二维卷积(2D Convolution)是图像处理中最基础也最重要的操作之一,广泛应用于:
- 图像模糊
- 边缘检测
- 卷积神经网络(CNN)特征提取
通俗地讲:
把一个小的“滤波器”(也叫“卷积核”)放在图像上一个位置,对应区域的值和卷积核每个位置相乘后加总,结果作为输出图像的一个像素值,然后不断滑动这个核,得到整张图的新图像。
二、卷积的操作步骤(滑动 + 乘加)
假设你有:
- 原始图像(5×5)
- 卷积核(3×3)
操作过程如下:
- 卷积核放在图像左上角,和 3x3 区域重叠
- 对应位置相乘,然后求和
- 得到的结果就是输出图像对应位置的像素值
- 卷积核向右移动一格,重复以上过程
- 到右边边缘后,向下一行移动,从左往右继续滑动
示例计算:
图像窗口:
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()
七、方波信号卷积
我们再来观察方波信号对图像进行卷积
# 冲击信号
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()
八、总结
项目 | 内容说明 |
---|---|
操作 | 二维卷积 |
输入 | 图像 + 卷积核 |
核心过程 | 滑动窗口 → 乘加 → 求和 |
输出 | 新图像(特征图) |
实现语言 | Python(手写) |
实用场景 | 图像处理、深度学习、CNN 等 |

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐
所有评论(0)