码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2017-09-20 00:33:05      阅读:284      评论:0      收藏:0      [点我收藏+]

标签:col   row   red   nec   default   std   .com   opencv2   函数返回   

  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的方式读取像素效率最低,用迭代器速度也比较慢,效率最高的方式还是使用指针读取。

 

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

标签:col   row   red   nec   default   std   .com   opencv2   函数返回   

原文地址:http://www.cnblogs.com/yunfung/p/7554566.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!