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"
  • 相关阅读:
    架构之道(1)
    看板管理(1)
    交互原型图
    Sequence Diagram时序图
    安卓项目的「轻」架构
    安卓ButtomBar实现方法
    工具类BitMap 把网络URL图片转换成BitMap
    使用OkHttp上传图片到服务器
    BaseAdapter教程(2) BaseAdapter的notifyDataSetChanged动态刷新
    开发中时间变换问题汇总
  • 原文地址:https://www.cnblogs.com/Vince-Wu/p/11078893.html
Copyright © 2011-2022 走看看