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 .data
    image.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应该是进行了优化,全部优化成最快的方式,至少在我电脑上几种访问方式的速度几乎差别

猜你喜欢

转载自blog.csdn.net/qq_41253960/article/details/129986827
今日推荐