Sum of elements in a matrix in OpenCV?
Asked Answered
B

3

31

I need to sum all the elements in a matrix. I used the function

  sum(sum(A)); 

in matlab. Where A is a matrix of size 300*360. I want to implement the same function in OpenCV. I used something like this.

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

But there is error showing cannot convert scalar to double. How to fix this problem?

Barnaba answered 19/2, 2014 at 8:24 Comment(2)
just as an aside, in Matlab it is better to sum(A(:)) instead of sum(sum(A))Damondamour
possible duplicate of OpenCV: Getting the total of Mat valuesBurden
R
57

Unlike Matlab, in opencv, cv::sum(A) sums along ALL dimensions and returns a single number (scalar) that is equal to Matlab's sum(sum(A)).
So, what you need is

double s = cv::sum(A)[0];
Roccoroch answered 19/2, 2014 at 8:38 Comment(8)
not quite correct: cv::Scalar s = cv::sum(A); if that's a 1chan mat, it's : double psum = cv::sum(A)[0];Age
What does [0] stands for.Can anyone please explain?Barnaba
cv::sum returns a cv::Scalar element. If you have a 3-channel image for example, the return value has 3 elements, one for each channel. So each channel is summed up independently. [0] would access the first value of that Scalar. For RGB images with BGR ordering (like mostly used in OpenCV), [0] of the Scalar would access the summed up "blue channel", '[1]' would be the sum of the "green channel" and '[2]' is the sum of the "red channel" in that example. docs.opencv.org/modules/core/doc/operations_on_arrays.html#sumParatroops
Can I pass a Mat object to this functionBertero
The reason it's done this way is that cv::Mat is runtime typed; the same cv::sum() is called regardless of whether the array actually contains uint8's, int16, float, etc; so all cases must return the same type. 'Scalar' contains 4 doubles, which accommodates all cases (up to 4 channels). Contrast with other matrix implementations which use compile-time typing, e.g. CImg<T> in which you generally have different function return types for different element types.Poona
Use cv::sum(cv::sum(A))[0] to get the sum of sums scalar value in the multi-channel scenarioUniversalize
@Universalize AFAIK that will not work, if I understand correctly cv::sum on a Scalar is an invariant, i.e. output is a copy of the input.Indignity
I wish I could put a negative bounty on this answer :), it is so misleading as far as it concerns multiple channel images, and it doesn't give an explanation on why [0]Indignity
V
10

In addition with @Shai you can use;

double sum = cv::sum(A).val(0);
Veilleux answered 20/2, 2014 at 19:40 Comment(1)
This also considers only the first channel in the case of a multi-channel (e.g. color) input image.Indignity
I
0

Scalar cv::sum(InputArray src) returns a Scalar where each channel has been summed separately (input image must have between 1 to 4 channels). If what we are looking for is the sum of all the values across all channels, one further step is needed summing all elements of the returned Scalar. A one-liner solution could be using the dot product with a scalar filled with ones:

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

This works universally also for single channel images, without adding significant extra computation.

Indignity answered 20/3, 2023 at 20:25 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.