Matlab 角度的方差

3
我有一个包含角度的矩阵,需要计算平均值和方差。 对于平均值,我是这样做的: 对于每个角度,计算正弦和余弦,并将所有正弦和所有余弦相加。 平均值由atan2(sin,cos)给出,并且有效。 我的问题是如何在已知平均值的情况下计算角度的方差? 感谢您的回答。 我附上我的Matlab代码:
for i=1:size(im2,1)

    for j=1:size(im2,2)
        y=y+sin(hue(i, j));
        x=x+cos(hue(i, j));
    end
end
mean=atan2(y, x);

if mean<0

    mean=mean+(2*pi);
end
4个回答

4

3

我不太确定你在做什么,但也许使用内置的MATLAB函数meanvar可以实现同样的功能。

>> [file path] = uigetfile;
>> someImage = imread([path file]);
>> hsv = rgb2hsv(someImage);
>> hue = hsv(:,:,1);
>> m = mean(hue(:))

m =

    0.5249

>> v = var(hue(:))

v =

    0.2074

编辑:根据您的变量名hue,我假设您拥有一张图片。但任何矩阵都是相同的。

编辑2:也许这就是您要找的:

>> sumsin = sum(sin(hue(:)));
>> sumcos = sum(cos(hue(:)));
>> meanvalue = atan2(sumsin,sumcos)

meanvalue =

    0.5276

>> sumsin = sum(sin((hue(:)-meanvalue).^2));
>> sumcos = sum(cos((hue(:)-meanvalue).^2));
>> variance = atan2(sumsin,sumcos)

variance =

    0.2074

我的问题是我不能只使用平均值:如果我有两个角度如30度和60度,平均值应该像正常平均值一样为45度,但是如果我有30度和330度,我需要平均值为0度,这就是为什么我必须用不同的方式计算平均值的原因。 - andrea
你说得没错,我正在处理图像。平均值的问题在于,如果图像中有大量红色像素(约为0-30°或330°-360°),那么就会出现问题。 - andrea
@andrea:啊,非常好,我明白你在做什么。我添加了一些东西。不确定它是否有效。虽然我消除了循环。 - Lucas
非常感谢,这次它有效了!只需要看看我的工作方差是在你告诉我的方法中更好还是在这个方法中更好,但这只是一个尝试和观察结果的问题。方差= sum((hue(:)-meanvalue).^2)-meanvalue^2; 还有感谢你消除循环。 - andrea
这不是计算角度均值和方差的正确方法。 - Cris Luengo

3
循环数据的方差不能像实数线上无限制的数据的方差一样处理。(对于非常小的方差,它们是等效的,但是对于大的方差,等效性会失效。你应该清楚为什么会这样。)我推荐阅读N.I. Fisher的《循环数据统计分析》。这本书包含了一个广泛使用的循环方差定义,它是通过角度所对应的单位向量的平均结果长度计算得出的。
>> sumsin = sum(sin((hue(:)-meanvalue).^2));
>> sumcos = sum(cos((hue(:)-meanvalue).^2));
这是错误的。你不能这样减去角度。
顺便说一下,这个问题与MATLAB没有任何关系。在统计堆栈交换上发布可能会获得更好的答案。

0
我们曾经遇到了同样的问题,在Python中,我们使用scipy.cirvar解决了这个问题,它计算在一个范围内假定为样本的圆形方差。例如:
from scipy.stats import circvar
circvar([0, 2*np.pi/3, 5*np.pi/3])
# 2.19722457734

circvar([0, 2*np.pi])
# -0.0

所提出的MATLAB代码存在问题,即[0, 6.28]的方差应为零。通过查看scipy.circvar的实现方式,可以发现:


# Recast samples as radians that range between 0 and 2 pi and calculate the sine and cosine
samples, sin_samp, cos_samp, nmask = _circfuncs_common(samples, high, low)

sin_mean = sin_samp.mean()
cos_mean = cos_samp.mean()

R = np.minimum(1, hypot(sin_mean, cos_mean))
circular_variance = ((high - low)/2.0/pi)**2 * -2 * np.log(R)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接