zoukankan      html  css  js  c++  java
  • OpenCv 004---图像像素的读写操作

     本次对像素的操作一共使用了五种方法,并进行计时对比,最终Opencv中的Copy方式速度是最快的,次之是指针遍历方式。

    有一点就是为什么迭代的方式会比数组遍历的方式还要慢那么多,正常应该是比数组快一些才是正确的。

    #include "opencv2opencv.hpp"
    #include <iostream>
    
    using namespace std;
    using namespace cv;
    
    bool copyByArrayWay(Mat srcImg, Mat &resultImg);//数组at遍历方式
    bool copyByRowPtrWay(Mat srcImg, Mat &resultImg);//行指针遍历方式
    bool copyByPtrWay(Mat srcImg, Mat &resultImg);//指针遍历方式
    bool copyByIteratorWay(Mat srcImg, Mat &resultImg);//迭代方式
    bool copyByOpenCv(Mat srcImg, Mat &resultImg);//OpenCv copy方式
    int main(int argv, char** argc)
    {
        Mat src = imread("G:\CVworkstudy\program_wwx\研习社140课时\ZhaiZhigang140\lena.jpg");
        if (src.empty())
        {
            printf("Could not load image...
    ");
            return -1;
        }
        int64 startTime, endTime;
        double usedTime;
    
        ////数组遍历方式
        Mat arrayWayResult = Mat::zeros(src.size(), src.type());
        startTime = getTickCount();
        copyByArrayWay(src, arrayWayResult);
        endTime = getTickCount();
        usedTime = (endTime - startTime) / getTickFrequency() * 1000;
        cout << "数组遍历方式耗时:" << usedTime << "毫秒" << endl;
        imshow("arrayWay", arrayWayResult);
    
        ////行指针遍历方式
        Mat rowPtrWayResult = Mat::zeros(src.size(), src.type());
        startTime = getTickCount();
        copyByRowPtrWay(src, rowPtrWayResult);
        endTime = getTickCount();
        usedTime = (endTime - startTime) / getTickFrequency() * 1000;
        cout << "行指针遍历方式耗时:" << usedTime << "毫秒" << endl;
        imshow("rowPtrWay", rowPtrWayResult);
    
        ////指针方式遍历
        Mat ptrWayResult = Mat::zeros(src.size(), src.type());
        startTime = getTickCount();
        copyByPtrWay(src, ptrWayResult);
        endTime = getTickCount();
        usedTime = (endTime - startTime) / getTickFrequency() * 1000;
        cout << "指针遍历方式耗时:" << usedTime << "毫秒" << endl;
        imshow("ptrWay", ptrWayResult);
    
        ////迭代方式遍历
        Mat iterWayResult = Mat::zeros(src.size(), src.type());
        startTime = getTickCount();
        copyByIteratorWay(src, iterWayResult);
        endTime = getTickCount();
        usedTime = (endTime - startTime) / getTickFrequency() * 1000;
        cout << "迭代方式耗时:" << usedTime << "毫秒" << endl;
        imshow("iterWay", iterWayResult);
    
        ////OpenCv copy方式
        Mat copyWayResult = Mat::zeros(src.size(), src.type());
        startTime = getTickCount();
        copyByOpenCv(src, copyWayResult);
        endTime = getTickCount();
        usedTime = (endTime - startTime) / getTickFrequency() * 1000;
        cout << "Opencv copy方式耗时:" << usedTime << "毫秒" << endl;
        imshow("OpencvCopyWay", copyWayResult);
        
        waitKey(0);
        return 0;
    }
    
    //数组遍历方式 at
    bool copyByArrayWay(Mat srcImg,Mat &resultImg)
    {
        if (srcImg.empty())
        {
            printf("Could not load image...
    ");
            return false;
        }
        int rows = srcImg.rows;
        int cols = srcImg.cols;
        int ch = srcImg.channels();
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < cols;col++) {
                if (ch == 3) {
                    resultImg.at<Vec3b>(row, col) = srcImg.at<Vec3b>(row,col);
    
                }
                else if (ch == 1) {
                    resultImg.at<uchar>(row, col) = srcImg.at<uchar>(row, col);
                }
            }
        }
        return true;
    }
    
    //行指针遍历方式
    bool copyByRowPtrWay(Mat srcImg, Mat &resultImg)
    {
        if (srcImg.empty())
        {
            printf("Could not load image...
    ");
            return false;
        }
        int rows = srcImg.rows;
        int rowPixelNums = (srcImg.cols) * (srcImg.channels());
        for (int row = 0; row < rows; row++) {
            uchar *srcRowPtr = srcImg.ptr<uchar>(row);
            uchar *resultRowPtr = resultImg.ptr<uchar>(row);
            for (int pixelNum = 0; pixelNum < rowPixelNums; pixelNum++) {
                resultRowPtr[pixelNum] = srcRowPtr[pixelNum];
            }
        }
        return true;
    }
    
    //指针遍历方式
    bool copyByPtrWay(Mat srcImg, Mat &resultImg)
    {
        if (srcImg.empty()) {
            printf("Could not load image...
    ");
            return false;
        }
        int ch = srcImg.channels();
        int totalPixelNums = (srcImg.rows) * (srcImg.cols) * ch;
        uchar *srcRowPtr = srcImg.ptr<uchar>(0);
        uchar *resultRowPtr = resultImg.ptr<uchar>(0);
        for (int pixel = 0; pixel < totalPixelNums; pixel++) {
            resultRowPtr[pixel] = srcRowPtr[pixel];
        }
        return true;
    }
    
    //迭代方式
    bool copyByIteratorWay(Mat srcImg, Mat &resultImg)
    {
        if (srcImg.empty()) {
            printf("Could not load image...
    ");
            return false;
        }
        int ch = srcImg.channels();
        if (ch == 3) {
            Mat_<Vec3b>::iterator srcPtrBegin = srcImg.begin<Vec3b>();
            Mat_<Vec3b>::iterator outPtrBegin = resultImg.begin<Vec3b>();
            Mat_<Vec3b>::iterator srcPtrEnd = srcImg.end<Vec3b>();
            while (srcPtrBegin != srcPtrEnd) {
                *outPtrBegin = *srcPtrBegin;
                srcPtrBegin++;
                outPtrBegin++;
            }
            return true;
        }
        else if (ch == 1) {
            Mat_<uchar>::iterator srcPtrBegin = srcImg.begin<uchar>();
            Mat_<uchar>::iterator outPtrBegin = resultImg.begin<uchar>();
            Mat_<uchar>::iterator srcPtrEnd = srcImg.end<uchar>();
            while (srcPtrBegin != srcPtrEnd) {
                *outPtrBegin = *srcPtrBegin;
                srcPtrBegin++;
                outPtrBegin++;
            }
            return true;
        }
        else
            return false;
    }
    
    //OpenCv copy方式
    bool copyByOpenCv(Mat srcImg, Mat &resultImg)
    {
        if (srcImg.empty()) {
            printf("Could not load image...
    ");
            return false;
        }
        srcImg.copyTo(resultImg);
        return true;
    }
    One day,I will say "I did it"
  • 相关阅读:
    013.ES6 -对象字面量增强型写法
    012. ES6
    011. ES6 语法
    10. 9. Vue 计算属性的setter和getter 以及 计算属性的缓存讲解
    4. Spring MVC 数据响应方式
    3. SpringMVC 组件解析
    9. Vue 计算属性
    【洛谷 2984】给巧克力
    【洛谷 1821】捉迷藏 Hide and Seek
    【洛谷 1821】银牛派对Silver Cow Party
  • 原文地址:https://www.cnblogs.com/Vince-Wu/p/11078893.html
Copyright © 2011-2022 走看看