我正在将图像处理算法从Python移植到C ++,在两种情况下都使用OpenCV。
在Python版本中,我们使用Numpy的np.cov:
import numpy as np
#Using some dummy data to represent BGR pixels
values = [[30, 37, 35], [26, 36, 34], [38, 45, 41], [40, 47, 43], [38, 45, 43], [34, 43, 40], [30, 39, 37]]
result = np.cov(values, rowvar=False) #Using default 1/(N-1) normalisation
print result
产生输出:
[[ 27.23809524 22.23809524 18.66666667]
[ 22.23809524 18.9047619 15.83333333]
[ 18.66666667 15.83333333 13.66666667]]
在C ++版本中,我们使用OpenCV中的calcCovarMatrix:
#include <opencv2/core.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main() {
Mat values(7, 3, CV_8UC1);
//Representing the same pixels as the Python code
values.at<uchar>(0) = (30, 37, 35);
values.at<uchar>(1) = (26, 36, 34);
values.at<uchar>(2) = (38, 45, 41);
values.at<uchar>(3) = (40, 47, 43);
values.at<uchar>(4) = (38, 45, 43);
values.at<uchar>(5) = (34, 43, 40);
values.at<uchar>(6) = (30, 39, 37);
Mat avgs, covars;
calcCovarMatrix(values, covars, avgs, CV_COVAR_NORMAL | CV_COVAR_SCALE | CV_COVAR_ROWS);
cout << covars << "\n";
calcCovarMatrix(values, covars, avgs, CV_COVAR_NORMAL | CV_COVAR_ROWS);
cout << covars << "\n";
return 0;
}
产生输出:
[364.8163265306122, 253.4285714285715, 260.6122448979592;
253.4285714285715, 308.2857142857143, 317.5714285714286;
260.6122448979592, 317.5714285714286, 334.8163265306122]
[2553.714285714286, 1774, 1824.285714285714;
1774, 2158, 2223;
1824.285714285714, 2223, 2343.714285714285]
可以看出,C ++输出根本不匹配Python输出。在calcCovarMatrix中缩放与否似乎无法纠正它,在np.cov中设置ddof或不设置似乎也无法纠正它。有什么想法吗?
注意:无论出于何种原因,np.cov和calcCovarMatrix使用“row”的矛盾解释;在两个输入案例中,每个行代表一个观察,每个列代表一个变量,所以在Numpy中我们设置rowvar = False但在calcCovarMatrix中我们设置CV_COVAR_ROWS(为True) )。我不认为这是问题的根源。
答案 0 :(得分:1)
罪魁祸首已被确定!有两个问题:
1)values.at<uchar>(0) = (30, 37, 35);
实际上并没有将值写入行(因为有人会从Python进入)。它实际上只是将最后一个值35写入Mat的第0个位置。上面代码中的Mat实际上解析为:
`[35, 34, 41;
43, 43, 40;
37, 0, 0;
0, 0, 0;
0, 0, 0;
0, 0, 0;
0, 0, 0]`
2)OpenCV CalcCovarMatrix未规范化。 covars/(values.rows-1)
修复此问题并生成与Python Numpy相同的输出。