使用 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 循环,它们将使用 Hi
和 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()
我似乎找不到代码的任何问题,但结果是黑屏。
任何帮助将不胜感激))
我使用稍微不同的方法找到了答案。
此方法获取图像的像素值并将其存储在 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)
我正在编写一个 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 循环,它们将使用 Hi
和 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()
我似乎找不到代码的任何问题,但结果是黑屏。 任何帮助将不胜感激))
我使用稍微不同的方法找到了答案。
此方法获取图像的像素值并将其存储在 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)