Error of Averaging a Large Vector in MATLAB


Error of Averaging a Large Vector in MATLAB



How do you accurately take the average of large sets of integers in MATLAB?
I have two large vectors (2672x4008 in dimensions) I am dealing with, each the result of pixels in an image. Hence, the resulting vector is filled with values 0 to 256, all integers. My problem is that I want an accurate value of the average intensity of these grey-scale images. To do this, I used the line


meanvalue = mean(I(:))



This yielded a value of meanvalue = 155.9335 in the output line of MATLAB.



Next, I added 20 to each value of the vector, as below (this should raise the intensity of the overall image, if I am understanding correctly).


Ipt = I + 20;



I then took the mean value of this new vector, Ipt


meanvaluept = mean(Ipt(:))



and matlab spat out a value of meanvaluept = 175.8916. I'm no math wizard, but I know enough to know that 175.8916 - 20 ≠ 155.9335.



Any help would be appreciated, either mathematically (how to increase the precision of MATLAB), or procedurally (there is some built-in function of MATLAB which will find the intensity).




3 Answers
3



Since you are referring to "grey-scale images", and you have integers in the range 0-255 (the 256 you mention must be a typo), my guess is that your I is of type uint8.


I


uint8



In this case, MATLAB uses saturated addition, in which results larger than 255 are clamped to 255. The effect you describe is caused by this saturated addition.



Here is an example:


>> I = uint8(randi(255,1000,1000));
>> mean( I(:)+20 )
ans =
147.1954
>> mean(I(:)) + 20
ans =
148.0151



The solution is to convert to doubles first:


>> mean( double(I(:)) + 20 )
ans =
148.0151



Have you checked the image datatype?



It's true that if your the mean of image I is


meanvalue = mean(I(:)) = 155.9335



and you added 20 to each pixels


Ipt = I + 20



you supposed to have


meanept = mean(Ipt(:)) = meanvalue + 20 = 175.9335



But, don't forget that image's datatype is uint8, which limit the pixels value to 0-255. It means if you added 20 to a pixel and its value is greater than 255, its value will set to 255, and the same if you substract some value and it's lower than 0.



Maybe, some of your pixels restricted to 255 when normally you'll have more than 255.



I have vector X in double


X = [1 1 1; ...
1 1 1; ...
1 1 240];



The mean of X is


mean(X(:)) = 27.5556



since


( 1 + 1 + 1 + 1 + 1 + 1 + 1 + 1 + 240)/9 = 27.5556



If I added 20 to each pixels


X20 = X + 20
= [(1 + 20) (1 + 20) (1 + 20); ...
(1 + 20) (1 + 20) (1 + 20); ...
(1 + 20) (1 + 20) (240 + 20)];
= [21 21 21; ...
21 21 21; ...
21 21 255];



Notice that X20(3,3) is 255, not 260. It cause


meanX20 = mean(X20(:)) = 47



but if I change X's datatype to double


X_double = double(X)



and added 20 to each pixels


X20_double = X_double + 20
= [(1 + 20) (1 + 20) (1 + 20); ...
(1 + 20) (1 + 20) (1 + 20); ...
(1 + 20) (1 + 20) (240 + 20)];
= [21 21 21; ...
21 21 21; ...
21 21 260];



and the average of X20_double is


X20_double_mean = mean(X20_double(:)) = 47.5556



See the difference?
The double X20's mean is 47.5556 and the uint8 X20's mean is 47.
I hope this will help :)





How is this different from what CrisLuengo already suggested?
– Sardar Usama
Jun 30 at 19:56



There is a very important note in your question :



Suppose I = [2 3;4 9]


I = [2 3;4 9]


meanvalue = mean(I(:)) = 4.5



When you add 20 with I , You will have :


Ipt = I + 20;



Ipt = [22 23;24 29]



so you add 20 to all elements in I, therefore your mean will increase 20 value.





“your mean will increase 20 value“ this is what OP expects. OP asks why this is not the case. Consequently, you’re not answering the question at all.
– Cris Luengo
Jun 30 at 19:39






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

List of Kim Possible characters

Audio Livestreaming with Python & Flask

NSwag: Generate C# Client from multiple Versions of an API