> 文章列表 > OpenCV访问元素的几种方式.at<>(), .ptr<>(), .data,并测试了各自的速度

OpenCV访问元素的几种方式.at<>(), .ptr<>(), .data,并测试了各自的速度

OpenCV访问元素的几种方式.at<>(), .ptr<>(), .data,并测试了各自的速度

OpenCV的Mat在内存中是按行保存的

#include <iostream>
#include <chrono>
#include <opencv2/opencv.hpp>
using namespace std;int main(int argc, char **argv)
{const int test_time = 100;cv::Mat image(5000, 10000, CV_32SC3, cv::Scalar(0, 0, 0));int width = image.cols;int height = image.rows;//! 1 .at<>()cout << "1\\n"<< image.at<cv::Vec3i>(50, 50) << endl;chrono::steady_clock::time_point t1 = chrono::steady_clock::now();for (int k = 0; k < test_time; k++){//method1 .at<>()最好理解for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){image.at<cv::Vec3i>(i, j) = cv::Vec3i(3 * k, 7 * k, 12 * k);}}}chrono::steady_clock::time_point t2 = chrono::steady_clock::now();cout << image.at<cv::Vec3i>(50, 50) << endl;chrono::duration<double> time = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "time = " << time.count() << "秒" << endl;//! 2 .ptr(row,col)image.setTo(cv::Scalar(0, 0, 0));cout << "2\\n"<< image.at<cv::Vec3i>(50, 50) << endl;t1 = chrono::steady_clock::now();for (int k = 0; k < test_time; k++){//method2 .ptr<>(行,列)for (int h = 0; h < height; h++){for (int w = 0; w < width; w++){cv::Vec3i *ptr = image.ptr<cv::Vec3i>(h, w);ptr->val[0] = 3 * k;ptr->val[1] = 7 * k;ptr->val[2] = 12 * k;}}}t2 = chrono::steady_clock::now();cout << image.at<cv::Vec3i>(50, 50) << endl;time = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "time = " << time.count() << "秒" << endl;//! 3 .ptr(row,col)image.setTo(cv::Scalar(0, 0, 0));cout << "3\\n"<< image.at<cv::Vec3i>(50, 50) << endl;t1 = chrono::steady_clock::now();for (int k = 0; k < test_time; k++){//method3 .ptr<>(行,列)for (int h = 0; h < height; h++){for (int w = 0; w < width; w++){int *ptr = image.ptr<int>(h, w);ptr[0] = 3 * k;ptr[1] = 7 * k;ptr[2] = 12 * k;}}}t2 = chrono::steady_clock::now();cout << image.at<cv::Vec3i>(50, 50) << endl;time = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "time = " << time.count() << "秒" << endl;//! 4 .ptr(row)image.setTo(cv::Scalar(0, 0, 0));cout << "4\\n"<< image.at<cv::Vec3i>(50, 50) << endl;t1 = chrono::steady_clock::now();for (int k = 0; k < test_time; k++){//method4 .ptr<>(行)for (int i = 0; i < height; i++){int *data = image.ptr<int>(i);for (int j = 0; j < width; j++){data[3 * j] = 3 * k;data[3 * j + 1] = 7 * k;data[3 * j + 2] = 12 * k;}}}t2 = chrono::steady_clock::now();cout << image.at<cv::Vec3i>(50, 50) << endl;time = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "time = " << time.count() << "秒" << endl;//! 5 .dataimage.setTo(cv::Scalar(0, 0, 0));cout << "5\\n"<< image.at<cv::Vec3i>(50, 50) << endl;t1 = chrono::steady_clock::now();int *pData = (int *)image.data;for (int k = 0; k < test_time; k++){//method5 .data for (int i = 0; i < height; i++){for (int j = 0; j < width; j++){pData[width * i * 3 + 3 * j] = 3 * k;pData[width * i * 3 + 3 * j + 1] = 7 * k;pData[width * i * 3 + 3 * j + 2] = 12 * k;}}}t2 = chrono::steady_clock::now();cout << image.at<cv::Vec3i>(50, 50) << endl;time = chrono::duration_cast<chrono::duration<double>>(t2 - t1);cout << "time = " << time.count() << "秒" << endl;return 0;
}

测试结果

1
[0, 0, 0]
[297, 693, 1188]
time = 4.427662
[0, 0, 0]
[297, 693, 1188]
time = 4.650733
[0, 0, 0]
[297, 693, 1188]
time = 4.639554
[0, 0, 0]
[297, 693, 1188]
time = 4.431085
[0, 0, 0]
[297, 693, 1188]
time = 4.44789

OpenCV应该是进行了优化,全部优化成最快的方式,至少在我电脑上几种访问方式的速度几乎差别