Постепенное преобразование изображения в оттенки серого с numpy in python - PullRequest
1 голос
/ 15 апреля 2020

Скажем, у меня есть изображение, и я хочу, чтобы оно постепенно исчезало в оттенках серого на расстоянии.

Я уже знаю, что для полного преобразования изображения в оттенки серого с помощью Numpy я бы сделал что-нибудь как

import numpy as np
import cv2
myImage = cv2.imread("myImage.jpg")
grey = np.dot(an_image[...,:3], [0.2989, 0.5870, 0.1140])

Это не , что я ищу. Я уже могу заставить это работать.

У меня есть матрица NxMx3 (где N и M - размеры изображения), и эта матрица является измерением с красным преобразованием, зеленым трансформация и синяя трансформация.

Итак, для данного источника и радиуса «сохранить этот цвет» у меня есть

greyscaleWeights = np.array([0.2989, 0.5870, 0.1140])
# We flip this so we can weight down the transformation
greyscaleWeightOffsets = np.ones(3) - greyscaleWeights
from scipy.spatial.distance import cdist as getDistances
transformWeighter = list()
for rowNumber in np.arange(rowCount, dtype= 'int'):
    # Create a row of tuples containing the coordinate we are at in the picture
    row = [(x, rowNumber) for x in np.arange(columnCount, dtype= 'int')]
    # Transform this into a row of distances from our in-color center
    rowDistances = getDistances(row, [self.focusOrigin]).T[0]
    # Get the transformation weights: inside of the focus radius we have no transform, 
    # outside of the pixelDistanceToFullTransform we have a weight of 1, and an even 
    # gradation in-between
    rowWeights = [np.clip((x - self.focusRadius) / pixelDistanceToFullTransform, 0, 1) for x in rowDistances]
    transformWeighter.append(rowWeights)
# Convert this into an numpy array
transformWeighter = np.array(transformWeighter)
# Change this 1-D set of weights into 3-D weights (for each color channel)
transformRGB = np.repeat(transformWeighter[:, :, None],3, axis=1).reshape(self.image.shape)
# Change the weight offsets back into greyscale weights
greyscaleTransform = 1 - greyscaleWeightOffsets * transformRGB
greyscaleishImage = self.image * greyscaleTransform

Я получаю поведение затухания, на которое я надеялся, но насколько я могу судить, он просто исчезает в зеленом канале, а ноль - красным и синим.

Так, например:

this test picture

преобразуется в

this output

, что является правильным поведением трансформации, но затухает до зеленого вместо оттенков серого ...

1 Ответ

1 голос
/ 16 апреля 2020

Ну, ответ был и легким, и трудным.

Суть моего вопроса была в корне ошибочной. Чтобы процитировать этот ответ на answers.opencv.org :

Во-первых, вы должны понимать, что MxNx3 в оттенках серого не существует. Я имею в виду, что концепция оттенков серого состоит в том, что у вас есть один канал, описывающий интенсивность в постепенном масштабе между черным и белым. Итак, не ясно, зачем вам нужно 3-канальное изображение в оттенках серого, но если вы это сделаете, я предлагаю вам взять значение каждого пикселя вашего 1-канального изображения в оттенках серого и скопировать его три раза, по одному на каждый канал изображение BGR. Когда изображение BGR имеет одно и то же значение на каждом канале, оно кажется серым.

Тогда правильным ответом было бы изменить цветовое пространство, а затем обесцветить изображение, поэтому

imageHSV = cv2.cvtColor(self.image, cv2.COLOR_RGB2HSV)
newSaturationChannel = saturationWeighter * imageHSV[:,:,1]
imageHSV[:,:,1] = newSaturationChannel
greyscaleishImage = cv2.cvtColor(imageHSV, cv2.COLOR_HSV2RGB)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...