Прежде чем проводить какие-нибудь манипуляции с изображением — его нужно предварительно считать из файла.
В OpenCV для этого используется функция imread().
В C++:
Mat cv::imread( const String & filename, int flags = IMREAD_COLOR )
В Python:
retval = cv2.imread( filename[, flags] )
Возможные параметры (flags):
IMREAD_UNCHANGED
Python: cv.IMREAD_UNCHANGED
Если установлен — возвращает загруженное изображение как есть (с альфа-каналом, иначе он будет обрезан).
IMREAD_GRAYSCALE
Python: cv.IMREAD_GRAYSCALE
— преобразует изображение в одноканальное изображение в оттенках серого (внутреннее преобразование кодека).
IMREAD_COLOR
Python: cv.IMREAD_COLOR
— преобразует изображение в 3-канальное цветное изображение BGR.
IMREAD_ANYDEPTH
Python: cv.IMREAD_ANYDEPTH
— возвращает 16-битное / 32-битное изображение, когда вход имеет соответствующую глубину, в противном случае — преобразует его в 8-битное.
IMREAD_ANYCOLOR
Python: cv.IMREAD_ANYCOLOR
— изображение считывается в любом возможном цветовом формате.
IMREAD_LOAD_GDAL
Python: cv.IMREAD_LOAD_GDAL
— использовать драйвер gdal для загрузки изображения.
IMREAD_REDUCED_GRAYSCALE_2
Python: cv.IMREAD_REDUCED_GRAYSCALE_2
— преобразовать изображение в одноканальное изображение в оттенках серого и уменьшить размер изображения на 1/2.
IMREAD_REDUCED_COLOR_2
Python: cv.IMREAD_REDUCED_COLOR_2
— преобразовать изображение в 3-канальное цветное изображение BGR и уменьшить размер изображения на 1/2.
IMREAD_REDUCED_GRAYSCALE_4
Python: cv.IMREAD_REDUCED_GRAYSCALE_4
— преобразовать изображение в одноканальное изображение в оттенках серого и уменьшить размер изображения на 1/4.
IMREAD_REDUCED_COLOR_4
Python: cv.IMREAD_REDUCED_COLOR_4
— преобразовать изображение в 3-канальное цветное изображение BGR и уменьшить размер изображения на 1/4.
IMREAD_REDUCED_GRAYSCALE_8
Python: cv.IMREAD_REDUCED_GRAYSCALE_8
— преобразовать изображение в одноканальное изображение в оттенках серого и уменьшить размер изображения на 1/8.
IMREAD_REDUCED_COLOR_8
Python: cv.IMREAD_REDUCED_COLOR_8
— преобразовать изображение в 3-канальное цветное изображение BGR и уменьшить размер изображения на 1/8.
IMREAD_IGNORE_ORIENTATION
Python: cv.IMREAD_IGNORE_ORIENTATION
— не поворачивать изображение в соответствии с флагом ориентации EXIF.
Попробуем считать нашу тестовую картинку.
Подключаем нужные библиотеки:
import matplotlib.pyplot as plt %matplotlib inline import cv2 print('OpenCV version:', cv2.__version__)
OpenCV version: 3.4.2
Считаем тестовое изображение:
imgorig = cv2.imread('cat2.jpg') print(type(imgorig)) print(imgorig.shape)
<class 'numpy.ndarray'=""> (278, 345, 3)
Посмотрим на нашу картинку:
plt.imshow(imgorig) plt.show()
Неожиданно! В чём же дело?
А в том, что OpenCV в качестве порядка хранения цветов изображения, по-умолчанию, использует порядок BGR, а matplotlib использует RGB.
Поэтому, при попытке отображении matplotlib-ом изображения, загруженного с помощью OpenCV, возникает путаница в порядке каналов и получается подобный эффект.
Чтобы решить эту проблему, достаточно сконвертировать картинку в RGB-формат при помощи функции cv2.cvtColor().
rgb_img = cv2.cvtColor(imgorig, cv2.COLOR_BGR2RGB) plt.imshow(rgb_img) plt.show()
Отлично!
Остаётся только единственный вопрос:
Почему в OpenCV по-умолчанию используется формат BGR ?
Поиск даёт единственный ответ — по историческим причинам.
В ранних версиях OpenCV использовался порядок BGR, так как тогда именно формат BGR был популярен среди производителей камер и поставщиков программного обеспечения.
Например, в ОС Windows для указания значения цвета с помощью COLORREF используется именно формат BGR:
0x00bbggrr
Вот и выходит, что по историческим причинам, в OpenCV и сейчас, по-умолчанию, используется порядок цветов BGR. Остаётся только помнить об этом.
Ссылки
Image file reading and writing
Why does OpenCV use BGR color format?
COLORREF
По теме
OpenCV шаг за шагом. Загрузка картинки
OpenCV — cравнение алгоритмов интерполяции при изменении размеров изображения