目录
什么是卷积?
在计算机视觉和信号处理中,卷积(Convolution) 是一种数学运算,主要用于图像处理(如高斯模糊、Canny 边缘检测)、深度学习(卷积神经网络 CNN)等任务。简单来说,卷积的本质是对某个区域进行加权求和,使得图像能够被平滑化、边缘增强、降噪等。
直观理解卷积
我们可以把卷积想象成一种“滑动窗口”操作,在输入图像上滑动一个小区域(称为卷积核 Kernel 或 滤波器 Filter),然后用它覆盖的像素进行某种数学运算,生成新的像素值。
假设你有一幅黑白图像:
10 20 30 40 50 60 70 80 90
然后你有一个3×3的卷积核(滤波器):
0 1 0 1 -4 1 0 1 0
我们将这个卷积核覆盖在原图像的某个 3×3 区域,计算“加权求和”的结果:
这个过程称为 卷积运算,它的本质就是把卷积核当作一个“滤波器”来提取不同的特征,比如:
-
模糊滤波(均值滤波、高斯模糊)
-
边缘检测(Sobel、Laplacian、Canny)
代码模拟运算过程
import cv2
import numpy as np
import matplotlib.pyplot as plt
import time
# 生成一个 10x10 的测试图像(随机灰度值)
np.random.seed(42)
image = np.random.randint(0, 256, (10, 10), dtype=np.uint8)
# 定义一个 3x3 卷积核(简单求和平均)
kernel = np.array([[1, 1, 1],
[1, 1, 1],
[1, 1, 1]]) / 9 # 归一化(求平均)
# 获取图像尺寸
height, width = image.shape
# 创建输出图像
output = np.zeros((height, width), dtype=np.uint8)
# 设置 Matplotlib 画布
fig, ax = plt.subplots()
ax.set_xticks(np.arange(0.5, width, 1))
ax.set_yticks(np.arange(0.5, height, 1))
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.grid(color='gray', linestyle='-', linewidth=1)
# 遍历图像进行卷积
for y in range(1, height - 1): # 遍历 y 轴(避免超出边界)
for x in range(1, width - 1): # 遍历 x 轴
# 取出当前 3x3 区域
region = image[y - 1:y + 2, x - 1:x + 2]
# 计算卷积(加权求和)
value = np.sum(region * kernel)
# 存入输出图像
output[y, x] = np.clip(value, 0, 255)
# 可视化当前窗口
ax.clear()
ax.imshow(image, cmap='gray', vmin=0, vmax=255)
ax.set_xticks(np.arange(0.5, width, 1))
ax.set_yticks(np.arange(0.5, height, 1))
ax.set_xticklabels([])
ax.set_yticklabels([])
ax.grid(color='gray', linestyle='-', linewidth=1)
# 在当前滑动窗口区域画红色框
rect = plt.Rectangle((x - 1, y - 1), 2, 2, linewidth=2, edgecolor='r', facecolor='none')
ax.add_patch(rect)
# 在当前计算的像素上标注数值
ax.text(x, y, int(output[y, x]), color='yellow', ha='center', va='center', fontsize=10, weight='bold')
ax.set_title(f"Processing Pixel ({x}, {y})")
plt.pause(0.2) # 控制更新速度
# 显示最终结果
plt.show()
cv2.imshow("Original Image", image)
cv2.imshow("Convolution Result", output)
cv2.waitKey(0)
cv2.destroyAllWindows()
效果如下:
卷积运算网络
卷积的数学定义
对于一个二维图像 f(x,y) 和卷积核 g(x,y),卷积运算定义如下:
其中:
-
f(x,y) 是原图像的像素值
-
g(x,y) 是卷积核
-
i,j 代表卷积核的索引
解释:
-
滑动窗口:卷积核在整个图像上滑动,每次覆盖一个区域
-
加权求和:计算该区域的加权和,替换成新的像素值
-
输出新图像:把计算后的结果存入一个新图像
卷积的应用
-
平滑(去噪):均值滤波、高斯模糊
-
边缘检测:Sobel、Canny、Laplacian
-
特征提取:卷积神经网络(CNN)
代码演示:使用 OpenCV 进行卷积
我们可以使用 Python + OpenCV 进行一个简单的卷积操作,比如高斯模糊:
import cv2
import numpy as np
# 读取图像
image = cv2.imread("image.jpg", cv2.IMREAD_GRAYSCALE)
# 定义一个 3x3 的均值滤波器
kernel = np.ones((3, 3), np.float32) / 9
# 进行卷积运算
blurred = cv2.filter2D(image, -1, kernel)
# 显示结果
cv2.imshow("Original", image)
cv2.imshow("Blurred", blurred)
cv2.waitKey(0)
cv2.destroyAllWindows()
解释:
-
cv2.filter2D()
:OpenCV 内置的卷积操作 -
kernel = np.ones((3,3), np.float32) / 9
:3×3 的均值滤波器 -
cv2.imshow()
:显示原图和模糊后的图像