使用 3x3 卷积核将彩色图像转换为灰度图像

Converting a color image into grayscale using a 3x3 convolution kernel

我正在编写一个 python 脚本,它将使用 3x3 内核将图像从彩色转换为灰度。

我创建了一个函数,它接受一个 'image' 和一个 'kernel' 作为参数,returns 图像的灰度版本。 在函数内部,我将图像分成 3 个单独的通道:redChannel、greenChannel 和 blueChannel。 然后我取这三个通道的平均值:image = (red + green + blue) / 3.

我按如下方式存储了图像高度和宽度的值:(Hi, Wi) = image.shape[:2],我也同样存储了内核的高度和宽度,(Hk, Wk) = kernel.shape[:2]。 我还包含了图像的填充,这样内核就不会 运行 越界 pad = (Wk - 1) // 2。 然后我创建了两个 for 循环,它们将使用 HiWi 遍历图像的高度和宽度。 在 for 循环内部,我将图像重塑为,以便我可以将它与内核相乘。然后我将计算结果存储在输出数组中。

这是完整代码:

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

def convolve(image, kernel):
    (Hi, Wi) = image.shape[:2]
    (Hk, Wk) = kernel.shape[:2]

    red, green, blue = cv2.split(image)
    image = (red + green + blue) / 3

    pad = (Wk - 1) // 2
    image = cv2.copyMakeBorder(image, pad, pad, pad, pad, cv2.BORDER_REPLICATE)
    output = np.zeros((Hi, Wi), dtype="float32")

    for y in range(Hi, Hk + pad):
        for x in range(Wi, Wk + pad):
            roi = image[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")

kernel = np.ones((3, 3)) * (1/3)

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

我似乎找不到代码的任何问题,但结果是黑屏。 任何帮助将不胜感激))

我使用稍微不同的方法找到了答案。 此方法获取图像的像素值并将其存储在 3 个颜色通道(R、G、B)中。 res = np.dot(kernel, v) 将图像与 3x3 灰度内核相乘。这三个 if statements 重新调整了像素值的强度。

import matplotlib.pyplot as plt
from PIL import Image
import numpy as np

def convolve(img, kernel):
    width, height = img.size
    pixels = img.load()

    for py in range(height):
        for px in range(width):
            r, g, b = img.getpixel((px, py))

            v = np.array([[r], [g], [b]])
            res = np.dot(kernel, v)

            tr, tg, tb = int(res[0, 0]), int(res[1, 0]), int(res[2, 0])

            if tr > 255:
                tr = 255

            if tg > 255:
                tg = 255

            if tb > 255:
                tb = 255

            pixels[px, py] = (tr, tg, tb)

    return img

img = Image.open('mandrill.jpg')
grayscale = np.ones((3, 3)) * (1/3)

convolve(img, grayscale)
plt.imshow(img)