Странные значения пикселей из объекта OpenCV Mat

Я пытаюсь извлечь пиксели из OpenCV Mat объект. Когда я извлекаю их как Vec4b, это работает хорошо, но когда я использую Scalar, который является стандартом (afaik), то я получаю странные цифры. Как пользоваться Scalar и правильно интерпретировать числа?

Код для извлечения пикселя (0, 0), один раз как Vec4b объявление сразу как Scalar (который находится в Scalar_<double>):

cv::Vec4b vec = stroke.at<cv::Vec4b>(0, 0);
printf("vec: %i, %i, %i\n", vec[0], vec[1], vec[2]);
cv::Scalar sca = stroke.at<cv::Scalar>(0, 0);
printf("sca: %5.1f, %5.1f, %5.1f\n", sca[0], sca[1], sca[2]);

Выход:

vec: 223, 178, 77
sca: -91331626426359316704088074967484318223735050578187982644502863694523413598032925912253837118690612448172200441235555626964757579094862898778997953403371230682094365379726071857064466448183314663075981261984082516073752896735112503485663679145991425485597914964276617645535969580912538709979773360278601728.0, ...

Я ожидаю немного кремового желтого цвета, так что я думаю, что Vec3b верно.

0

Решение

Ну это интересно

Для серой шкалы вы обычно используете cv::Scalar вот так:

Scalar myColor = stroke.at<uchar>(Point(x, y));
std::cout << myColor.val[0] << std::endl;;

За 3-channel цветное изображение вам нужно cv::vec3b вот так:

Vec3b myColor = stroke.at<Vec3b>(Point(x, y));
for(int i = 0; i < 3; i++) std::cout << myColor.val[i] << " ";

Как следует из названия (как видно Вот) скаляр — это единое целое, а не векторная единица. Что может быть путано с показанной документацией Вот. Но что вы можете сделать, если вы должны иметь свои ценности себя как cv::Scalar типа, вы можете просто назначить каждому vec3b Индекс к своему собственному скаляру. то есть:

cv::Scalar b = vec[0];
cv::Scalar g = vec[1];
cv::Scalar r = vec[2];
3

Другие решения

Для .at<_Tp>() Для корректной работы функции необходимо правильно указать тип данных компонента матрицы изображения. Если вам этого не нужно, двоичные данные пикселя будут неверно истолкованы, и вы получите неожиданные результаты.

После того как вы извлекли значение пикселя правильно, вы можете преобразовать его в любой другой универсальный Scalar_<_Tp> типа хочешь. Обычно вы конвертируете его в Scalarкоторый на самом деле является псевдонимом для Scalar_<double>, Преобразование неявным образом выполняется с помощью оператора присваивания (=).

Больше деталей:

Большинство матриц изображения поставляются с кодом типа CV_8UC4 (4 канала, красный, зеленый, синий и альфа). Например. при загрузке цветного изображения из файла JPG матрица изображения будет иметь этот формат. 8U означает «8 бит на канал, целое число без знака» и C4 означает «4 канала на матричный элемент». Соответствующий тип C ++ элементов Scalar_<uchar>, Вы должны приспособить это к универсальному .at<_Tp>() Функция, чтобы заставить это работать:

mat.at<Scalar_<uchar>(y, x)

После правильного извлечения Scalar_<uchar>, вы можете автоматически преобразовать его в Scalar (что на самом деле Scalar_<double>) просто по назначению:

cv::Scalar scalar = mat.at<cv::Scalar_<uchar>>(0, 0);
0

По вопросам рекламы [email protected]