У меня есть матрица с 3 каналами, и у меня проблема с доступом и изменением значения элементов. У меня есть этот код:
Mat m(4,4, CV_8UC3);
Vec3b a;
a[0] = 255;
a[1] = 0;
a[2] = 0;
m.at<Vec3b>(0,0) = a;
когда я печатаю матрицу m, у меня есть это:
[255, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0;
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
это хорошо, но изображение, которое я получаю, когда храню матрицу с imwrite
это один:
и я не понимаю, почему это синий и почему у меня квадрат 2х2 синего цвета, у меня должен был быть только первый красный пиксель нет?
Я где-то сделал ошибку?
Как упоминалось ранее, пиксели рядом с пикселем высокой интенсивности принимают ненулевые значения после сжатия JPG, поскольку JPEG является алгоритмом с потерями. Фактически, JPEG-сжатие отбрасывает информацию именно в областях изображения с сильным градиентом.
Что касается вашего второго вопроса: ваши пиксели синие из-за причуд Opencv: цветовые каналы хранятся не в порядке R, G, B, а в порядке B, G, R:
Для цветных изображений порядок каналов обычно синий, зеленый, красный
Источник: http://docs.opencv.org/modules/core/doc/drawing_functions.html?highlight=green
(это одна из тех вещей, которые делают жизнь программиста Opencv несчастной)
Я не понимаю, почему это синий … не красный?
В OpenCV формат изображения устанавливается флагом при создании изображения, например, CV_8UC3
означает 8-битные пиксели, без знака, 3 цветовых канала. В цветном изображении порядок пикселей BGR
Данные хранятся в порядке строк. Так же, BGRA
за CV_8UC4
, Таким образом, значение, которое вы устанавливаете, — синий, а не красный, поэтому вы получили синий.
Я должен был иметь только первый пиксель …?
Причина в том, что для сжатых типов изображений, например JPG
, они не могут гарантировать точное содержание. Пробовать imwrite()
на несжатый, например, BMP
изображение (как правило). Вы получите изображение как: