Как мне назвать мои RGB-каналы, используя cv :: Mat_

Я хочу получить доступ к своим элементам матрицы следующим образом:

frame[i][j].Red

, то есть красный канал (i, j) -го пикселя.

Я пытался:

typedef struct{unsigned char Blue,Green,Red;}Pixel;
typedef cv::Mat_<Pixel> Image;

Однако при попытке imread (), imwrite () или чего-либо другого с таким определенным типом g ++ приветствует меня:

OpenCV Error: Assertion failed (func != 0) in convertTo, file /home/users/mvitkov/projects/opencv-legacy/OpenCV-2.3.1/modules/core/src/convert.cpp, line 937
terminate called after throwing an instance of 'cv::Exception'
what():  /home/users/mvitkov/projects/opencv-legacy/OpenCV-2.3.1/modules/core/src/convert.cpp:937: error: (-215) func != 0 in function convertTo

Обновление: так что нет ответа на мой, вероятно, плохо заданный вопрос. Очень плохо. Суть вопроса заключается в том, как обращаться к отдельным каналам с разумными именами (красный, зеленый, bkue), а не с помощью индексации массива c-era. [2], Duh!

3

Решение

Вот как вы получаете доступ к каждому каналу:

blue = frame.at<cv::Vec3b>(i,j)[0];
green = frame.at<cv::Vec3b>(i,j)[1];
red = frame.at<cv::Vec3b>(i,j)[2];

Приведенный выше код предполагает, что у вас есть 3-канальное изображение, где каждое значение является 8-битный символ без знака (CV_8UC3). Этот тип используется во многих распространенных форматах изображений. Однако, если у вас есть другой тип 3-канального изображения, вот что вы делаете:

  • Если тип изображения 3-канальный с плавающей точкой (CV_32FC3), затем заменить cv::Vec3b с cv::Vec3f
  • Если тип изображения 3-канальный двойной (CV_64FC3), затем заменить cv::Vec3b с cv::Vec3d
  • Если тип изображения 3-канальный int (CV_32SC3), затем заменить cv::Vec3b с cv::Vec3i
  • Если тип изображения 3-канальный короткий int (CV_16SC3) или 16-битный учар (CV_16UC3), затем заменить cv::Vec3b с cv::Vec3s

Не уверены, какой формат изображения вы используете? Попробуйте позвонить getImgType(frame) (см. код ниже).

string getImgType(cv::Mat frame)
{
int imgTypeInt = frame.type();
int numImgTypes = 28; // 7 base types, with 4 channel options each (C1, ..., C4)
int enum_ints[] = {CV_8UC1,  CV_8UC2,  CV_8UC3,  CV_8UC4, CV_8SC1,  CV_8SC2,  CV_8SC3,  CV_8SC4, CV_16UC1, CV_16UC2, CV_16UC3, CV_16UC4, CV_16SC1, CV_16SC2, CV_16SC3, CV_16SC4, CV_32SC1, CV_32SC2, CV_32SC3, CV_32SC4, CV_32FC1, CV_32FC2, CV_32FC3, CV_32FC4, CV_64FC1, CV_64FC2, CV_64FC3, CV_64FC4};
string enum_strings[] = {"CV_8U",  "CV_8UC1",  "CV_8UC2",  "CV_8UC3",  "CV_8UC4", "CV_8SC1",  "CV_8SC2",  "CV_8SC3",  "CV_8SC4", "CV_16UC1",  "CV_16UC2",  "CV_16UC3",  "CV_16UC4", "CV_16SC1", "CV_16SC2", "CV_16SC3", "CV_16SC4", "CV_32SC1", "CV_32SC2", "CV_32SC3", "CV_32SC4", "CV_32FC1", "CV_32FC2", "CV_32FC3", "CV_32FC4", "CV_64FC1", "CV_64FC2", "CV_64FC3", "CV_64FC4"};
for(int i=0; i<numImgTypes; i++)
{
if(imgTypeInt == enum_ints[i]) return enum_strings[i];
}
return "unknown image type";
}
4

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

Если тип изображения 3-канальный короткий int (CV_16SC3) или 16-битный uchar (CV_16UC3), то замените cv :: Vec3b на cv :: Vec3s

это просто не правильно. Я выделил 3-канальное 16-битное изображение без знака один раз < Vec3s> и получил отрицательное значение G: 29096 B: -21671 R: 23413 вернулся.

Если CV_16UC3, адрес Мат с < Vec3w>. Используя это, я получил G: 29096 B: 43865 R: 23413

«s» в CV_16SC3 обозначает подписанный, а не короткий.

0

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector