您的位置:首页 > 运维架构

opencv2-用迭代器访问图像像素

2015-10-19 21:37 387 查看
opencv2-用迭代器访问图像像素

//-----------------------------------【全局函数声明部分】-----------------------------------

// 描述:全局函数声明

//-----------------------------------------------------------------------------------------------

void colorReduce(Mat& inputImage, Mat& outputImage, int div);

void ShowHelpText();

//--------------------------------------【main( )函数】--------------------------------------

// 描述:控制台应用程序的入口函数,我们的程序从这里开始执行

//-----------------------------------------------------------------------------------------------

int main( )

{

//【1】创建原始图并显示

Mat srcImage = imread("1.jpg");

imshow("原始图像",srcImage);

//【2】按原始图的参数规格来创建创建效果图

Mat dstImage;

dstImage.create(srcImage.rows,srcImage.cols,srcImage.type());//效果图的大小、类型与原图片相同

ShowHelpText();

//【3】记录起始时间

double time0 = static_cast<double>(getTickCount());

//【4】调用颜色空间缩减函数

colorReduce(srcImage,dstImage,32);

//【5】计算运行时间并输出

time0 = ((double)getTickCount() - time0)/getTickFrequency();

cout<<"此方法运行时间为: "<<time0<<"秒"<<endl; //输出运行时间

//【6】显示效果图

imshow("效果图",dstImage);

waitKey(0);

}

//-------------------------------------【colorReduce( )函数】-----------------------------

// 描述:使用【迭代器】方法版的颜色空间缩减函数

//----------------------------------------------------------------------------------------------

void colorReduce(Mat& inputImage, Mat& outputImage, int div)

{

//参数准备

outputImage = inputImage.clone(); //拷贝实参到临时变量

//获取迭代器

Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>(); //初始位置的迭代器

Mat_<Vec3b>::iterator itend = outputImage.end<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;

// ------------------------【处理结束】----------------------------

}

}

//-----------------------------------【ShowHelpText( )函数】----------------------------------

// 描述:输出一些帮助信息

//----------------------------------------------------------------------------------------------

void ShowHelpText()

{

//输出欢迎信息和OpenCV版本

printf("\n\n\t\t\t非常感谢购买《OpenCV3编程入门》一书!\n");

printf("\n\n\t\t\t此为本书OpenCV2版的第22个配套示例程序\n");

printf("\n\n\t\t\t 当前使用的OpenCV版本为:" CV_VERSION );

printf("\n\n ----------------------------------------------------------------------------\n");

}

程序分析,先来看一下计算时间的函数。

(1)CV_EXPORTS_W int64
getTickCount()

The function returns the number of ticks since the certain event (e.g. when the machine was turned on).

It can be used to initialize cv::RNG or to measure a function execution time by reading the tick count

before and after the function call. The granularity of ticks depends on the hardware and OS used. Use

cv::getTickFrequency() to convert ticks to seconds

该英文翻译为:该函数返回的是某个触发事件所经历的tick次数(当计算机开始计算)。通过计算tick次数,可以用于初始化RNG或者检测一个被调用的应用程序的运行时间。具体的tick次数视硬件和os平台而定。使用getTickFrenquency来把tick转换成秒。

CV_EXPORTS_W double getTickFrequency()//每一秒经历的tick次数

经典用法:

double exec_time = (double)getTickCount();

exec_time = ((double)getTickCount() - exec_time)*1000./getTickFrequency();

再来区分一下这个函数GetTickCount()

实际上,该getTickCount()函数为opencv中的函数,该函数返回的值为自从某一时刻(比如计算机启动)开始,计算机总共经过的tick的次数,其需要结合getTickFrequency()函数使用,getTickFrequency()返回的是CPU在一秒钟内会发出的tick的次数,总体来说,该函数的精度较高,能够精确到1ms左右,获得时间的一个例子如:

double t = (double)getTickCount();

//do sth.

t = ((double)getTickCount() - t)/getTickFrequency(); //获得时间,单位是秒

使用时应注意加上 using namespace cv;

GetTickCount(),首字母大写后,该函数即为windows编程自带的API函数了,也是统计时间用的,但是用起来的时候,返回的值直接就是ms.根据参考文献,其精度大概只有18ms左右。

使用时,应注意:

库文件:kernel32.dll

C/C++头文件:winbase.h

windows程序设计中可以使用头文件windows.h

(2)迭代器iterator

来看这几句:

Mat_<Vec3b>::iterator it = outputImage.begin<Vec3b>(); //初始位置的迭代器

Mat_<Vec3b>::iterator itend = outputImage.end<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;

// ------------------------【处理结束】----------------------------

}

意思是定义一个迭代器来实现访问像素的过程。首先定义iterator it,是图像的开始指针。然后定义iterator itend,是图像结束像素的指针。然后通过遍历迭代器来访问图像的全部像素。

template<typename _Tp> class CV_EXPORTS Mat_ : public Mat,从矩阵Mat派生出来的类Mat_,是一个_Tp类型的模板类,是个可以存储相关类型对象的集合。

而typedef Vec<uchar, 3> Vec3b;是uchar类型的3通道数据。

迭代器iterator的原型是:

typedef MatIterator_<_Tp> iterator;

而MatIterator_<_Tp>的原型又是:

template<typename _Tp> class CV_EXPORTS MatIterator_;

(完)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: