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

时间:2015-01-11 21:13:05

标签: python image image-processing numpy

假设我们有两帧视频,我们想要返回两帧之间协方差的矩阵。该矩阵将具有与两个帧中的一个相同的尺寸。

我在下面简化了我的代码。这是类实现的一部分,因此没有必要显示它。

def covar(self,frame):

    return np.cov(current_frame,next_frame)

这会返回我想要的飞机。但是上面的问题是它返回了更大的尺寸。了解np.cov如何返回值将有所帮助。有什么指针吗?

修改

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

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

Edit2

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

4 个答案:

答案 0 :(得分:0)

  

了解np.cov如何返回值将有所帮助。有什么指针吗?

是。 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),就像您对协方差矩阵所期望的那样。

答案 1 :(得分:0)

我认为您正在寻找的是以下内容。我经常计算两个连续帧之间的相关性,例如我使用它来确定深度,相关系数为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

答案 2 :(得分:0)

我想出了我想做的事情。

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

我的回复声明就是这样,它似乎有效。如果有这样的原因,请告诉我。

    return 2*np.var(stack,2) 

答案 3 :(得分:0)

拍摄两个图像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))

它将为您提供两幅图像之间的适当协方差。