Why my calculation of standard deviation of an image is different from the built-in function

Hello,
My code is shown below, and I opened the built-in function. I found it just calculates the square root or variance. So, the method is the same. I don't know why.
function ret = yStdDeva(im)
tic;
[tR, tC] = size(im);
mean1 = mean(im(:));
% Calculate square of difference between pixels and mean
sdpm = (double(im) - mean1).^2;
sum_sdpm = sum(sdpm(:));
% Calculate variance
imvar = (1/(tR*tC ))*sum_sdpm;
% Calculate Standard deviation
ret = (imvar)^(1/2);
toc;

回答 (4 件)

Jan
Jan 2013 年 6 月 28 日
編集済み: Jan 2013 年 6 月 28 日
You simply use a wrong formula: You have to normalize by the number of elements minus 1. In addition there can be a difference between SQRT and ^0.5 due to the different numerical implementations.
d = double(im);
C = d(:) - mean(d(:));
S = sqrt(sum(C .* C, 1) ./ (numel(d) - 1)):

4 件のコメント

ZhG
ZhG 2013 年 6 月 28 日
Thanks Jan.
ZhG
ZhG 2013 年 6 月 28 日
Excuse me, but why it is normalzied by 1. Is this specific for image?
ZhG
ZhG 2013 年 6 月 28 日
Actually, it is the same after I had modified my program as your answer. I am confused. The result obtained by built-in function is only 9.6938. But a result of 72.0412 was obtained by my program.
Jan
Jan 2013 年 6 月 28 日
編集済み: Jan 2013 年 6 月 28 日
I have converted the image to the type double to avoid saturation effects with integer types. So please try my code and not a program modified like my code.

サインインしてコメントする。

ZhG
ZhG 2013 年 6 月 28 日

0 投票

However, I found where the problem happens. If I calculate standard deviation of an image without converting it into double, it will generate a result of 9.6938. However, it will does return 72.0412 afte I transformed it to double.
Is there anyone know what the problem is?

3 件のコメント

The problem is wind-up. To see it, try these at command line:
uint8(255) + uint8(1) - uint8(1) % Get it here
uint16(255) + uint16(1) - uint16(1) % Don't get it here
double(10^30) + double(1) - double(10^30) % Get it here
double(10^30) - double(10^30) + double(1) % Don't get it here
Jan
Jan 2013 年 6 月 28 日
編集済み: Jan 2013 年 6 月 28 日
Operations on integer types are affected of the saturaion:
uint8(250) + uint8(250) == uint8(255) !!
Iain
Iain 2013 年 6 月 28 日
Wind-up is a type of saturation, and I use the terms almost interchangably.

サインインしてコメントする。

Image Analyst
Image Analyst 2013 年 6 月 28 日
I don't see much difference - just a really slight difference (less than a thousandth of a gray level):
im=imread('cameraman.tif');
% Your way:
[tR, tC] = size(im);
mean1 = mean(im(:));
% Calculate square of difference between pixels and mean
sdpm = (double(im) - mean1).^2;
sum_sdpm = sum(sdpm(:));
% Calculate variance
imvar = (1/(tR*tC ))*sum_sdpm;
% Calculate Standard deviation
ret = (imvar)^(1/2)
% Standard, built-in way:
std(double(im(:)))
In the command window:
ret =
62.3412396872523
ans =
62.3417153186086
Why are you wanting to do it yourself anyway? Why not just use std()?

1 件のコメント

ZhG
ZhG 2013 年 6 月 28 日
because std is slower that what i did. but what i did is not useful. 0:)

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeImages についてさらに検索

質問済み:

ZhG
2013 年 6 月 28 日

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by