python+opencv求协方差

在实际工作中,协方差作为数据的重要统计特征,我们经常会用到。最近在用到opencv_py的cv2.calcCovarMatrix求数据的协方差时就踩了一个小坑,特记录一下。例如,我要求下面数据(每一行是某一图像的CrCb值,一共有几万个数据对,也就是几万个样本)的协方差,数据名字label_pixVale。

                       

                 ……………                                                ……………

第一时间想到用了用opencv自带的函数:

covar, means = cv2.calcCovarMatrix(label_pixVale, mean=mean, flags=cv2.COVAR_ROWS |cv2.COVAR_SCALE)

这个用法貌似没错,但是运行就报OutOfMemoryError的错误,COVAR_ROWS参数已经指明样本是作为行是没错的。虽然我的数据比较多,但是维度只有2,怎么会溢出呢?

因为只有两个维度,比较简单,于是自己写了下协方差的计算:

xx = 0
yy = 0
xy = 0
means = np.mean(np.array(label_pixVale), axis=0)
num =  label_pixVale.shape[0]
for i in range(num):
    xx += (label_pixVale[i][0] - means[0]) * (label_pixVale[i][0] - means[0])
    yy += (label_pixVale[i][1] - means[1]) * (label_pixVale[i][1] - means[1])
    xy += (label_pixVale[i][0] - means[0]) * (label_pixVale[i][1] - means[1])
xx /= (num -1)
yy /= (num -1)
xy /= (num -1)

没有内存溢出的情况。

于是找答案,查看opencv文档(opencv2.3.2):

 红色框中,CV_COVAR_SCRAMBLED 和CV_COVAR_NORMAL必须指定一个,于是用这样设置:

covar, means = cv2.calcCovarMatrix(label_pixVale, mean=means, flags=cv2.COVAR_ROWS |cv2.COVAR_SCALE |cv2.COVAR_NORMAL)

这样运行就正确了,与手写的结果基本一致,但是还有一点点不一样,从CV_COVAR_SCALE参数说明可以看到,opencv归一是除以样本总数,然而协方差计算公式应该是除以(样本总数-1)。

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值