Как преобразовать пиксели изображения RGB в L * a * b *? - PullRequest
0 голосов
/ 11 октября 2018

Что ж, я работаю с обработкой изображения, чтобы определить изменение цвета изображения и иметь возможность отобразить эти данные в гистограмме.Для этого я использую изображения пятен кожи в цветовом пространстве RGB.Код ниже, я могу получить цвета каждого пикселя и преобразовать в HSV, используя color.rgb2lab.Но поскольку я хочу преобразовать в L * a * b *, поскольку он ближе к человеческому зрению, в библиотеке python нет преобразования в L * a * b *.Благодаря этому, через разделенные пиксели RGB, как мне преобразовать эти пиксели в цвета LAB?

import numpy as np
import mpl_toolkits.mplot3d.axes3d as p3
import matplotlib.pyplot as plt
import colorsys
from PIL import Image

# (1) Import the file to be analyzed!
img_file = Image.open("IMD006.png")
img = img_file.load()

# (2) Get image width & height in pixels
[xs, ys] = img_file.size
max_intensity = 100
hues = {}

# (3) Examine each pixel in the image file
for x in xrange(0, xs):
  for y in xrange(0, ys):
    # (4)  Get the RGB color of the pixel
    [r, g, b] = img[x, y]

# (5)  Normalize pixel color values
r /= 255.0
g /= 255.0
b /= 255.0

# (6)  Convert RGB color to HSV
[h, s, v] = colorsys.rgb_to_hsv(r, g, b)

# (7)  Marginalize s; count how many pixels have matching (h, v)
if h not in hues:
  hues[h] = {}
if v not in hues[h]:
  hues[h][v] = 1
else:
  if hues[h][v] < max_intensity:
    hues[h][v] += 1

1 Ответ

0 голосов
/ 17 ноября 2018

Вы можете сделать это с помощью PIL / Pillow, используя встроенную систему управления цветом и создавая преобразование следующим образом:

#!/usr/local/bin/python3

import numpy as np
from PIL import Image, ImageCms

# Open image and discard alpha channel which makes wheel round rather than square
im = Image.open('colorwheel.png').convert('RGB')

# Convert to Lab colourspace
srgb_p = ImageCms.createProfile("sRGB")
lab_p  = ImageCms.createProfile("LAB")

rgb2lab = ImageCms.buildTransformFromOpenProfiles(srgb_p, lab_p, "RGB", "LAB")
Lab = ImageCms.applyTransform(im, rgb2lab)

И Lab теперь ваше изображение в цветовом пространстве Lab.Если вы продолжите и добавите следующие строки в конец приведенного выше кода, вы можете разделить изображение Lab на составляющие его каналы и сохранить каждое из них как изображения в оттенках серого для проверки.

# Split into constituent channels so we can save 3 separate greyscales
L, a, b = Lab.split()

L.save('L.png')
a.save('a.png')
b.save('b.png')

Итак, если выначните с этого изображения:

enter image description here

вы получите это как L канал:

enter image description here

это канал a:

enter image description here

и канал b:

enter image description here

На мгновение ненаучный канал a должен быть отрицательным / низким, если изображение зеленым, и высоким / положительным, если изображение пурпурноетак это выглядит правильно.И канал b должен быть отрицательным / низким, если изображение синим, и высоким / положительным, где желтый, так что это выглядит довольно хорошо для меня!Что касается канала L, формула от RGB к оттенкам серого выглядит (вне головы) примерно так:

L = 0.2*R + 0.7*G + 0.1*B

Так что можно ожидать, что канал L будет намного ярче, чем изображениезеленый и самый темный там, где синий.


В качестве альтернативы, вы можете сделать это с помощью модуля scikit-image, может быть, даже более просто так:

import numpy as np
from skimage import color, io

# Open image and make Numpy arrays 'rgb' and 'Lab'
rgb = io.imread('image.png')
Lab = color.rgb2lab(rgb)

не уверен на 100% в масштабировании, но я подозреваю, что канал L является плавающим в диапазоне 0..100, и что a и b также являются плавающими в диапазоне -128 .. + 128, хотя я могубыть неправым!

С моим изображением цветового круга выше я получил следующие минимумы / максимумы для каждого канала:

Lab[:,:,0].min()     # L min
32.29567256501352

Lab[:,:,0].max()     # L max
97.13950703971322

Lab[:,:,1].min()     # a min
-86.18302974439501

Lab[:,:,1].max()     # a max
98.23305386311316

Lab[:,:,2].min()     # b min
-107.85730020669489

Lab[:,:,2].max()     # b max
94.47812227647823
...