Методы OpenCV clone() и copyTo() не создают Mat того же типа, что и оригинал?

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

cv::Mat result;
result = image.clone();
cv::watershed(image, result);

При выполнении это приводит к следующей ошибке:

segmentation.cpp:159: error: (-215) src.type() == CV_8UC3 && dst.type() == CV_32SC1 
in function watershed

Ошибка, безусловно, правильная, как я проверял с type2str функция в этом посте SO: Как узнать, какой тип объекта Mat есть с Mat::type() в OpenCV

Я также пытался использовать image.copyTo(result) вместо clone(), но это выдает то же сообщение об ошибке. Что я делаю не так, и как я могу скопировать Mat получить такой же тип?

Я предполагаю, что хакерское решение состояло бы в том, чтобы преобразовать цвет результата, чтобы соответствовать цвету изображения, как здесь сделано: OpenCV: Как преобразовать мат CV_8UC1 в CV_8UC3, но это кажется неправильным, нет?

1 ответ

Решение

Как также упоминалось здесь: Разница Clone CopyTo, в этом контексте нет никакой разницы между clone() а также copyTo(),

На самом деле, исходный код clone() как следует:

inline Mat Mat::clone() const
{
    Mat m;
    copyTo(m);
    return m;
}

copyTo однако может использоваться в сочетании с маской и, в общем, копировать данные в другую матрицу, что может быть полезно, например, для рисования подизображения в другом изображении.

Что касается кода для watershed, документация гласит,

  • image - Ввод 8-битного 3-канального изображения.
  • маркеры - ввод / вывод 32-битного одноканального изображения (карты) маркеров. Он должен иметь тот же размер, что и изображение.

Так image (ваш image) а также markers (ваш result) не должно быть одинаковым.

Перед передачей изображения в функцию необходимо приблизительно обвести нужные области в маркерах изображения с помощью положительных (>0) индексов. Таким образом, каждый регион представлен как один или несколько связанных компонентов со значениями пикселей 1, 2, 3 и так далее. Такие маркеры могут быть извлечены из двоичной маски с помощью findContours() и drawContours() (см. Демонстрацию watershed.cpp). Маркеры являются "семенами" будущих областей изображения. Все остальные пиксели в маркерах, чье отношение к выделенным областям неизвестно и должно определяться алгоритмом, должны быть установлены в 0. В выходных данных функции каждому пикселю в маркерах присваивается значение "начальных" компонентов или -1 на границах между областями.

Визуальную демонстрацию и пример использования функции можно найти в каталоге примеров OpenCV (см. Демонстрацию watershed.cpp).

Другие вопросы по тегам