您可以轻松转换此 MATLAB 代码:
idx = A > 0;
B(idx) = 0;
// same as
B(A>0) = 0;
到 OpenCV 为:
Mat1d A(...)
Mat1d B(...)
Mat1b idx = A > 0;
B.setTo(0, idx) = 0;
// or
B.setTo(0, A > 0);
关于性能,在 C++ 中,处理原始指针通常更快(取决于启用的优化)(但可读性):
for (int r = 0; r < B.rows; ++r)
{
double* pA = A.ptr<double>(r);
double* pB = B.ptr<double>(r);
for (int c = 0; c < B.cols; ++c)
{
if (pA[c] > 0.0) pB[c] = 0.0;
}
}
另请注意,在 OpenCV 中没有任何 布尔 矩阵,但它是一个 CV_8UC1 矩阵(又名unsigned char 的单通道矩阵),其中0 表示false ,并且任何值 >0 都是 true(通常是 255)。
评估
请注意,这可能会有所不同,具体取决于 OpenCV 启用的优化。您可以在您的 PC 上测试下面的代码以获得准确的结果。
以毫秒为单位的时间:
my results my results @AdrienDescamps
(OpenCV 3.0 No IPP) (OpenCV 2.4.9)
Matlab : 13.473
C++ Mask: 640.824 5.81815 ~5
C++ Loop: 5.24414 4.95127 ~4
注意:我不完全确定 OpenCV 3.0 的性能下降,所以我只是说:在您的 PC 上测试下面的代码以获得准确的结果。
正如@AdrienDescamps 在 cmets 中所述:
OpenCV 3.0 的性能下降似乎与 OpenCL 选项有关,该选项现在在比较运算符中启用。
C++ 代码
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
// Random initialize A with values in [-100, 100]
Mat1d A(1000, 1000);
randu(A, Scalar(-100), Scalar(100));
// B initialized with some constant (5) value
Mat1d B(A.rows, A.cols, 5.0);
// Operation: B(A>0) = 0;
{
// Using mask
double tic = double(getTickCount());
B.setTo(0, A > 0);
double toc = (double(getTickCount()) - tic) * 1000 / getTickFrequency();
cout << "Mask: " << toc << endl;
}
{
// Using for loop
double tic = double(getTickCount());
for (int r = 0; r < B.rows; ++r)
{
double* pA = A.ptr<double>(r);
double* pB = B.ptr<double>(r);
for (int c = 0; c < B.cols; ++c)
{
if (pA[c] > 0.0) pB[c] = 0.0;
}
}
double toc = (double(getTickCount()) - tic) * 1000 / getTickFrequency();
cout << "Loop: " << toc << endl;
}
getchar();
return 0;
}
Matlab 代码
% Random initialize A with values in [-100, 100]
A = (rand(1000) * 200) - 100;
% B initialized with some constant (5) value
B = ones(1000) * 5;
tic
B(A>0) = 0;
toc
更新
OpenCV 3.0 在函数setTo 中使用IPP 优化。如果您启用了该功能(您可以通过cv::getBuildInformation() 进行检查),您将获得更快的计算速度。