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

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

时间: 2024-10-15 04:51:10

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

opencv学习笔记(03)——遍历图像(迭代器法)

1 #include <opencv2\highgui\highgui.hpp> 2 #include <opencv2\imgproc\imgproc.hpp> 3 #include <opencv2\core\core.hpp> 4 5 void colorReduce(cv::Mat& img, int div=64); 6 7 8 int main() 9 { 10 cv::Mat img_orginal = cv::imread("F:\\i

opencv学习笔记(02)——遍历图像(指针法)

#include <opencv2\core\core.hpp> #include <opencv2\highgui\highgui.hpp> #include <opencv2\imgproc\imgproc.hpp> #include <iostream> void colorReduce(cv::Mat& image, int div=64) { int nr = image.rows; int nc = image.cols * image.

opencv学习笔记(01)——操作图像的像素

1 #include <opencv2\core\core.hpp> 2 #include <opencv2\highgui\highgui.hpp> 3 #include <opencv2\imgproc\imgproc.hpp> 4 #include <iostream> 5 6 7 void salt(cv::Mat& image, int n) 8 { 9 10 for(int k=0; k<n; k++) 11 { 12 13 int

【opencv学习笔记1】5种图像滤波辨析:方框、均值、高斯、中值、双边

图像滤波 什么是图像滤波 图像滤波,即在尽量保留图像细节特征的条件下对目标图像的噪声进行抑制,是图像预处理中不可缺少的操作,其处理效果的好坏将直接影响到后续图像处理和分析的有效性和可靠性. 图像滤波的目的 a.消除图像中混入的噪声 b.为图像识别抽取出图像特征 图像滤波的要求 a.不能损坏图像轮廓及边缘 b.图像视觉效果应当更好 滤波器的定义 滤波器,顾名思义,是对波进行过滤的器件.(摘自网络) 以上的定义是针对物理器件的,但对于图像滤波而言显然也是适用的. 大家都用过放大镜,这里就以此举一个例

OpenCV(C++接口)学习笔记2-像素级的图像操作

1.通过成员函数at(int y, int x)访问 这种方法需要知道像素保存的格式. (1) 这是为模板类型的函数,因为一个函数的返回类型只有在运行时才会知道. (2)这个函数返回的是一个向量即Vector,故有下标的操作. image.at<uchar>(j,i)= 255; 在单通道图像中,采用以上语句可以获取图像(i,j)处的灰度值(注:先行后列,一般用j表示行(rows),i表示列(cols)).如果是灰度图像的话,只需要更改一个数据就可以了.如果是rgb图像的话,就要用"

Opencv学习笔记(六)SURF学习笔记

原创文章,转载请注明出处:http://blog.csdn.net/crzy_sparrow/article/details/7392345 本人挺菜的,肯定有非常多错误纰漏之处 ,希望大家不吝指正. 看了harris角点检測之后,開始研究SURF角点检測,发现挺复杂的,一时也仅仅了解了大概,把了解的东西总结下,以便下次深入学习. SURF角点检測算法是对SIFT的一种改进,主要体如今速度上,效率更高.它和SIFT的主要差别是图像多尺度空间的构建方法不同. 在计算视觉领域,尺度空间被象征性的表述

opencv学习笔记(四)投影

opencv学习笔记(四)投影 任选了一张图片用于测试,图片如下所示: 1 #include <cv.h> 2 #include <highgui.h> 3 using namespace std; 4 using namespace cv; 5 int main() 6 { 7 IplImage * src = cvLoadImage("cat.png", 0); //强制转化读取图像为灰度图 8 cvShowImage("灰度图像", s

OpenCV学习笔记[3]Java Demo人脸识别

OpenCV学习笔记:Java Demo人脸识别 [简介] 我记得在很久以前,CSDN似乎搞过一个活动,给一个橘子林的照片,让程序计算相片里有多少个橘子.之所以对这个问题记忆犹新,是因为在专业学习初期,相比于排序遍历搜索等简单算法而言,"图像识别"算法一直是难以理解的东西,而我偏偏又痴迷于此,不管自己多么无知,对于令我迷惑的问题总是充满着解决的渴望. 通过对OpenCV的初步了解,我发现图像识别的很多问题都可以用它方便的解决,本次将是一个来自官方的人脸识别的实例,我们提供图像,使用内置

OpenCV 学习笔记(模板匹配)

OpenCV 学习笔记(模板匹配) 模板匹配是在一幅图像中寻找一个特定目标的方法之一.这种方法的原理非常简单,遍历图像中的每一个可能的位置,比较各处与模板是否"相似",当相似度足够高时,就认为找到了我们的目标. 在 OpenCV 中,提供了相应的函数完成这个操作. matchTemplate 函数:在模板和输入图像之间寻找匹配,获得匹配结果图像 minMaxLoc 函数:在给定的矩阵中寻找最大和最小值,并给出它们的位置 在具体介绍这两个函数之前呢,我们还要介绍一个概念,就是如何来评价两