首页 > 解决方案 > 使用 3x3 卷积核将彩色图像转换为灰度图像

问题描述

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

我创建了一个以“图像”和“内核”为参数的函数,并返回图像的灰度版本。在函数内部,我将图像分成 3 个单独的通道:redChannel、greenChannel 和 blueChannel。然后我取这三个渠道的平均值:image = (red + green + blue) / 3.

我将图像高度和宽度的值存储如下:(Hi, Wi) = image.shape[:2]并且我对存储内核的高度和宽度做了同样的事情,(Hk, Wk) = kernel.shape[:2]. 我还包括了图像的填充,这样内核就不会超出边界 pad = (Wk - 1) // 2Hi然后我创建了两个 for 循环,它们将使用和遍历图像的高度和宽度Wi。在 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()

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

标签: python-3.xnumpyconvolutionopencv-python

解决方案


我使用稍微不同的方法找到了答案。此方法获取图像的像素值并将其存储在 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)

推荐阅读