Второй аргумент imread
определяет способ чтения изображения.Значение по умолчанию IMREAD_COLOR
, что означает, что:
В случае цветных изображений декодированные изображения будут иметь каналы, сохраненные в порядке BGR.( из ссылки )
, поэтому ваш результат mat имеет разрешение 256x256
и каждый пиксель описывается 3 значениями: для хранения Blue , Зеленый и Красный компонент пространства цвета.Эти компоненты хранятся по типу uchar
(диапазон [0,255)
).
2D-изображения в OpenCV хранятся построчно.Приведенную ниже формулу можно использовать для вычисления адреса элемента M(row,col)
:
addr(M[row,col]) = data + step1 * row + step2 * col
, где data
- первый байт массива, в котором хранятся данные изображения.Ваш мат имеет 3 канала, а ширина изображения 256
, поэтому step1
равно 256 * 3
(это число столбцов в строке, умноженное на количество каналов на пиксель), а step2
равно 3
.
Теперь давайте откроем исходный код at
функции-члена:
template<typename _Tp> inline
_Tp& Mat::at(int i0, int i1) {
return ((_Tp*)(data + step.p[0] * i0))[i1];
}
// i0 means row, i1 means col
в вашем коде вы указываете _Tp
как uchar
.Теперь просто правила работы с арифметикой указателей, которые позволяют получить доступ только к 1/3 входного изображения.Например, когда вы звоните <uchar>(0,1)
, вы получаете доступ к Зеленому компоненту (0,0)
пикселей.
Чтобы решить вашу проблему, вы должны передать Vec3b
в списке аргументов шаблона:
image.at<cv::Vec3b>(row, col) = cv::Vec3b(255,255,255);
(каждый компонент Vec3b имеет тип uchar
).