我正在使用 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 之间download
和 upload
数据,速度会非常慢,使用 GPU 的优势就不存在了。
所以我的问题是:
- 在 Mat 和 GpuMat 上进行元素处理有哪些改进方法? 尤其是 OpenCV 本身提供的那些。
- GpuMat 上的元素处理怎么做?
最佳答案
您只需使用内置的 openCV 函数来执行每个元素的操作。例如。您有用于矩阵加法、减法或矩阵和标量的重载矩阵运算符、用于逐元素乘法、除法、绝对差、三角函数、幂、根等的函数。它们通常与标准库数学函数具有相同的名称。只需搜索文档。要比较第一个示例中的矩阵元素,请使用 matrix expressions .
这实际上与第 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/