Vector-Matrix-Multiplication在OpenCV C ++界面中非常慢

时间:2011-08-08 14:49:54

标签: c++ performance opencv

我已经通过“随机停止方法”确定以下两行看起来非常慢:

cv::Mat pixelSubMue = pixel - vecMatMue[kk_real];   // ca. 35.5 %
cv::Mat pixelTemp = pixelSubMue * covInvRef;        // ca. 58.1 %
cv::multiply(pixelSubMue, pixelTemp, pixelTemp);    // ca. 0 %
cv::Scalar sumScalar = cv::sum(pixelTemp);          // ca. 3.2 %

double cost = sumScalar.val[0] * 0.5 + vecLogTerm[kk_real]; // ca. 3.2 %
  • vecMatMue[kk_real]std::vector<cv::Mat>&lt; - 我知道涉及很多复制,但使用指针在性能方面并没有太大变化
  • pixelSubMuecv::Mat(1, 3, CV_64FC1)向量
  • covInvRef是对cv::Mat(3, 3, CV_64FC1)矩阵
  • 的引用
  • vecLogTerm[kk_real]std::vector<double>

上面的代码片段位于内部循环中,称为数百万次。

问题:有没有办法提高该操作的速度?

修改:感谢您的评论!我现在已经测量了程序中的时间,百分比表示每行花费了多少时间。测量在释放模式下完成。每次执行代码数百万次时,我做了六次测量。

我可能还应该提到,std::vector对象对性能没有影响,我只是用常量对象替换它们。

编辑2 :我还使用C-Api实现了算法。相关的行现在看起来像这样:

cvSub(pixel, vecPMatMue[kk], pixelSubMue);                   // ca. 24.4 %
cvMatMulAdd(pixelSubMue, vecPMatFCovInv[kk], 0, pixelTemp);  // ca. 39.0 %
cvMul(pixelSubMue, pixelTemp, pixelSubMue);                  // ca. 22.0 %
CvScalar sumScalar = cvSum(pixelSubMue);                     // ca. 14.6 %
cost = sumScalar.val[0] * 0.5 + vecFLogTerm[kk];             // ca. 0.0 %

C ++实现需要相同的输入数据ca. 3100毫秒,而C-Implementation只需要大约2050毫秒(两次测量都是指执行片段数百万次的总时间)。但我仍然更喜欢我的C ++实现,因为它更容易为我阅读(必须进行其他“丑陋”的更改才能使它与C-API一起使用)。

编辑3 :我没有使用任何函数调用来重写代码进行实际计算:

capacity_t mue0 = meanRef.at<double>(0, 0);
capacity_t mue1 = meanRef.at<double>(0, 1);
capacity_t mue2 = meanRef.at<double>(0, 2);

capacity_t sigma00 = covInvRef.at<double>(0, 0);
capacity_t sigma01 = covInvRef.at<double>(0, 1);
capacity_t sigma02 = covInvRef.at<double>(0, 2);
capacity_t sigma11 = covInvRef.at<double>(1, 1);
capacity_t sigma12 = covInvRef.at<double>(1, 2);
capacity_t sigma22 = covInvRef.at<double>(2, 2);

mue0 = p0 - mue0; mue1 = p1 - mue1; mue2 = p2 - mue2;

capacity_t pt0 = mue0 * sigma00 + mue1 * sigma01 + mue2 * sigma02;
capacity_t pt1 = mue0 * sigma01 + mue1 * sigma11 + mue2 * sigma12;
capacity_t pt2 = mue0 * sigma02 + mue1 * sigma12 + mue2 * sigma22;

mue0 *= pt0; mue1 *= pt1; mue2 *= pt2;

capacity_t cost = (mue0 + mue1 + mue2) / 2.0 + vecLogTerm[kk_real];

现在每个像素的计算只需要150ms!

1 个答案:

答案 0 :(得分:1)

看起来你正在编译调试模式,这可能解释了性能损失。您可以使用clock()等时间函数来分析代码。

E.g。

clock_t start,end;
...
start = clock();
cv::Mat pixelTemp = pixelSubMue * covInvRef;    // Very SLOW!
end = clock();

cout<<"Elapsed time in seconds: "<<(static_cast<double>(end)-start)/CLK_TCK<<endl;