我正在使用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的优势。
所以我的问题是:
答案 0 :(得分:2)
您只需使用内置的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/