#c #opencv #remap
#c #opencv #переназначение
Вопрос:
Использование функции переназначения open CV с различными типами исходных изображений дало мне несколько интересных результатов.
Следующие типы работают должным образом: CV_8UC1, CV_16UC1, CV_16SC1, CV_32FC1, CV_64FC1.
Два типа, которые выдают мне ошибку: CV_8SC1, CV_32SC1.
Интересная часть заключается в том, что CV_16SC1 работает, а CV_8SC1 — нет.
У кого-нибудь есть какие-либо идеи относительно того, почему это происходит?
Это мой код, который я использую:
cv::Mat remapX, remapY;
remapX.create(output_cv_mat.rows, output_cv_mat.cols, CV_32FC1);
remapY.create(output_cv_mat.rows, output_cv_mat.cols, CV_32FC1);
for(int x = 0; x < remapX.cols; x ) //Column iteration
{
for(int y = 0; y < remapX.rows; y ) //Row iteration
{
remapX.at<float>(y, x) = (float)(x);
remapY.at<float>(y, x) = (float)(remapX.rows - y);
}
}
cv::remap(source_cv_mat, output_cv_mat, remapX, remapY, cv::INTER_LINEAR, cv::BORDER_CONSTANT, cv::Scalar(0, 0, 0));
Код использует исходный cv:: Mat (тот, который я тестирую) и выводит cv::Mat. Я создаю карты X и Y, использую их в циклах for, а затем завершаю с помощью функции переназначения.
Ошибка, которую я получаю с этими двумя типами, является:
завершение вызывается после создания экземпляра ‘cv::Exception’ what(): OpenCV(4.0.1-dev) /home/aljaz/opencv_build/opencv/modules/imgproc/src/imgwarp.cpp:1805: ошибка: (-215: ошибка утверждения) ifunc != 0 в функции ‘переназначения’
Комментарии:
1. Потому что эти варианты не реализованы. Смотрите исходный код . Я не знаю, почему они не реализованы, но вы можете преобразовать свое изображение в более широкий тип и использовать доступные реализации
2. Тип вывода такой же, как и тип ввода (я установил это при создании выходного cv::Mat)
3. да, затем выполните узкое преобразование к исходному типу
Ответ №1:
Если вы посмотрите в код cv::remap, вы можете увидеть следующую проверку совместимости типов данных с типами интерполяции:
static RemapNNFunc nn_tab[] =
{
remapNearest<uchar>, remapNearest<schar>, remapNearest<ushort>, remapNearest<short>,
remapNearest<int>, remapNearest<float>, remapNearest<double>, 0
};
static RemapFunc linear_tab[] =
{
remapBilinear<FixedPtCast<int, uchar, INTER_REMAP_COEF_BITS>, RemapVec_8u, short>, 0,
remapBilinear<Cast<float, ushort>, RemapNoVec, float>,
remapBilinear<Cast<float, short>, RemapNoVec, float>, 0,
remapBilinear<Cast<float, float>, RemapNoVec, float>,
remapBilinear<Cast<double, double>, RemapNoVec, float>, 0
};
Итак, несмотря на то, что тип символа со знаком разрешен для интерполяции ближайшего соседа, это не относится к билинейной интерполяции. Не все комбинации реализованы.
IPP (библиотека Intel для обработки изображений), которая может использоваться с OpenCV, также не допускает операции со знаком символа:https://software.intel.com/en-us/ipp-dev-reference-remap . В моем понимании, Intel не предоставляет такие реализации, когда они не имеют смысла с точки зрения производительности (т. Е. Они не предоставляют функцию, которая преобразует 8 секунд в 16 секунд внутри функции, вычисляет что-то и преобразует обратно за 8 секунд). Кроме того, поддержка всех комбинаций типов данных, типов интерполяции, количества каналов, безусловно, требует некоторой работы, поэтому также неплохо сосредоточиться на наиболее используемых типах.
Если у вас нет проблем с производительностью, которые абсолютно требуют работы с целыми числами, я бы рекомендовал преобразовать в float . Также с целыми числами вы должны позаботиться о количественной оценке.
Когда вы получаете ошибки «assert», это обычно потому, что вы не соответствовали ожидаемым / реализованным типам входных данных или формам (размер изображения / количество каналов).
Надеюсь, это поможет!