OPENCV学习笔记2-4_编写高效的图像扫描循环

  When you write an image-processing function, efficiency is often a concern(涉及). When you design your function, you will frequently need to check the computational efficiency of your code in order to detect(发现) any bottleneck(瓶颈) in your processing that might slow down(变慢) your program.

1.1 实现方法

  为了衡量函数或代码段的运行时间,OpenCV有一个非常实用的函数,即cv::getTickCount(),该函数返回从最近一次电脑开机到当前的时钟周期数。如希望得到以秒为单位的代码运行时间,要使用另一个方法,即cv::getTickFrequency(),返回每秒的时钟周期数。

  const int64 start = cv::getTickCount();

  colorReduce(image);

  // elapsed (经过的时间) time in seconds

  double duration = (cv::getTickCount() - start) /

  cv::getTickFrequency();

1.2 四种存取像素方式效率对比

  查看.at、pointers、reshape及iterators四种遍历图像方式所消耗时间

//Test running time,edited by yunfung
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;

void colorReduce1(Mat& image, int div = 64)
{
    for (int i = 0; i < image.rows; i++)
    {
         for (int j = 0; j < image.cols; j++)
        {
            image.at<Vec3b>(i, j)[0] = image.at<Vec3b>(i, j)[0] / div*div + div / 2;
            image.at<Vec3b>(i, j)[1] = image.at<Vec3b>(i, j)[1] / div*div + div / 2;
            image.at<Vec3b>(i, j)[2] = image.at<Vec3b>(i, j)[2] / div*div + div / 2;
        }
    }
}

void colorReduce2(cv::Mat image, int div = 64) {
    int nl = image.rows;
    int nc = image.cols * image.channels();
    for (int j = 0; j < nl; j++) {
        uchar* data = image.ptr<uchar>(j);
        for (int i = 0; i < nc; i++) {
            data[i] = data[i] / div*div + div / 2;

        }
    }
}

void colorReduce3(cv::Mat &image, int div = 64) {
    if (image.isContinuous()){
        image.reshape(1, 1);
    }
    int nl = image.rows;
    int nc = image.cols * image.channels();
    for (int j = 0; j < nl; j++) {
        uchar* data = image.ptr<uchar>(j);
        for (int i = 0; i < nc; i++) {
            data[i] = data[i] / div*div + div / 2;
        }
    }
}

void colorReduce4(cv::Mat &image, int div = 64) {
    cv::Mat_<cv::Vec3b>::iterator it = image.begin<cv::Vec3b>();
    cv::Mat_<cv::Vec3b>::iterator itend = image.end<cv::Vec3b>();
    for (; it != itend; ++it) {
        (*it)[0] = (*it)[0] / div * div + div / 2;
        (*it)[1] = (*it)[1] / div * div + div / 2;
        (*it)[2] = (*it)[2] / div * div + div / 2;
    }
}

void calrunTime(int v, Mat&image)
{
    double duration;
    duration = static_cast<double>(getTickCount()); //强制转化为double
    for (int i = 0; i < 10; i++)
    {
        switch (v)
        {
        case 1:
            colorReduce1(image);   //at
            break;
        case 2:
            colorReduce2(image);   //pointers
            break;
        case 3:
            colorReduce3(image);   //reshape(continuous)
            break;
        case 4:
            colorReduce4(image);   //iterators
            break;
        default:
            break;
        }
    }
    duration = static_cast<double>(getTickCount()) - duration;
    duration /= getTickFrequency();
    duration *= (1000/10); //average
    cout << "duration" << v << " : " << duration << "mS"<< endl;
}

int main()
{
    Mat image = imread("test.jpg");
    Mat imageClone = image.clone();
    cout << "yunfung_opencv_learn_test:" <<"\n\n";
    calrunTime(1, image);

    image = imread("test.jpg");
    imageClone = image.clone();
    calrunTime(2, image);
    image = imread("test.jpg");
    imageClone = image.clone();
    calrunTime(3, image);
    image = imread("test.jpg");
    imageClone = image.clone();
    calrunTime(4, image);

    namedWindow("Image Result");
    imshow("Image Result", imageClone);
    waitKey();
    return 0;
}

  可见用at的方式读取像素效率最低,用迭代器速度也比较慢,效率最高的方式还是使用指针读取。

 

转载于:https://www.cnblogs.com/yunfung/p/7554566.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值