Импорт изображения в градациях серого и преобразование его в градации серого не дает того же результата при умножении его на 255 - PullRequest
1 голос
/ 22 июня 2019

В настоящее время я работаю над проектом по изоляции номерного знака от изображения.

Когда я импортирую изображение, используя cv2.imread("filename",0), полученное мной изображение в градациях серого более или менее одинаково (возможно, несколько различий в округлении из-за того, что я конвертирую его в целые числа.) Когда я импортирую его, используя cv2.imread("filename") а затем преобразовать его в оттенки серого, используя np.dot(original_image[...,:3], [0.299, 0.587, 0.144]).

Однако, когда я умножаю оба значения ndarrays на 255, я не получаю одинаковые выходные матрицы. Оба изображения в градациях серого имеют одинаковые размеры, выдают одинаковый результат при преобразовании их в фигуру, имеют одинаковый тип и одинаковый порог otsu. Почему это происходит? OpenCV отображает и сохраняет изображение ndarrays по-другому?

Как я могу манипулировать вторым изображением в градациях серого для получения того же результата, что и первое изображение в градациях серого, после умножения его на 255?

def func():
    rgb_image=cv2.imread('filename')
    gray_image=cv2.imread('filename',0)

    rgb_converted_to_gray_image=np.dot(rgb_image[...,:3], [0.299, 0.587, 0.144])

    print("Before multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)

    gray_image=gray_image*255
    rgb_converted_to_gray_image=rgb_converted_to_gray_image*255

    print("After multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)

Вывод выглядит следующим образом:

Перед умножением на 255

[[32 29 34 ... 92 88 86]
 [33 28 32 ... 85 85 86]
 [35 29 28 ... 85 93 99]
 ...
 [ 8  8  8 ... 32 32 32]
 [ 8  8  8 ... 32 32 32]
 [ 8  8  8 ... 33 33 33]]
------------
[[ 27.512  24.721  29.129 ... 105.014 100.894  98.989]
 [ 29.14   23.99   27.069 ...  97.804  97.804  99.432]
 [ 30.912  25.02   23.547 ...  98.701 106.797 112.977]
 ...
 [  9.292   9.292   9.292 ...  33.558  33.558  33.558]
 [  9.292   9.292   9.292 ...  33.558  33.558  33.558]
 [  9.292   9.292   9.292 ...  34.588  34.588  34.588]]

После умножения на 255:

[[224 227 222 ... 164 168 170]
 [223 228 224 ... 171 171 170]
 [221 227 228 ... 171 163 157]
 ...
 [248 248 248 ... 224 224 224]
 [248 248 248 ... 224 224 224]
 [248 248 248 ... 223 223 223]]
------------
[[ 7015.56   6303.855  7427.895 ... 26778.57  25727.97  25242.195]
 [ 7430.7    6117.45   6902.595 ... 24940.02  24940.02  25355.16 ]
 [ 7882.56   6380.1    6004.485 ... 25168.755 27233.235 28809.135]
 ...
 [ 2369.46   2369.46   2369.46  ...  8557.29   8557.29   8557.29 ]
 [ 2369.46   2369.46   2369.46  ...  8557.29   8557.29   8557.29 ]
 [ 2369.46   2369.46   2369.46  ...  8819.94   8819.94   8819.94 ]]69.46  ...  8819.94   8819.94   8819.94 ]]

Таким образом, я хотел бы, чтобы последняя матрица выглядела так же, как та, что над ней.

1 Ответ

1 голос
/ 23 июня 2019

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

  1. Разница в типе данных
  2. Порядок каналов

Первая причина, как отметил @Cris Luengo в комментарии, - это разница в типе данныхмежду gray_image и rgb_converted_to_gray_image.gray_image имеет тип uint8, тогда как rgb_converted_to_gray имеет тип float32.В результате умножения на 255 значения gray_image масштабируются до диапазона uint8.Чтобы обойти эту проблему, вы можете выполнить умножение с плавающей запятой, просто изменив 255 на 255.0.

gray_image = gray_image * 255.0

Теперь возникает вторая проблема.Даже если мы сделаем умножение с плавающей запятой, результаты будут другими, потому что изображения OpenCV по умолчанию хранятся в канальном порядке BGR, а коэффициенты преобразования серой шкалы в порядке RGB.Также коэффициент для синего значения неверен.Это должно быть 0.114 вместо 0.144.Чтобы проверить логическую правильность значений коэффициентов RGB, убедитесь, что их сумма равна 1. Исправленный массив коэффициентов должен выглядеть следующим образом:

[0.114, 0.587, 0.299]

Окончательный код может выглядеть следующим образом:

def func():
    rgb_image=cv2.imread('filename')
    gray_image=cv2.imread('filename',0)

    rgb_converted_to_gray_image=np.dot(rgb_image[...,:3], [0.114, 0.587, 0.299])

    print("Before multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)

    gray_image=gray_image*255.0
    rgb_converted_to_gray_image=rgb_converted_to_gray_image*255

    print("After multiplying with 255")
    print(gray_image)
    print("------------")
    print(rgb_converted_to_gray_image)
...