题解:图像卷积操作
题目概述
本题要求实现灰度图像的卷积操作。给定一个 m×n
的灰度图像矩阵和一个 k×k
的卷积核(k
为奇数),程序需要对图像进行卷积操作,边缘使用零填充(Zero Padding),并输出卷积结果(保留两位小数)。
核心概念
- 卷积操作:将卷积核在图像上滑动,计算每个位置覆盖区域的像素值与卷积核的乘积之和。
- 零填充:在图像边缘填充零,使卷积核可以覆盖边缘像素。
- 卷积核尺寸:
k
为奇数,确保卷积核有明确的中心点。
解题思路
- 读取输入:获取图像矩阵和卷积核矩阵。
- 零填充:在图像四周各填充
k//2
个零。 - 卷积计算:
- 遍历图像的每个像素位置
(i, j)
。 - 截取以
(i, j)
为中心的k×k
区域。 - 计算该区域与卷积核的乘积之和。
- 遍历图像的每个像素位置
- 输出结果:保留两位小数,按行输出矩阵。
代码解析
import sys
import numpy as np
def read_matrix(rows, cols, data_type=float):
"""读取指定行数和列数的矩阵"""
matrix = []
for _ in range(rows):
while True:
line = sys.stdin.readline()
if line.strip(): # 跳过空行
break
elements = list(map(data_type, line.strip().split()))
matrix.append(elements)
return np.array(matrix)
def convolve2d(image, kernel):
"""执行卷积操作"""
m, n = image.shape # 图像尺寸
k = kernel.shape[0] # 卷积核尺寸
pad_width = k // 2 # 计算填充宽度
# 零填充图像
padded_image = np.pad(image, pad_width, mode='constant', constant_values=0)
output = np.zeros((m, n)) # 初始化输出矩阵
# 遍历每个像素位置
for i in range(m):
for j in range(n):
# 截取当前区域 (k×k)
region = padded_image[i:i+k, j:j+k]
# 计算区域与卷积核的乘积之和
output[i, j] = np.sum(region * kernel)
# 四舍五入保留两位小数
output = np.round(output, 2)
return output
if __name__ == "__main__":
# 读取图像尺寸
m, n = map(int, sys.stdin.readline().split())
# 读取图像矩阵
image = read_matrix(m, n, data_type=float)
# 读取卷积核尺寸
k = int(sys.stdin.readline().strip())
# 读取卷积核矩阵
kernel = read_matrix(k, k, data_type=float)
# 执行卷积
output = convolve2d(image, kernel)
# 输出结果
for row in output:
print(' '.join(map(str, row)))
关键步骤说明
-
零填充:
- 使用
np.pad(image, pad_width, mode='constant', constant_values=0)
在图像四周填充零。 - 填充宽度
pad_width = k // 2
(例如k=3
时填充 1 圈零)。
- 使用
-
卷积计算:
- 遍历原始图像的每个位置
(i, j)
。 - 在填充后的图像上截取区域
[i:i+k, j:j+k]
(尺寸k×k
)。 - 计算区域与卷积核的乘积之和:
np.sum(region * kernel)
。
- 遍历原始图像的每个位置
-
保留小数:
- 使用
np.round(output, 2)
将结果四舍五入到两位小数。
- 使用
示例演示
输入:
2 2
1 2
3 4
3
0.1 0.1 0.1
0.1 0.1 0.1
0.1 0.1 0.1
处理过程:
- 图像填充后(
k=3
,填充 1 圈零):[[0, 0, 0, 0], [0, 1, 2, 0], [0, 3, 4, 0], [0, 0, 0, 0]]
- 计算位置
(0,0)
的卷积:- 区域:
[[0,0,0], [0,1,2], [0,3,4]]
- 乘积之和:
0.1*(0+0+0+0+1+2+0+3+4) = 1.0
- 区域:
- 最终输出(保留两位小数):
1.00 1.00 1.00 1.00
复杂度分析
- 时间复杂度:
O(m × n × k²)
,其中m×n
是图像尺寸,k²
是卷积核尺寸。 - 空间复杂度:
O((m+2p) × (n+2p))
,p=k//2
是填充宽度。