技术标签: 图像处理 | 目标跟踪 | OpenCV 计算机视觉-目标跟踪
视频中包含的信息要远远大于图片,对视频的分析也成为计算机视觉的主流,而本质上视频是由一帧帧的图像组成,所以视频处理最终还是要归结于图像处理,但在视频处理中,有更多的时间维的信息可以利用。1.1视频帧的读取
OpenCV为视频的读入提供了一个类VideoCapture,下面我们说明一下类的几个重要的方法:
1,打开一段视频或默认的摄像头
有两种方法,一种是在定义类的时候,一种是用open()方法。
如果把文件名换为设置ID,则可打开摄像头,默认摄像头为0。VideoCapture capture("../video.avi"); // 方法1 capture.open("../video.avi"); // 方法2
2,获取视频帧
获取视频帧可以有多种方法:
3,获取视频的参数capture.read(frame);// 方法一 capture.grab();// 方法二 capture.retrieve(frame); capture>>frame;// 方法三
一个视频有很多参数,比如:帧率、总帧数、尺寸、格式等,VideoCapture的get方法可以获取大量这些参数。
更加相关的参数可以参考手册。double rate=capture.get(CV_CAP_PROP_FPS); // 获取 long nFrame=static_cast<long>(capture.get(CV_CAP_PROP_FRAME_COUNT));
4,设置视频帧的读取位置
VideoCapture类的set方法可以允许我们取出视频中某个位置的帧,它有一些参数,可以按时间,也可以按帧号,还可以按视频长短的比例。当然,set方法仅用于取视频帧的位置,还可以设置视频的帧率、亮度。// 第100帧 double position=100.0; capture.set(CV_CAP_PROP_POS_FRAMES,position); // 第1e6毫秒 double position=1e6; capture.set(CV_CAP_PROP_POS_MSEC,position); // 视频1/2位置 double position=0.5; capture.set(CV_CAP_PROP_POS_AVI_RATIO,position);
下面是一个将canny边缘检测应用于视频的程序:
int main() { VideoCapture capture("../track.avi"); if(!capture.isOpened()) return 1; double rate=capture.get(CV_CAP_PROP_FPS); bool stop(false); Mat frame; namedWindow("Canny Video"); int delay=1000/rate; while(!stop) { if(!capture.read(frame)) break; Mat result; Canny(frame,result,100,200); threshold(result,result,128,255,THRESH_BINARY); imshow("Canny Video",result); if(waitKey(delay)>=0) stop=true; } capture.release(); }
1.2视频的写入
视频的写入与读取类似,OpenCV中是使用VideoWriter类来实现的,这个类有几个方法,都很简单。除了构造函数外,提供了open、IsOpen、write、和重载操作符<<
值得注意的是OpenCV里对视频的编码解码等支持并不是很良好,所以不要希望用这个类去实现摄像头图像的获取与转码,有兴趣的可以参考FFmpeg库。
上面是类的构造函数与open方法,它们的参数相同,首先指定文件名,第二个参数是编码格式,OpenCV里提供了很多种的编码格式,如CV_FOURCC(‘P’,’I’,’M’,’1’)是MPEG-1格式,CV_FOURCC(‘M’,’G’,’P’,’G’)为motion-jpeg格式。第三个参数为帧率,第4个参数为视频的尺寸大小。VideoWriter::VideoWriter(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true); bool VideoWriter::open(const string& filename, int fourcc, double fps, Size frameSize, bool isColor=true);
VideoCapture capture("../track.avi"); double rate=capture.get(CV_CAP_PROP_FPS); Size videoSize(capture.get(CV_CAP_PROP_FRAME_WIDTH), capture.get(CV_CAP_PROP_FRAME_HEIGHT)); VideoWriter writer; writer.open("../result.avi",CV_FOURCC('P','I','M','1'),rate, videoSize); Mat frame; capture>>frame; writer<<frame;
实验结果:#include <cv.h> #include <highgui.h> int main( int argc, char** argv ) { IplImage* pImg; //声明IplImage指针 //colorful->grayscale if( argc == 2 && (pImg = cvLoadImage( argv[1], CV_LOAD_IMAGE_UNCHANGED)) != 0 ) { IplImage* pImg2 = cvCreateImage(cvGetSize(pImg), pImg->depth, pImg->nChannels); //CV_CVTIMG_FLIP 垂直翻转 //CV_CVTIMG_SWAP_RB 交换红蓝通道 cvConvertImage(pImg, pImg2, CV_CVTIMG_FLIP); cvNamedWindow( "Image", 1 ); cvShowImage( "Image", pImg ); cvWaitKey(0); cvShowImage( "Image", pImg2 ); cvWaitKey(0); cvDestroyWindow( "Image" ); cvReleaseImage( &pImg ); cvReleaseImage( &pImg2 ); return 0; } return -1; }
文章浏览阅读340次。1134 最长递增子序列基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题 收藏 关注给出长度为N的数组,找出这个数组的最长递增子序列。(递增子序列是指,子序列的元素是递增的)例如:5 1 6 8 2 4 5 10,最长递增子序列是1 2 4 5 10。Input第1行:1_说明书上有着一个长度为 n (2 <= n <= 50000)的序列 a (-10^9 <= a[i] <= 10^9)的
文章浏览阅读1.1w次。有些数据库,比如MySQL支持一次性插入多条数据的语法,当然也有些数据库不支持。这里演示了两种方法,一种适用于支持多条数据插入语法的数据库,另外一个适用于不支持多条数据插入语法的数据库,两者都能实现一次性插入多条数据的功能。这里用到的两个方法:InsertMulti和PrepareInsert的原型如下:func (o *querySet) PrepareInsert() (Inserte
文章浏览阅读4.5k次,点赞2次,收藏2次。一、环境变量1、/etc/profile:在登录时,操作系统定制用户环境时使用的第一个文件,此文件为系统的每个用户设置环境信息,当用户第一次登录时,该文件被执行。 2、/etc/environment:在登录时操作系统使用的第二个文件,系统在读取你自己的profile前,设置环境文件的环境变量。 3、~/.bash_profile:在登录时用到的第三个文件是.bash_pr_z,,,j vf
文章浏览阅读1.5k次。第六章 支持模块本章描述为管理整体应用程序行为所提供的一些基础支持特征及配置参数的APIs所对应的模块。6.1 应用支持和管理模块SYS/BIOS和XDCtools提供了数个模块用于支持和管理整个应用程序行为。以下模块提供了属于这个类别的APIs和配置设置:BIOS Module (ti.sysbios.BIOS): 负责SYS/BIOS启动和全局参数维护。_bios_getthreadtype
文章浏览阅读3.6k次。前言NumPy 中的数组称为 N-dimensions arrays 或者 ndarray,顾名思义NumPy的数组是一种多维数组。dimension的意思就是维度的意思,在NumPy中,用axis(轴)来表示dimension,也就是用axis来表示NumPy的维度。本文用画图的方式彻底理解NumPy数组的dimenss(axes) 和 Index(索引)。注:axis的复数形式是axes。利用..._numpy数组画图
文章浏览阅读1.2k次。哇!刚刚突然发现我的那篇扩展欧几里得达到了500+的阅读量,开森森~ 看起来努力就是有回报的嘛!用心写的文章和不用心写的文章相信广大程序员萌都一眼看得出来撒~快乐!你们的关注和点赞是我最大的动力嗷!┗|`O′|┛好了,闲话不多说~ 正片开始!A.跑步训练这个题个人不建议写程序,直接手算就好了,但是要注意的是,每一轮-600然后+300,就相当于-300,但是!一定要记得这-300的时间是120s,..._2019年到2020年芜湖市c++考试试卷
文章浏览阅读572次,点赞21次,收藏8次。指定启用或者禁用的功能 --enable-ssl --disable-filter。16、mysql的innodb如何定位锁问题,mysql如何减少主从复制延迟?2、在工作中,运维人员经常需要跟运营人员打交道,请问运营人员是做什么工作的?6、Squid、Varinsh和Nginx有什么区别,工作中你怎么选择?5、LVS、Nginx、HAproxy有什么区别?9、讲述一下Tomcat8005、8009、8080三个端口的含义?7、Tomcat和Resin有什么区别,工作中你怎么选择?
文章浏览阅读1.3k次。前端干着干着,就把自己干没了......作者 | 郭芮出品 | CSDN资讯要说开源精神,阿里估计在国内能够排在最前列。近几年,阿里接二连三“搞事情”。根据阿里近期发布的..._源代码智能科技有限公司
文章浏览阅读870次。对倾斜的Keys采样进行单独的Join操作步骤有点复杂:首先对RDD1进行采样,例如RDD1进行Sample抽样(15%)可以计算出一个结果,其是一个RDD,采样之后进行Map操作,通过reduceBykey操作计数,然后对Key和Value进行置换,通过SortByKey进行排序,再进行Map置换操作,从而找出哪一个Key值倾斜比较严重,对其进行过滤,提取到RDD11中,剩下的提取到RDD12中。避免了占用过多内存。如果倾斜的Key特别多,如50多个倾斜的Key,我们可以一个一个地对Key进行过滤处理。_spark 数据采样
文章浏览阅读145次。前言据说是一个程序员为了讨好老婆而编写的一个搜索引擎,结果意外的大受欢迎。业界大名鼎鼎的全文搜索引擎一、安装docker选择使用docker来安装,是因为省事。由于我是在linux环境下安装的docker,所以,安装docker也省事。至于windows下安装docker,这个就比较折腾了。建议安装虚拟机,然后在虚拟机上安装linux再在linux上安装docker。二、拉取镜像这里的镜像,我选择了nshou/elasticsearch-kiban,原因是少折腾,因为kiban是elastic_elasticsearch nshou/elasticsearch-kibana
文章浏览阅读4.1k次,点赞4次,收藏9次。决策树的剪枝处理为什么要进行决策树的剪枝处理呢?决策树的过拟合的风险很大,因为理论上来说可以将数据完全分的开,如果树足够大,每个叶子节点就剩下了一个数据。那么,这就会造成模型在训练集上的拟合效果很好,但是泛化能力很差,对新样本的适应能力不足。所以,对决策树进行剪枝,可以降低过拟合的风险。决策树的剪枝策略决策树的剪枝策略分为预剪枝和后剪枝预剪枝预剪枝就是边建立决策时边进行剪枝的操作。..._决策树为什么要剪枝
文章浏览阅读6.2k次,点赞13次,收藏59次。基础知识条件概率(Conditional Probability)相互独立时,p(A | B) = p(A)贝叶斯规则贝叶斯网络(Bayesian Network)定了一个独立的结构:一个节点的概率仅依赖于它的父节点。贝叶斯网络适用于稀疏模型,即大部分节点之间不存在任何直接的依赖关系。联合概率(Joint Probability)表示所有节点共同发生的概率,将所有条件概率相乘:我们最终的目标是计算准确的边缘概率(Marginal Probability),比如计算Hangover的概_app-bp概率域置信传播