• 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 。

            

                   

                                                                                2010 年 10 月 23 日

                  

  • 相关阅读:
    Mybatis入门
    java开发七大原则
    常用的一些实用类
    sql语句大全
    jsp中9个隐含对象
    解决POST和GET方式的中文乱码问题
    Servlet跳转页面的重定向和转发
    通用增删改查的方式
    IDEA 部署spring Cloud
    Oracle基础语法
  • 原文地址:https://www.cnblogs.com/zhouwenJS/p/3739008.html
Copyright © 2020-2023  润新知