#python-3.x #numpy #convolution #opencv-python
Вопрос:
Я пишу скрипт на python, который будет использовать ядро 3×3 для преобразования изображения из цветного в оттенки серого.
Я создал функцию, которая принимает «изображение» и «ядро» в качестве параметров и возвращает версию изображения в оттенках серого. Внутри функции я разделил изображение на 3 отдельных канала: красный канал, зеленый канал и синий канал. Затем я беру среднее значение этих трех каналов как таковое: 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()
Кажется, я не могу найти никаких проблем с кодом, но в результате появляется черный экран. Любая помощь будет очень признательна))
Комментарии:
1. Пожалуйста, добавьте решение в поле для ответов
Ответ №1:
Я нашел ответ, используя несколько иной подход. Этот метод получает значения пикселей изображения и сохраняет их в 3 цветовых каналах (R,G,B). Изображение res = np.dot(kernel, v)
умножается на ядро в оттенках серого 3×3. Эти три 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 gt; 255: tr = 255 if tg gt; 255: tg = 255 if tb gt; 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)