c++ - 如何有效地在OpenCV Mat和GpuMat上进行元素处理?

标签 c++ opencv image-processing

我正在使用 OpenCV C++ 进行图像处理。我想对 Mat 和 GpuMat 按元素 进行一些快速处理。

例如,我必须对 Mat 或 GpuMat 的每个元素应用一个复杂的函数。目前,我正在通过如下循环访问 Mat 的每个元素:

// C++ Example 1: a and b are Mat
for (int i = 0; i < 512; i++) {
    for (int j = 0; j < 512; j++) {
        double sPixel = s.at<double>(512 * i + j);
        if (sPixel >= 0 && sPixel <= 1) {
            a.at<double>(512 * i + j) = double(1);
        } else if (sPixel > 1) {
            b.at<double>(512 * i + j) = double(1);
        }
    }
}

// C++ Example 2: f, x are Mat
for (int i = 0; i < 512; i++) {
    for (int j = 0; j < 512; j++) {
        f.at<double>(512 * i + j) = (1 / (2 * sigma)) * (1 + cos(pi * x.at<double>(512 * i + j) / sigma));
    }
}

但是我觉得这种方法比较慢,因为Mat的元素之间没有实际的关系,如果按元素并行计算会更好。

另一方面,我无法访问 GpuMat 的元素。如果我经常在 Mat 和 GpuMat 之间downloadupload 数据,速度会非常慢,使用 GPU 的优势就不存在了。

所以我的问题是:

  1. 在 Mat 和 GpuMat 上进行元素处理有哪些改进方法? 尤其是 OpenCV 本身提供的那些。
  2. GpuMat 上的元素处理怎么做?

最佳答案

  1. 您只需使用内置的 openCV 函数来执行每个元素的操作。例如。您有用于矩阵加法、减法或矩阵和标量的重载矩阵运算符、用于逐元素乘法、除法、绝对差、三角函数、幂、根等的函数。它们通常与标准库数学函数具有相同的名称。只需搜索文档。要比较第一个示例中的矩阵元素,请使用 matrix expressions .

  2. 这实际上与第 1 点相同。您必须检查 openCV 提供的功能,并将您的操作分成可能使用这些功能执行的步骤。例如。这是此类功能的不错列表:

http://docs.opencv.org/2.4/modules/gpu/doc/per_element_operations.html

http://docs.opencv.org/trunk/d8/d34/group__cudaarithm__elem.html

如果以上功能对您来说还不够,请避免使用 at() 方法访问像素,因为这是非常低效的,在遍历所有像素时不推荐这样做。使用 ptr()函数而不是访问整行。

下面是如何使用上述技术转换计算的示例:

//first example
b = (s > 1);
a = (s >= 0).mul(s <= 1);

//second example
f = (1 / (2*sigma)) * ((1 + cos_mat) / sigma);

在 openCV 中没有每个元素的 cos() 函数,但是如果你想要性能,你可以将余弦实现为泰勒级数,这将等于几个每个元素的乘法和减法/添加,并以这种方式获得 cos_mat 矩阵。你可以在这里找到一个例子:

http://answers.opencv.org/question/55602/sine-or-cosine-of-every-element-in-mat-c/

关于c++ - 如何有效地在OpenCV Mat和GpuMat上进行元素处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45436818/

相关文章:

c++ - 未定义对 Armadillo 的 LAPACK 包装器的引用

c++ - 模板和字符串转换

c++ - OpenCv 中的 stitcher() 错误

c++ - 如何推断 lambda 的返回类型?

c++ - 由于已达到数组的最大内存分配,因此无法编译Modelica程序(编译器的堆空间不足)

c++ - 使用imwrite OpenCV时断言失败

python - AttributeError: 'module' object has no attribute 'HOUGH_GRADIENT' , cv.HOUGH_GRADIENT 没有解决这个问题

image-processing - 如何匹配图像中的纹理相似性?

java - 来自谷歌地图的图像区域/树检测

wpf - 将图像加载到 ImageSource - 不正确的宽度和高度