c++ - 使用 open CV 的重映射函数和 CV_8SC1 类型的源图像

标签 c++ opencv remap

将开放 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”实例后调用终止 什么():OpenCV(4.0.1-dev)/home/aljaz/opencv_build/opencv/modules/imgproc/src/imgwarp.cpp:1805:错误:(-215:断言失败)ifunc!= 0函数'remap '

最佳答案

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

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

可与 OpenCV 一起使用的 IPP(英特尔图像处理库)也不允许有符号字符操作:https://software.intel.com/en-us/ipp-dev-reference-remap 。根据我的理解,当英特尔在性能方面没有意义时,不会提供此类实现(即,他们不提供在函数内部将 8 秒转换为 16 秒、计算某些内容并在 8 秒内转换回来的函数)。此外,支持数据类型、插值类型、 channel 数的所有组合肯定需要一些工作,因此专注于最常用的类型也可以。

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

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

希望这有帮助!

关于c++ - 使用 open CV 的重映射函数和 CV_8SC1 类型的源图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55157623/

相关文章:

c# - 使用 AutoGen FFmpeg 库在 MP4 中同步音频/视频

c++ - 使用 OpenCV 在同一窗口中显示多个图像

visual-studio - Visual Studio 2010 : How Can I remap F2 to Rename File rather than Open Object Browser

c# - 'remap' 一个简单的二进制掩码的最佳方法?

emacs - 重新映射 Emacs 命令

c++ - 为什么 std::plus 是一个类模板?

c++ 可以通过引用传递临时 lambda(适用于 msvc/windows 但不适用于 gcc/linux)吗?

c++ - OpenCV:期望最大化的预测函数的输出

c++ - 如何知道帧或图像的大小

python - 将图像从 float32 转换为 uint8 时,蒙版对象消失