You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用3x3卷积核将彩色图转灰度图代码输出黑屏问题求助

代码问题排查与修复方案

核心错误点

    1. 遍历范围完全错误:两层for循环的起始值和终止值写反了,原代码for y in range(Hi, Hk + pad)逻辑完全错误,当原图高宽大于4时(3x3核pad=1,Hk+pad=4),range为空,循环根本没有执行,output数组全为0,所以输出黑屏。正确的遍历范围应该是从pad到Hi+pad(因为原图做了pad,总高度是Hi+2*pad),宽度同理。
    1. 代码缩进错误:像素值缩放、类型转换的代码被错误放到了外层for循环内部,还没完成所有像素的卷积计算就提前做了缩放,而且每遍历一行就做一次无意义的缩放转换,逻辑完全错误。这部分代码应该放到两层for循环全部结束之后再执行。
    1. 卷积核参数错误:3x3的平均卷积核权重应该是1/(3*3)=1/9,你写的1/3会导致卷积结果超过0-255范围,就算前面的问题修复了也会出现过曝问题。
    1. (次要优化点)获取原图高宽的逻辑可以调整到灰度转换之后,避免后续逻辑修改时出现维度错误。

修复后的完整代码

from skimage.exposure import rescale_intensity
import numpy as np
import cv2

def convolve(image, kernel):
    # 先拆分通道转灰度
    red, green, blue = cv2.split(image)
    gray = (red + green + blue) / 3
    # 转灰度后再取高宽更稳妥
    (Hi, Wi) = gray.shape[:2]
    (Hk, Wk) = kernel.shape[:2]

    pad = (Wk - 1) // 2
    # 对灰度图做填充
    pad_gray = cv2.copyMakeBorder(gray, pad, pad, pad, pad, cv2.BORDER_REPLICATE)
    output = np.zeros((Hi, Wi), dtype="float32")

    # 修正遍历范围:从pad到Hi+pad,覆盖所有原图像素对应的位置
    for y in range(pad, Hi + pad):
        for x in range(pad, Wi + pad):
            roi = pad_gray[y - pad:y + pad + 1, x - pad:x + pad + 1]
            k = (roi * kernel).sum()
            output[y - pad, x - pad] = k
    # 修正缩进:所有卷积计算完成后再做缩放和类型转换
    output = rescale_intensity(output, in_range=(0, 255))
    output = (output * 255).astype("uint8")
    return output


image = cv2.imread("mandrill.png")
# 修正卷积核权重为1/9
kernel = np.ones((3, 3)) * (1/9)

cv2.imshow("Output", convolve(image, kernel))
cv2.waitKey(0)
cv2.destroyAllWindows()

内容的提问来源于stack exchange,提问作者karlembeast

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.26 05:15:04