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

来源:互联网 发布:vr软件 编辑:程序博客网 时间:2024/05/21 19:44
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_;


(完)



0 0
原创粉丝点击