在 MATLAB 中平均大向量的错误

Error of Averaging a Large Vector in MATLAB

如何在 MATLAB 中准确取大整数集的平均值? 我正在处理两个大向量(尺寸为 2672x4008),每个向量都是图像中像素的结果。因此,生成的向量填充了 0 到 256 之间的值,全部为整数。我的问题是我想要这些灰度图像的平均强度的准确值。为此,我使用了行

meanvalue = mean(I(:))

这在 MATLAB 的输出行中产生了 meanvalue = 155.9335 的值。

接下来,我将向量的每个值都加了 20,如下所示(如果我理解正确的话,这应该会提高整个图像的强度)。

Ipt = I + 20;

然后我取这个新向量的平均值 Ipt

meanvaluept = mean(Ipt(:))

并且 matlab 吐出一个 meanvaluept = 175.8916 的值。我不是数学天才,但我知道 175.8916 - 20 ≠ 155.9335。

任何帮助将不胜感激,无论是在数学上(如何提高 MATLAB 的精度),还是在程序上(MATLAB 有一些内置函数可以找到强度)。

因为你指的是 "grey-scale images",并且你有 0-255 范围内的整数(你提到的 256 一定是错字),我猜你的 I 是类型uint8.

在这种情况下,MATLAB使用饱和加法,其中大于255的结果被限制为255。您描述的效果是由这种饱和加法引起的。

这是一个例子:

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

解决方法是先转换成double:

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

您的问题中有一个非常重要的说明:

假设I = [2 3;4 9]

meanvalue = mean(I(:)) = 4.5

当你用 I 加上 20 时,你将得到:

Ipt = I + 20;

Ipt = [22 23;24 29]

所以你将 20 添加到 I 中的所有元素,因此你的均值将增加 20 个值。

你检查过图像数据类型了吗?

这是真的,如果你的图像 I 的平均值是

meanvalue = mean(I(:)) = 155.9335

你为每个像素添加了 20

Ipt = I + 20

你应该有

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

但是,不要忘记图像的数据类型是 uint8,它将像素值限制为 0-255。这意味着如果你给一个像素加上20并且它的值大于255,它的值将设置为255,如果你减去一些值并且它小于0也是如此。

也许,您的某些像素限制为 255,而通常情况下您的像素会超过 255。


例如:

我在双精度中有向量 X

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

X 的平均值是

mean(X(:)) = 27.5556

因为

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

如果我给每个像素加20

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];

注意 X20(3,3) 是 255,而不是 260。它导致

meanX20 = mean(X20(:)) = 47

但是如果我将 X 的数据类型更改为双精度

X_double = double(X)

每个像素加20

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];

X20_double的平均值是

X20_double_mean = mean(X20_double(:)) = 47.5556

看出区别了吗? 双 X20 的平均值是 47.5556,uint8 X20 的平均值是 47。 我希望这会有所帮助:)