【问题标题】:Per-pixel lookup-table每像素查找表
【发布时间】:2020-09-21 07:37:29
【问题描述】:

我想知道是否有另一种方法可以在 Opencv 中创建逐像素查找表。我现在所拥有的适用于小分辨率(每秒约 4 帧),但在高分辨率(小于每秒 1 帧)上运行缓慢。

我读到我可以使用 CUDA,但不知道如何使用它。如果这是唯一能有人指出我正确方向的方法吗?谢谢。

In header file:
    Mat_<Vec<uchar,256>> _GB;
    Mat_<Vec<uchar,256>> _GG;
    Mat_<Vec<uchar,256>> _GR;
…
Mat VideoProcessor::CamCalib(Mat _tempFrame)
{

    Mat_<Vec3b> _frame = _tempFrame;

    for( int i = 0; i < _tempFrame.rows; ++i)
        for( int j = 0; j < _tempFrame.cols; ++j )
        {
            _frame(i,j)[0] = _GB(i,j)[ _frame(i,j)[0] ];
            _frame(i,j)[1] = _GG(i,j)[ _frame(i,j)[1] ];
            _frame(i,j)[2] = _GR(i,j)[ _frame(i,j)[2] ];
        }

    _tempFrame = _frame;

    return _tempFrame;
}

【问题讨论】:

  • 为什么要这样做?为每个像素的每个组件创建一个大小为 256 的表似乎非常昂贵!例如,对于 1080p 图像,您需要为仅占用 6 Mio 的图片分配和填充 1.5 Gio 的内存!话虽如此,请注意您可以使用多线程来加速此代码(例如,使用 OpenMP)。
  • 我只会使用 cuda 来改进你需要做的任何计算

标签: c++ algorithm performance opencv lookup


【解决方案1】:

做了一些微调。(在帖子末尾添加了校正前后的图像)

(1) 假设所有 4 个象限的镜头球面形状相同,我能够进一步将帧速率提高到 9fps,以实现 1920x1080 分辨率。

(2) 强制减少线程,将 CPU 使用率从 100% 降低到 80%

(3) 使用更少的内存,查找表大小为原来的1/4

注意:必须处于“发布”模式才能使 openMP 正常运行!再次感谢杰罗姆!

Mat VideoProcessor::CamCalib(Mat _tempFrame)
{

    Mat_<Vec3b> _frame = _tempFrame;
    int nrows = _tempFrame.rows-1;
    int ncols = _tempFrame.cols-1;

#pragma omp parallel for num_threads(2)
    for( int i = 0; i < _tempFrame.rows/2; ++i)
        for( int j = 0; j < _tempFrame.cols/2; ++j )
        {
            _frame(i,j)[0] = _GB(i,j)[_frame(i,j)[0]];
            _frame(i,j)[1] = _GG(i,j)[_frame(i,j)[1]];
            _frame(i,j)[2] = _GR(i,j)[_frame(i,j)[2]];

            _frame(nrows-i,j)[0] = _GB(i,j)[_frame(nrows-i,j)[0]];
            _frame(nrows-i,j)[1] = _GG(i,j)[_frame(nrows-i,j)[1]];
            _frame(nrows-i,j)[2] = _GR(i,j)[_frame(nrows-i,j)[2]];

            _frame(i,ncols-j)[0] = _GB(i,j)[_frame(i,ncols-j)[0]];
            _frame(i,ncols-j)[1] = _GG(i,j)[_frame(i,ncols-j)[1]];
            _frame(i,ncols-j)[2] = _GR(i,j)[_frame(i,ncols-j)[2]];

            _frame(nrows-i,ncols-j)[0] = _GB(i,j)[_frame(nrows-i,ncols-j)[0]];
            _frame(nrows-i,ncols-j)[1] = _GG(i,j)[_frame(nrows-i,ncols-j)[1]];
            _frame(nrows-i,ncols-j)[2] = _GR(i,j)[_frame(nrows-i,ncols-j)[2]];
        }

    _tempFrame = _frame;

    return _tempFrame;
}

Before and After correction

【讨论】:

    【解决方案2】:

    谢谢杰罗姆,我听从了你的建议。一个简单的实现,性能提高了 25%。对我来说,由于我正在使用软件镜头校正进行实时图像捕获,因此内存不如速度那么昂贵。

    这是我添加的内容:

    在 Pro 文件中添加: QMAKE_CXXFLAGS += -openmp

    在 CPP 文件中添加: #include "omp.h" ... 并在方法中的“for循环”之前添加: #pragma omp parallel for

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-13
      • 2013-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-02-09
      • 2012-10-15
      相关资源
      最近更新 更多