Как получить доступ к одноканальной матрице в OpenCV

0

Я хочу спросить, можно ли получить доступ к одноканальной матрице, используя img.at<T>(y, x) вместо этого используя img.ptr<T>(y, x)[0]

В приведенном ниже примере я создаю простую программу для копирования изображения в другое

cv::Mat inpImg = cv::imread("test.png");
cv::Mat img;  
inpImg.convertTo(img, CV_8UC1); // single channel image

cv::Mat outImg(img.rows, img.cols, CV_8UC1);

for(int a = 0; a < img.cols; a++)
    for(int b = 0; b < img.rows; b++)
        outImg.at<uchar>(b, a) = img.at<uchar>(b, a);   // This is wrong

cv::imshow("Test", outImg);

Показанный результат был неправильным, но если я изменю его на

outImg.ptr<uchar>(b, a)[0] = img.ptr<uchar>(b, a)[0];

Результат был верным.

Я довольно озадачен, так как img.at<T>(y, x) также должен быть в порядке. Я также пытался с 32FC1 и плавать, результат схож.

  • 0
    На моем ПК все работает нормально. Не уверен насчет проблемы здесь ...
  • 0
    Кстати, вы можете просто сделать Mat outImg = img.clone ();
Показать ещё 1 комментарий
Теги:
opencv
image-processing

1 ответ

2

Хотя я знаю, что вы его уже нашли, настоящая причина, хорошо cv::convertTo на документацию, заключается в том, что cv::convertTo игнорирует количество каналов, подразумеваемых типом вывода, поэтому, когда вы это делаете:

inpImg.convertTo(img, CV_8UC1); 

И, предполагая, что ваше входное изображение имеет три канала, на самом деле вы CV_8UC3 формат CV_8UC3, который объясняет, почему ваш первоначальный обходной путь был успешным - эффективно, вы сделали только один канал:

outImg.ptr<uchar>(b, a)[0]     // takes the first channel of a CV_8UC3

Это только срабатывало случайно, поскольку пиксель должен был быть доступен следующим образом:

outImg.ptr<Vec3b>(b, a)[0]     // takes the blue channel of a CV_8UC3

Поскольку данные по - прежнему упакованы uchar в обоих случаях эффективное переосмысление случилось работать.

Как вы отметили, вы можете преобразовать в оттенки серого при загрузке:

cv::imread("test.png", CV_LOAD_IMAGE_GRAYSCALE)

Или вы можете явно преобразовать:

cv::cvtColor(inpImg, inpImg, CV_BGR2GRAY);

Ещё вопросы

Сообщество Overcoder
Наверх
Меню