题解 | #图像处理中的卷积操作实现#

图像处理中的卷积操作实现

https://www.nowcoder.com/practice/798b474486af4528b9722feacc39aafb

题解:图像卷积操作

题目概述

本题要求实现灰度图像的卷积操作。给定一个 m×n 的灰度图像矩阵和一个 k×k 的卷积核(k 为奇数),程序需要对图像进行卷积操作,边缘使用零填充(Zero Padding),并输出卷积结果(保留两位小数)。

核心概念

  1. 卷积操作:将卷积核在图像上滑动,计算每个位置覆盖区域的像素值与卷积核的乘积之和。
  2. 零填充:在图像边缘填充零,使卷积核可以覆盖边缘像素。
  3. 卷积核尺寸k 为奇数,确保卷积核有明确的中心点。

解题思路

  1. 读取输入:获取图像矩阵和卷积核矩阵。
  2. 零填充:在图像四周各填充 k//2 个零。
  3. 卷积计算
    • 遍历图像的每个像素位置 (i, j)
    • 截取以 (i, j) 为中心的 k×k 区域。
    • 计算该区域与卷积核的乘积之和。
  4. 输出结果:保留两位小数,按行输出矩阵。

代码解析

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)))

关键步骤说明

  1. 零填充

    • 使用 np.pad(image, pad_width, mode='constant', constant_values=0) 在图像四周填充零。
    • 填充宽度 pad_width = k // 2(例如 k=3 时填充 1 圈零)。
  2. 卷积计算

    • 遍历原始图像的每个位置 (i, j)
    • 在填充后的图像上截取区域 [i:i+k, j:j+k](尺寸 k×k)。
    • 计算区域与卷积核的乘积之和:np.sum(region * kernel)
  3. 保留小数

    • 使用 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

处理过程

  1. 图像填充后(k=3,填充 1 圈零):
    [[0, 0, 0, 0],
     [0, 1, 2, 0],
     [0, 3, 4, 0],
     [0, 0, 0, 0]]
    
  2. 计算位置 (0,0) 的卷积:
    • 区域:[[0,0,0], [0,1,2], [0,3,4]]
    • 乘积之和:0.1*(0+0+0+0+1+2+0+3+4) = 1.0
  3. 最终输出(保留两位小数):
    1.00 1.00
    1.00 1.00
    

复杂度分析

  • 时间复杂度O(m × n × k²),其中 m×n 是图像尺寸, 是卷积核尺寸。
  • 空间复杂度O((m+2p) × (n+2p))p=k//2 是填充宽度。
全部评论

相关推荐

Cherrycola01:0实习 0项目 约等于啥也没有啊 哥们儿这简历认真的吗
点赞 评论 收藏
分享
球Offer上岸👑:可能是大环境太差了 太卷了 学历也很重要 hc也不是很多 所以很难
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务