【问题标题】:How to do by element processing on OpenCV Mat and GpuMat effectively?如何有效地对 OpenCV Mat 和 GpuMat 进行元素处理?
【发布时间】:2018-01-08 06:16:20
【问题描述】:

我正在使用 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 的元素。如果我downloadupload在Mat和GpuMat之间频繁数据,会非常慢,不存在使用GPU的优势。

所以我的问题是:

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

【问题讨论】:

标签: c++ opencv image-processing


【解决方案1】:
  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() 函数,但是如果你想要性能,你可以将余弦实现为泰勒级数,这将等于几个每个元素的乘法和减法/加法,并获得 @987654329 @矩阵那样。你可以在这里找到一个例子:

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

【讨论】:

  • 感谢ptr()的建议,我稍后试试。但是内置函数对我来说总是不够的......你对遍历 GpuMat 有任何想法吗?
  • 就您目前在示例中展示的目的而言,内置函数已经绰绰有余。请查看我更新的答案 - 我已经向您展示了如何将操作拆分为基本的 opencv 函数。您只需要一些练习来习惯于考虑矩阵运算,而不是传统的每元素数学。您可以对 GpuMat 执行相同的操作,但 GpuMat 的可用函数集较少。
  • 谢谢KjMag,这对我很有帮助。以后我会重写我所有的代码。
  • 没问题,很高兴我能帮上忙。
  • 我认为 OpenCV 没有将三角函数应用于矩阵的内置方法
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-01-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-23
  • 1970-01-01
  • 2017-06-06
  • 1970-01-01
相关资源
最近更新 更多