使用 NumPy 计算两个平面之间的协方差

Calculating covariance between 2 planes with NumPy

假设我们有两帧视频,我们想要 return 两帧之间的协方差矩阵。该矩阵将与两个帧之一具有相同的维度。

我在下面简化了我的代码。这是 class 实施的一部分,因此没有必要展示其中的大部分内容。

def covar(self,frame):

    return np.cov(current_frame,next_frame)

这return是我想要的飞机。但上面的问题是它 return 的尺寸要大得多。这将有助于了解 np.cov return 的值。有什么指点吗?

编辑

我想澄清一下我的意思。我的 2 帧是由矩阵中的强度值表示的灰度图像。每个值映射到一个像素。我试图找到一帧和下一帧中像素之间的协方差。

(此外,我更喜欢使用 NumPy 或其他非常高效的计算方法,因为我的堆栈中可能有数千张图像。)

编辑2

假设我想使用 OpenCV,因为 NumPy 不适合图像处理。关于使用 calcCovarMatrix 函数的任何提示 (http://docs.opencv.org/modules/core/doc/operations_on_arrays.html)?

It would help to know how the np.cov returns a value. Any pointers?

是的。 Official Documentation

我想您想查看一个特定像素位置的统计属性。为此,请将帧视为对一组像素的一次观察;下一帧是同一组的下一个观察结果。

这导致了一种与

不同的方法
import numpy
a = numpy.ravel(frame1)
b = numpy.ravel(frame2)
c = numpy.column_stack((a,b))
res = numpy.cov(c)

res 将具有 (rows*cols, rows*cols) 的维度,就像您对协方差矩阵的期望一样。

我想你要找的是以下内容。我经常计算两个连续帧之间的相关性,例如我用它来确定深度,其中相关性为 0.5,这意味着我们的 SNR 等于 0(穿透深度)。

我执行以下操作:

# Window used for averaging
winrows = 3
wincols = 21

eps = np.finfo(np.float64).eps

win = np.ones((winrows, wincols)) / winrows / wincols

# I have my own conv2 (like Matlab), so use convolve2d from scipy.signal instead
R11 = rfdata1 * rfdata1.conjugate()
R11 = np.sqrt(np.abs(conv2(R11, win, 'same')))
R11[R11 == 0] = eps

R22 = rfdata2 * rfdata2.conjugate()
R22 = np.sqrt(np.abs(conv2(R22, win, 'same')))
R22[R22 == 0] = eps

R12 = rfdata1 * rfdata2.conjugate()
R12 = np.abs(conv2(R12, win, 'same'))
R12 = R12 / R11 / R22

R12[R12 > 1] = 1

矩阵 R12 现在包含绝对相关系数(截断到范围 [-1,1])。也可以使用来自scipy.ndimage.filters的convolve,速度很快,但是相比Matlab的conv2要偏移1.

为了使这个计算有效,conv2 可以这样定义

from scipy.ndimage.filters import convolve

def conv2(x,y,mode='same'):
    """
    Emulate the function conv2 from Mathworks.

    Usage:

    z = conv2(x,y,mode='same')

    """

    if not(mode == 'same'):
        raise Exception("Only same is supported")

    if not(len(x.shape) == len(y.shape)):
        raise Exception("Number of dimensions must match")

    origin = ()

    # Apparently, the origin must be set in a special way to reproduce
    # the results of scipy.signal.convolve
    for i in range(len(x.shape)):
        if (x.shape[i] - y.shape[i]) % 2 == 0:
            origin = origin + (-1,)
        else:
            origin = origin + (0,)

    if (mode == 'same'):
        z = convolve(x,y, mode='constant', origin=origin)

    return z

我想出了我想做什么。

之前,我已经计算了一堆图像中所有像素(在一个点上)的方差,并将其绘制为矩阵。我花了一段时间,但我意识到像素强度之间的协方差(我一直想要的)等于方差的两倍!

我的 return 声明是这样的,它似乎有效。如果这有效,请告诉我。

    return 2*np.var(stack,2) 

拍摄两张图片,img1 和 img2,并定义以下 python 函数

def Covariance(x, y):
    xbar, ybar = x.mean(), y.mean()
    return np.sum((x - xbar)*(y - ybar))/(len(x) - 1)

现在调用函数,方法如下

print("Covariance(img1,img2)  :", Covariance(img1,img2))

它会给你两个图像之间适当的协方差。