Конвертировать все белые пиксели изображения в черные пиксели
У меня есть это изображение rand-walk-2.png
Я хотел бы преобразовать все белые пиксели в черные, чтобы на черном фоне было изображение случайного красного обхода, это означает, что я не могу просто инвертировать цвета изображения. Мой текущий код просто находит белые пиксели и устанавливает их на черный:
from PIL import Image
import PIL.ImageOps
import numpy as np
from skimage.io import imsave
import cv2
in_path = 'rand-walk-2.png'
out_path = 'rand-walk-trial.png'
Image = cv2.imread(in_path)
Image2 = np.array(Image, copy=True)
white_px = np.asarray([255, 255, 255])
black_px = np.asarray([0 , 0 , 0 ])
(row, col, _) = Image.shape
for r in xrange(row):
for c in xrange(col):
px = Image[r][c]
if all(px == white_px):
Image2[r][c] = black_px
imsave(out_path, Image2)
Но это производит это:
по какой-то причине я не могу объяснить.
1 ответ
Причина в том, что модуль Skimage (в вашем случае функция skimage.io.imsave
) использует цветовую последовательность RGB, тогда как OpenCV (в вашем случае функция cv2.imread
), как известно, использует цветовую последовательность BGR. Таким образом, синий и красный цвета поменялись местами с вашим сценарием.
Два решения для вас - конвертировать изображение в RGB сразу после чтения:
Image = cv2.imread(in_path)
Image = cv2.cvtColor(Image, cv2.COLOR_BGR2RGB)
Или сохранить выходное изображение с помощью cv2:
cv2.imwrite(out_path, Image2)
Результат:
Другое решение, которое дает намного более приятный вывод, это просто инвертирование вашего изображения:
Image = cv2.imread(in_path)
Image = cv2.bitwise_not(Image)
cv2.imwrite(out_path, Image)
Результат:
Или, если вы все еще хотите красный цвет, вы можете инвертировать, удалить зеленый канал и поменять местами синий и красный:
Image = cv2.imread(in_path)
Image = cv2.bitwise_not(Image)
b,g,r = cv2.split(Image)
z = np.zeros_like(g)
Image = cv2.merge((z,z,b))
cv2.imwrite(out_path, Image)
Результат: