zoukankan      html  css  js  c++  java
  • OpenCV 入门级一

    首先声明,这一系列博文是本人在学习 OpenCV 的过程中对自身学习的一个总结而已,

    仅作为 OpenCV 入门级参考,并没有什么内容值得高手参考,

    所以,只适合和我一样正值学习状态者阅读,高手无意者请飘过,但欢迎留言指教。

                 

    OpenCV 是一个开源的计算机视觉库,其采用 C/C++ 编写,被设计为可移植的库,

    OpenCV 的设计目标是执行速度尽可能的快,

    其主要关注的是实时应用,同时,OpenCV 的另一个目标是构建一个简单易用的计算机视觉框架,

    以帮助开发人员更便捷地设计更复杂的计算机视觉相关的应用程序。

               

    OpenCV 的结构和内容

    image

    上面这幅截图是 OpenCV 源码的文件组成结构,可以看出其中包括 cv ,cvaux , cxcore , highgui , ml 这 5 个模块。

    如果以库来体现这几个模块之间的关系的话,可以采用下面的结构图来展现:

    image

    CV:   包含了基本的图像处理函数和高级的计算机视觉算法,包括图像处理,

             图像结构分析,运动描述和跟踪,模式识别和摄像机标定。

    ML:   是机器学习库,包含一些基于统计的分类和聚类工具。

    HighGUI:   包含图像和视频的输入/输出函数。

    CXCORE:   包含了 OpenCV 的一些基本的数据结构和相关函数。

    CVAUX:   该模块则是一般用存放即将被淘汰的算法和函数,同时也包含一些新出现的实验性的函数和算法。

    关于 OpenCV 的介绍到此介绍,下面呢,就是通过一个 Demo 来学习一些常用的 API 的使用。

             

    Demo 学习               

    Demo01

    下面的 Demo 将介绍如何显示一张图片,具体 API 的使用请注意注释。

                   

    //在HighGUI 模块中包含了图像和视频的输入/输出的基本函数
    #include "highgui.h"
    
    //使用了命令行下运行的形式,其中要在命令行下传递参数
    int main(int argc,char ** argv)
    {
    	//通过cvLoadImage 将一幅指定路径的图片加载到内存中
    	//同时会生成一个IplImage 类型的结构
    	//这个结构会指向图片所在的内存区域
    	IplImage * image=cvLoadImage(argv[1]);
    	//通过cvNamedWindow 来建立一个窗体
    	//因为图片必须在指定的窗体中才能显示
    	cvNamedWindow("Demo01",0);
    	//通过cvShowImage 函数来指定在指定的窗口中显示指定的图片
    	cvShowImage("Demo01",image);
    
    	//暂停程序的执行
    	//只有当用户按下任意键后才执行后面的代码
    	cvWaitKey(0);
    	//释放掉加载到内存中的图片所占的内存资源
    	cvReleaseImage(&image);
    	//销毁窗口
    	cvDestroyWindow("Demo01");
    }
      

    至于程序的执行的话,必须到命令行下执行,同时还需要将一张图片拷贝到 exe 文件所在的目录,

    然后再在命令行中指定该图片作为参数传递到 Main 函数中。

    image 

             

    Demo02

    下面继续看下一个 Demo,这个 Demo 将展示播放视频文件:

                  

    //图像和视频的输入/输出均在HighGUI 模块中
    #include "highgui.h"
    
    //播放视频文件只需要循环的顺序的读取视频中的每一帧
    //读到帧后,便可以将这个帧作为普通的图像一样显示即可
    int main(int argc,char **argv)
    {
    	//首先需要建立一个窗口来容纳视频的播放
    	cvNamedWindow("Demo02",CV_WINDOW_AUTOSIZE);
    	//打开一个视频文件,返回的 CvCapture 结构中包含了视频文件的信息
    	CvCapture *capture=cvCreateFileCapture(argv[1]);
    
    	IplImage *frame;
    	//循环顺序的读取视频中的帧
    	while(1)
    	{
    		//获取当前播放帧的下一个帧,并且将获取到的帧加载到内存中,覆盖掉前面帧所占的内存控件
    		frame=cvQueryFrame(capture);
    		if(!frame)
    		{
    			//如果没有读取到帧的话则说明播放完毕了
    			//从而退出播放
    			break;
    		}
    		//将读取到的帧显示在窗口中
    		cvShowImage("Demo02",frame);
    		//每播放一个帧就在此等待30 毫秒
    		char c=cvWaitKey(30);
    		//如果在30 ms 中用户按下了ESC 键
    		//(ESC 的ASCII 为27)则退出播放
    		if(c==27)
    		{
    			break;
    		}
    	}
    
    	//分配的内存需要手动释放
    	cvReleaseCapture(&capture);
    	//销毁窗口
    	cvDestroyWindow("Demo02");
    }
      

    image 

    image 

    image 

                 

    Demo03

    上面呢,确实是可以成功的播放视频了,但是一般的视频播放器都是有个滚动条的,

    允许用户手动拖动滚动条从而定位到视频指定的帧上,

    下面我们就要实现这个功能了。 

                

    //CV 模块中包含了图像处理,图像结构分析,
    //运动描述和跟踪,模式识别和摄像机标定
    #include "cv.h"
    
    //包含了图像和视频的输入/输出
    #include "highgui.h"
    
    //用来标定滚动条当前的位置
    int g_Pos=0;
    //将打开的视频文件作为一个全局变量使用
    CvCapture * g_Capture=NULL;
    
    //当拖动滚动条后,会回调这个函数
    //同时会将当前滚动条的位置以32 位形式传递过来
    void CallBackTrackBarSlide(int pos)
    {
    	//这里便是重新设置视频文件当前播放的帧
    	cvSetCaptureProperty(g_Capture,CV_CAP_PROP_POS_FRAMES,pos);
    }
    
    
    int main(int argc,char **argv)
    {
    	cvNamedWindow("Demo03",CV_WINDOW_AUTOSIZE);
    	//根据参数打开指定的视频文件
    	g_Capture=cvCreateFileCapture(argv[1]);
    
    	//获得总的帧数
    	int totalFrames=
    		(int)cvGetCaptureProperty(g_Capture,CV_CAP_PROP_FRAME_COUNT);
    
    	if(totalFrames!=0)
    	{
    		//创建滚动条,在这里指定了滚动条拖动后的回调函数
    		cvCreateTrackbar("TrackBar","Demo03",
    			&g_Pos,totalFrames,CallBackTrackBarSlide);
    	}
    
    	IplImage * frame;
    	//循环的顺序的遍历所有的帧
    	while(1)
    	{
    		//获取当前帧的下一个帧,并将其加载到内存中
    		frame=cvQueryFrame(g_Capture);
    		if(!frame)
    		{
    			break;
    		}
    		cvShowImage("Demo03",frame);
    		char chKeyCode=cvWaitKey(30);
    		if(chKeyCode==27)
    		{
    			break;
    		}
    	}
    
    	cvReleaseCapture(&g_Capture);
    	cvDestroyWindow("Demo03");
    
    	return 0;
    }

                      

    在测试的时候需要注意,有一些视频文件时不支持动态指定帧的操作,所以有可能拖动时会失败。                   

    image

     image

     image

    然后就可以拖动滚动条来定位帧了

    image

                    

    Demo03

    上面的 Demo 呢确实是实现了可以通过拖动滚动条来实现对视频帧的动态控制,

    但是有一个问题就是滚动条并不会跟随视频的播放而自带增加,也就是,随时时间流逝,

    视频会一直播放,但是滚动条如果不人为地拖动的话是不会发生改变的,

    而我们要是实现的就是当视频播放到哪一个帧了,滚动条就应该位于相应的位置上,

    所以下面的 Demo 就来实现这个功能。

              

    //CV 模块中包含了图像处理,图像结构分析,
    //运动描述和跟踪,模式识别和摄像机标定
    #include "cv.h"
    
    //包含了图像和视频的输入/输出
    #include "highgui.h"
    
    //用来标定滚动条当前的位置
    int g_Pos=0;
    //将打开的视频文件作为一个全局变量使用
    CvCapture * g_Capture=NULL;
    
    //当拖动滚动条后,会回调这个函数
    //同时会将当前滚动条的位置以32 位形式传递过来
    void CallBackTrackBarSlide(int pos)
    {
    	//这里便是重新设置视频文件当前播放的帧
    	cvSetCaptureProperty(g_Capture,CV_CAP_PROP_POS_FRAMES,pos);
    	g_Pos=pos;
    }
    
    
    int main(int argc,char **argv)
    {
    	//建立一个名字叫做Demo04 的窗体
    	cvNamedWindow("Demo04",CV_WINDOW_AUTOSIZE);
    	//根据参数打开指定的视频文件
    	g_Capture=cvCreateFileCapture(argv[1]);
    
    	//获得总的帧数
    	int totalFrames=
    		(int)cvGetCaptureProperty(g_Capture,CV_CAP_PROP_FRAME_COUNT);
    
    	if(totalFrames!=0)
    	{
    		//创建滚动条,在这里指定了滚动条拖动后的回调函数
    		cvCreateTrackbar("TrackBar","Demo04",
    			&g_Pos,totalFrames,CallBackTrackBarSlide);
    	}
    
    	IplImage * frame;
    
    	//循环的顺序的遍历所有的帧
    	while(1)
    	{
    		//获取当前帧的下一个帧,并将其加载到内存中
    		frame=cvQueryFrame(g_Capture);
    		if(!frame)
    		{
    			break;
    		}
    		cvShowImage("Demo04",frame);
    	
    		char chKeyCode=cvWaitKey(30);
    		if(chKeyCode==27)
    		{
    			break;
    		}
    
    		g_Pos++;
    
    		//当播放完200 个帧的时候才触发滚动条滚动
    		if(g_Pos%200==0)
    		{
    			cvSetTrackbarPos("TrackBar","Demo04", g_Pos);
    		}
    	}
    
    	cvReleaseCapture(&g_Capture);
    	cvDestroyWindow("Demo03");
    
    	return 0;
    }
               

    image

    image

    从而实现了滚动条随着视频的播放而自动滚动的效果。

               

             

    这一篇博文就写到这里了,从上面可以看出,主要是随着逐步的深入来介绍一些 OpenCV 的常用的 API ,

    其主线是首先是加载一张图片,而后再是加载视频,再在视频中加入滚动条,最后是滚动条和视频联动的效果,

    随着一步一步的深入,可以更好的熟悉 OpenCV 的几个常用的 API 。

  • 相关阅读:
    【面积并】 Atlantis
    【动态前k大 贪心】 Gone Fishing
    【复杂枚举】 library
    【双端队列bfs 网格图建图】拯救大兵瑞恩
    【奇偶传递关系 边带权】 奇偶游戏
    【权值并查集】 supermarket
    CF w4d3 A. Pythagorean Theorem II
    CF w4d2 C. Purification
    CF w4d2 B. Road Construction
    CF w4d2 A. Cakeminator
  • 原文地址:https://www.cnblogs.com/mtcnn/p/9410121.html
Copyright © 2011-2022 走看看