Использование функции переназначения открытого CV с исходным изображением типа CV_8SC1 - PullRequest
2 голосов
/ 14 марта 2019

Использование функции переназначения открытого 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 и затем заканчиваю с помощью функции remap.

Ошибка, которую я получаю с этими двумя типами:

terminate вызывается после бросания экземпляра 'cv :: Exception 'what (): OpenCV (4.0.1-dev) /home/aljaz/opencv_build/opencv/modules/imgproc/src/imgwarp.cpp:1805: ошибка: (-215: утверждение не выполнено) ifunc! =0 в функции 'remap'

1 Ответ

2 голосов
/ 14 марта 2019

Если вы посмотрите в коде 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. Также с целыми числами вы должны заботиться о количественном определении.

Когда вы получаете "утверждать" ошибки, это обычно происходит потому, что вы не выполняете ожидаемые / реализованные входные типы данных или формы (размер изображения / количество каналов).

Надеюсь, это поможет!

...