在OpenCV中计算矩阵元素的总和?

29

我需要对矩阵中的所有元素求和。我使用了这个函数:

  sum(sum(A)); 

在matlab中,A是一个大小为300*360的矩阵。我想在OpenCV中实现相同的功能。我使用了类似于以下内容的代码。

  double s=cv::sum(cv::sum(A));

但是出现了错误,显示无法将标量转换为双精度。如何解决这个问题?


8
在Matlab中,最好使用sum(A(:))而不是sum(sum(A)) - bla
2
可能是OpenCV:获取Mat值的总和的重复问题。 - m0nhawk
3个回答

54

与Matlab不同,opencv中的cv::sum(A)会沿着所有维度求和并返回一个等于Matlab的sum(sum(A))的标量(单个数字)。
因此,你需要的是

double s = cv::sum(A)[0];

14
如果A是一通道矩阵,那么cv::Scalar s = cv::sum(A);的写法不太正确,应该改为:double psum = cv::sum(A)[0];。这样可以得到矩阵A所有元素的和。请注意,不要改变原有语句的含义。 - berak
1
[0] 代表什么?有人可以解释一下吗? - kadu
26
cv::sum 返回一个 cv::Scalar 元素。例如,如果你有一张3通道的图像,则返回值将有3个元素,每个通道都会单独求和。[0] 将访问该标量的第一个值。对于具有BGR顺序的RGB图像(如OpenCV中常用的),标量的 [0] 将访问总和的"蓝色通道", [1] 是"绿色通道"的总和,而 [2] 是该示例中"红色通道"的总和。http://docs.opencv.org/modules/core/doc/operations_on_arrays.html#sum - Micka
1
我可以将一个 Mat 对象传递给这个函数吗? - Romantic Electron
4
这样做的原因是因为cv::Mat是运行时类型;无论数组实际包含uint8、int16、float等类型,都会调用相同的cv::sum()函数;因此所有情况都必须返回相同的类型。‘Scalar’ 包含4个双精度浮点数,可以容纳所有情况(最多4个通道)。与其他矩阵实现不同,其他实现使用编译时类型,例如CImg<T>,在其中通常对于不同的元素类型具有不同的函数返回类型。 - greggo
显示剩余3条评论

10

除了@Shai之外,你还可以使用;

double sum = cv::sum(A).val(0);

在多通道(例如彩色)输入图像的情况下,这也仅考虑第一个通道。 - Antonio

0

Scalar cv::sum(InputArray src) 返回一个Scalar,其中每个通道都被单独求和(输入图像必须具有1到4个通道)。如果我们要找的是跨所有通道的所有值的总和,则需要再进行一步操作,对返回的Scalar的所有元素求和。一个简洁的解决方案可以使用dot函数和填充有“1”的标量来实现:

cv::sum(A).dot(cv::Scalar::ones());

这也适用于单通道图像,而不会增加显著的额外计算。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接