Преобразование серого изображения в синее и красное изображение

#python #opencv

#python #opencv

Вопрос:

Мне было интересно, как сделать изображение в оттенках серого и превратить темные пиксели в красные, а белые пиксели в синие? Все остальные пиксели, которые выглядят серыми (не полностью черными или белыми), должны быть переходом от красного к синему.

Я попробовал следующее, взяв изображение в оттенках серого, преобразовав его в RGB, а затем попытался удалить зеленый канал. Но изображение выглядит просто розоватым:

 im = cv2.imread('grey_img.jpg')
im[:,:,1] = 0
  

Итак, как я мог превратить серое изображение в изображение сине-красного цвета?

Ответ №1:

Я пришел к некоторым математическим вещам, и они изящны:

 img = cv2.imread('images/lena.png', cv2.IMREAD_GRAYSCALE)

# find some percentiles for grayscale range of src image
percentiles = np.percentile(img, [0, 25, 75, 100])

# define the same count of values to further interpolation
targets = np.geomspace(10, 255, 4)

# use interpolation from percentiles to targets for blue and red
b = np.interp(img, percentiles, targets).astype(np.uint8)
g = np.zeros_like(img)
r = np.interp(img, percentiles, targets[::-1]).astype(np.uint8)

# merge channels to BGR image
result = cv2.merge([b, g, r])
  

Результат:

результат интерполяции logspace

Вы можете настроить яркость, изменив процентили или целевые точки пробела

Ответ №2:

Вот один из способов применить градиентный цвет к изображению в оттенках серого с помощью Python / OpenCV.

  - Load the grayscale image

 - Convert it to 3 equal channels (only if image is 1 channel grayscale already)

 - Create a 1 pixel red image

 - Create a 1 pixel blue image

 - Concatenate the two

 - Resize linearly to 256 pixels as a Lookup Table (LUT)

 - Apply the LUT

 - Save the result
  

Ввод:

введите описание изображения здесь

 import cv2
import numpy as np

# load image as grayscale
img = cv2.imread('lena_gray.png', cv2.IMREAD_GRAYSCALE)

# convert to 3 equal channels (only if img is already 1 channel grayscale)
img = cv2.merge((img, img, img))

# create 1 pixel red image
red = np.zeros((1, 1, 3), np.uint8)
red[:] = (0,0,255)

# create 1 pixel blue image
blue = np.zeros((1, 1, 3), np.uint8)
blue[:] = (255,0,0)

# append the two images
lut = np.concatenate((red, blue), axis=0)

# resize lut to 256 values
lut = cv2.resize(lut, (1,256), interpolation=cv2.INTER_CUBIC)

# apply lut
result = cv2.LUT(img, lut)

# save result
cv2.imwrite('lena_red_blue_lut_mapped.png', result)

# display result
cv2.imshow('RESULT', result)
cv2.waitKey(0)
cv2.destroyAllWindows()
  

введите описание изображения здесь

Ответ №3:

Удаление цветовой полосы не приведет к тому, что вы описали, потому что вы пытаетесь раскрасить изображение, а не обесцветить его. Функция уровня пикселей, позволяющая решить, что делать с каждым пикселем, является хорошим способом решения этой проблемы.

введите описание изображения здесь

 from PIL import Image

def pixop_redblue(pixel):
    pixel, alpha = pixel[:3], pixel[3:]
    grey = sum(pixel) // len(pixel)
    redvalue = 255 - grey  # "darkness"
    bluevalue = grey  # "brightness"
    return (redvalue, 0, bluevalue)   alpha


img = Image.open('trees.jpg')
img2 = img.copy()
img2.putdata([pixop_redblue(pixel) for pixel in img.getdata()])
img2.show()
  

введите описание изображения здесь

Комментарии:

1. Я имел в виду изображение в оттенках серого. Не чисто белое и чисто черное изображение. Я преобразую изображение, которое у меня есть, в оттенки серого, и, полагаю, я мог бы использовать ту же концепцию, о которой вы упомянули, но вместо порогового значения я буду определять его количественно по интенсивности пикселя в оттенках серого. Это может дать мне переходы вместо просто двоичного синего или красного.

2. Да, стратегия та же. Вы просто захотите использовать значение серого для определения «светлоты» и «темноты» пикселя для синего и красного значений соответственно. Я обновил свою функцию, чтобы сделать это за вас. Этой функции все равно, является ли исходное изображение серым или цветным.