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

1 回表示 (過去 30 日間)
ZhG
ZhG 2013 年 6 月 28 日
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 日
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 日
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 件のコメント
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:)

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


ZhG
ZhG 2013 年 6 月 28 日
thank you all, guys.

カテゴリ

Help Center および File ExchangeImages についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by