преобразование цветового пространства в opencv (RGB -> LAB) - красный не дает ожидаемых значений - PullRequest
1 голос
/ 05 августа 2020

Следующее создает красное изображение с использованием цвета RGB 255,0,0

import numpy as np
import matplotlib.pyplot as plt
import cv2

width = 5
height = 2

array = np.zeros([height, width, 3], dtype=np.uint8)
array[:,:] = [255, 0, 0] # make it red

print(array)

plt.imshow(array)
plt.show()

Вывод:

[[[255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]]

 [[255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]
  [255   0   0]]]

enter image description here

If I transform the array into the LAB space:

array = cv2.cvtColor(array, cv2.COLOR_BGR2LAB)

print(array)

The results look like this:

[[[ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]]

 [[ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]
  [ 82 207  20]]]

According to http://colorizer.org/ значение красного должно быть:

lab(53.23, 80.11, 67.22)

Почему opencv выдает разные значения? Я что-то упускаю? Есть ли сайт, на котором я могу найти, например, красный цвет в номерах цветов Lab для opebcv? Спасибо.

PS:

Одна проблема заключается в том, что я использовал COLOR_BGR2LAB вместо COLOR_RGB2LAB (спасибо Марку Сетчеллу), но это все еще не приводит к ожидаемому вектору 53.23, 80.11, 67.22, который дает: 54,4 83,2 78. что не близко, но не то же самое ...

import numpy as np
import matplotlib.pyplot as plt
import cv2

width = 5
height = 2

array = np.zeros([height, width, 3], dtype=np.uint8)
array[:,:] = [255, 0, 0] # make it red

print(array)

array = cv2.cvtColor(array, cv2.COLOR_RGB2LAB)
array = array / 2.5

print(array)

1 Ответ

2 голосов
/ 05 августа 2020

Вы создали изображение в порядке RGB, поэтому это

array = cv2.cvtColor(array, cv2.COLOR_BGR2LAB)

должно быть:

array = cv2.cvtColor(array, cv2.COLOR_RGB2LAB)

Если вы отображаете его с помощью OpenCV cv2.imshow(array) и cv2.waitKey() вы увидите OpenCV считает его синим.

Что касается несоответствия, которое вы видите между онлайн-конвертером и OpenCV , я могу только предположить, что это как-то связано с ошибками округления, возникающими из-за использования uint8 для значений RGB. Если преобразовать в тип float, проблема исчезнет:

Lab = cv2.cvtColor(array.astype(np.float32), cv2.COLOR_RGB2LAB)

# Result
array([[[53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125]],

       [[53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125],
        [53.240967, 80.09375 , 67.203125]]], dtype=float32)

В стороне, отмечу, что scikit-image выбирает автоматически возвращать вам float, когда вы его передаете uint8:

from skimage import color
import numpy as np

# Make a rather small red image
array = np.full((1, 1, 3), [255,0,0], dtype=np.uint8)

# Convert to Lab with scikit-image
Lab = color.rgb2lab(array)

# Result
array([[[53.24058794, 80.09230823, 67.20275104]]])

Просто для удовольствия, пока мы занимаемся этим, проверьте, что ImageMagick делает это:

magick xc:red -colorspace lab txt:
# ImageMagick pixel enumeration: 1,1,65535,cielab
0,0: (34891.4,53351.7,17270.9)  #884BD068C376 cielab(53.2408,80.0943,67.202)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...