将开放式CV的重映射功能与类型为CV_8SC1的源图像一起使用

时间:2019-03-14 08:07:33

标签: c++ opencv remap

使用开放式CV的remap函数处理不同类型的源图像会给我带来一些有趣的结果。

以下类型可以正常工作: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,在循环中使用它们,然后完成remap函数。

这两种类型的错误是:

抛出'cv :: Exception'实例后调用

terminate   what():OpenCV(4.0.1-dev)/home/aljaz/opencv_build/opencv/modules/imgproc/src/imgwarp.cpp:1805:error:(-215:Assertion failed)ifunc!= 0 in function'remap '

1 个答案:

答案 0 :(得分:2)

如果您查看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
    };

因此,尽管最近邻插值允许使用带符号的char类型,但双线性插值并非如此。所有组合均未实现。

可以与OpenCV一起使用的IPP(用于图像处理的Intel库)不允许签名char操作:https://software.intel.com/en-us/ipp-dev-reference-remap。据我了解,英特尔在性能方面没有意义的情况下不提供此类实现(即,它们未提供将函数内部的8s转换为16s,计算某些内容并转换回8s的功能)。此外,支持数据类型,插值类型,通道数量的所有组合肯定需要做一些工作,因此专注于最常用的类型也很好。

如果您没有绝对需要使用整数的性能瓶颈,我建议将其转换为float。另外,对于整数,您还必须注意量化。

当您收到“断言”错误时,通常是因为您不符合预期/实现的输入数据类型或形状(图像大小/通道数)。

希望这会有所帮助!