1.测试用例:
给定一个10000×10000大小的三通道Mat及单通道Mat,像素值全为0,现分别逐一修改为(120, 220, 300)以及180,测量各种方法的运行时间。
2.Mat元素访问方式对比
(1) 使用.at方式
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
using namespace std;
using namespace cv;
int main()
{
Mat img1(10000, 10000, CV_64FC3, Scalar(0, 0, 0));
Mat img2(10000, 10000, CV_64FC1, Scalar(0));
// 三通道图像
clock_t start1, end1;
start1 = clock();
for (int i = 0; i < img1.rows; ++i) {
for (int j = 0; j < img1.cols; ++j) {
img1.at<Vec3d>(i, j)[0] = 120;
img1.at<Vec3d>(i, j)[1] = 220;
img1.at<Vec3d>(i, j)[2] = 300;
}
}
end1 = clock();
double time1 = double(end1 - start1) / CLOCKS_PER_SEC;
// 单通道图像
clock_t start2, end2;
start2 = clock();
for (int i = 0; i < img2.rows; ++i) {
for (int j = 0; j < img2.cols; ++j) {
img2.at <double> (i, j) = 180;
}
}
end2 = clock();
double time2 = double(end2 - start2) / CLOCKS_PER_SEC;
cout << " 三通道Mat的运行时间为:" << time1 << " 秒" << endl;
cout << " 单通道Mat的运行时间为:" << time2 << " 秒" << endl;
return 0;
}
运行结果:
Release模式下:
Debug模式下:
(2) 使用.ptr方式
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
using namespace std;
using namespace cv;
int main()
{
Mat img1(10000, 10000, CV_64FC3, Scalar(0, 0, 0));
Mat img2(10000, 10000, CV_64FC1, Scalar(0));
// 三通道图像
clock_t start1, end1;
start1 = clock();
for (int i = 0; i < img1.rows; ++i) {
for (int j = 0; j < img1.cols; ++j) {
double *ptr = img1.ptr<double>(i, j);
ptr[0] = 120;
ptr[1] = 220;
ptr[2] = 300;
}
}
end1 = clock();
double time1 = double(end1 - start1) / CLOCKS_PER_SEC;
// 单通道图像
clock_t start2, end2;
start2 = clock();
for (int i = 0; i < img2.rows; ++i) {
double *ptr = img2.ptr<double>(i);
for (int j = 0; j < img2.cols; ++j) {
ptr[j] = 180;
}
}
end2 = clock();
double time2 = double(end2 - start2) / CLOCKS_PER_SEC;
cout << " 三通道Mat的运行时间为:" << time1 << " 秒" << endl;
cout << " 单通道Mat的运行时间为:" << time2 << " 秒" << endl;
return 0;
}
运行结果:
Release模式下:
Debug模式下:
(3) 使用迭代器方式
#include <opencv2/opencv.hpp>
#include <iostream>
#include <time.h>
using namespace std;
using namespace cv;
int main()
{
Mat img1(10000, 10000, CV_64FC3, Scalar(0, 0, 0));
Mat img2(10000, 10000, CV_64FC1, Scalar(0));
// 三通道图像
clock_t start1, end1;
start1 = clock();
Mat_<Vec3d>::iterator it1 = img1.begin<Vec3d>();
Mat_<Vec3d>::iterator itend1 = img1.end<Vec3d>();
for (; it1 != itend1; ++it1) {
(*it1)[0] = 120;
(*it1)[1] = 220;
(*it1)[2] = 300;
}
end1 = clock();
double time1 = double(end1 - start1) / CLOCKS_PER_SEC;
// 单通道图像
clock_t start2, end2;
start2 = clock();
Mat_<double>::iterator it2 = img2.begin<double>();
Mat_<double>::iterator itend2 = img2.end <double> ();
for (; it2 != itend2; ++it2) {
(*it2) = 180;
}
end2 = clock();
double time2 = double(end2 - start2) / CLOCKS_PER_SEC;
cout << " 三通道Mat的运行时间为:" << time1 << " 秒" << endl;
cout << " 单通道Mat的运行时间为:" << time2 << " 秒" << endl;
return 0;
}
运行结果:
Release模式下:
Debug模式下:
3.总 结
在Release模式下,三种方式的差异不大。在Debug模式下,运行时间:.Ptr < 迭代器 < .at
后续会继续补充测量其他访问方式......