前几天提取了一些视频中的人脸头像,交给同事去做识别分析,后来返回来说,其中的头像出现周期性的重复。
由于在视频中进行人脸检测开始是设定隔几幀检测一次,所以循环中使用了 cvSetCaptureProperty() 进行了跳帧,尔后通过cvQueryFrame()获取相应的帧转换成图像,于是怀疑是这里的问题。取消跳帧的规则后,程序检测正常。而修改定位的参数,比如直接改成定位到下一帧,却丝毫不起作用。
帧的重复非常有规律,我这边的测试数据是每隔5帧重复一次。于是就怀疑是否是定位出现了问题。google了一下,果然: opencv中cvSetCaptureProperty定位不准的原因及解决
friedvan的专栏 写道
经过差不多一晚上的探究,得出粗略的结论。原因在于opencv2.0以后,采用ffmpeg采集视频,而在opencv1.0采用vfw采集视频(具体的概念暂时还不清楚,有时间继续补上)。而opencv在定位时候,调用的ffmpeg的av_seek_frame()函数,此函数原型为:
int av_seek_frame(AVFormatContext *s, int stream_index, int64_t timestamp, int flags);
其中,最后一个参数有
AVSEEK_FLAG_BACKWARD = 1; ///< seek backward
AVSEEK_FLAG_BYTE = 2; ///< seeking based on position in bytes
AVSEEK_FLAG_ANY = 4; ///< seek to any frame, even non key-frames
ffmpeg默认的是选取关键帧(这个概念需要具体定义)。opencv里面这个函数的参数flag是0,
int ret = av_seek_frame(ic, video_stream, timestamp, 0);
也就是按照默认的读取关键帧。因此,视频跳跃就出现了。
解决这个问题需要将0改为 AVSEEK_FLAG_ANY ,即:
int ret = av_seek_frame(ic, video_stream, timestamp, AVSEEK_FLAG_ANY );
之后重新编译opencv库,就可以了。
但看了friedvan上面文章的回复,发现有人反映说是重新编译后读取视频出现花屏。因为一时也腾不出手来重新编译了测试,只好先通过另外的方式解决:即在读取的循环中加入判断,如果是需要处理的帧进行处理的逻辑,否则continue
VideoCapture cap;
cap.open("test.avi");
namedWindow("video",1);
int frameNum=0;
int readRatio=3;//读取的周期
for(;;){
if(frameNum%readRatio!=0) continue;
Mat frame;
cap<<frame;
//Do something
frameNum++;
}
分享到:
相关推荐
8. **features2d.2DFeaturesFramework**:提供二维特征检测和描述的框架。 9. **objdetect.ObjectDetection**:实现目标检测算法。 10. **ml.MachineLearning**:提供机器学习相关的功能,如分类器训练。 11. **...
2. 从视频或摄像头中读取一帧: - `cvGrabFrame(cvCapture* capture)`:这个函数抓取当前视频流的一帧,但并不返回该帧数据,而是保存在 `capture` 结构体内部。 - `cvRetrieveFrame(cvCapture* capture)`:调用 `...
3. **播放视频**:`cvCaptureFromAVI`或`cvCreateFileCapture`用于从视频文件中读取帧,`cvQueryFrame`获取当前帧并显示,`cvWaitKey`检测用户是否按下ESC键退出,最后释放内存和销毁窗口。 ### 基本操作 1. **...
这使得用户能够将处理后的视频帧保存为文件,便于后续分析或分享。 ### 19. cvWriteFrame 将一帧图像数据写入由cvCreateVideoWriter创建的视频文件中。这在视频编辑和合成中非常有用。 ### 20. ...
7. **cvCreateFileCapture**:创建一个CvCapture对象,用于从视频文件中读取帧。 8. **cvQueryFrame**:从CvCapture对象中获取下一帧视频图像。 9. **cvReleaseCapture**:释放CvCapture对象所占用的内存。 10. *...
本段代码示例展示了如何使用OpenCV库读取视频文件,并对其进行初步的预处理工作,包括读取视频帧、创建显示窗口、获取视频属性、转换图像格式等步骤。这为后续执行光流法提供了基础准备。需要注意的是,提供的代码...
获取到摄像头帧后,我们可以通过`cvQueryFrame()`函数来获取每一帧的IplImage结构体,这是一个在OpenCV中广泛使用的图像数据结构。每帧图像可以进一步进行处理,如灰度转换、滤波、边缘检测等。这些处理后的图像可以...
如果需要调整捕获的帧率或摄像头的其他属性,可以使用`cvSetCaptureProperty`函数。例如,可以设置摄像头的亮度、对比度等参数,以适应不同的环境条件。 6. **IplImage结构** `IplImage`是OpenCV早期版本中用于...
OpenCV 是一个强大的计算机视觉库,它包含了众多用于图像处理和计算机视觉的函数。以下是 OpenCV 2.0 版本中的一些核心函数及其详细解释: 1. **cvLoadImage**: 此函数用于从磁盘加载图像文件到内存中,支持多种...
OpenCV HighGUI 参考手册 OpenCV HighGUI 是 OpenCV 库中的一个图形用户界面模块,提供了图形界面和视频处理功能。下面是 HighGUI 中一些重要的函数和概念: 1. 窗口管理函数 * cvNamedWindow: 创建一个窗口,...
OpenCV(开源计算机视觉库)是一个强大的计算机视觉和图像处理库,广泛应用于图像分析、识别、追踪等任务。这里我们详细讨论一些常用的OpenCV函数,它们可以帮助你更好地理解和应用OpenCV。 1. **cvLoadImage**: 该...
7. **cvCreateFileCapture**: 用于打开一个视频文件,返回一个CvCapture对象,可以用来读取视频帧。 8. **cvQueryFrame**: 获取CvCapture对象中的下一帧图像,返回IplImage类型的图像。 9. **cvReleaseCapture**: ...
OpenCV(开源计算机视觉库)是图像处理和计算机视觉领域广泛应用的一个库,它提供了大量的函数来处理、分析和识别图像。以下是对标题和描述中提到的一些常用OpenCV函数的详细说明: 1. **cvLoadImage**:这个函数...
7. **cvCreateFileCapture**: 用于打开视频文件,创建一个CvCapture对象,可以读取视频帧。 8. **cvQueryFrame**: 获取视频文件的下一帧并将其加载到内存中,返回一个IplImage指针。 9. **cvReleaseCapture**: ...
- **功能**:此函数用于从文件系统中读取图像,并将其转换为OpenCV的图像格式(通常是IplImage*)。支持多种图像格式,包括BMP、JPEG、PNG等。 - **应用场景**:图像处理或分析项目的初始阶段,用于加载图像文件进行...
### OpenCV函数详解 #### 1. cvLoadImage:加载图像至内存 - **功能**:此函数用于从文件系统中加载图像,并将其存储在内存中。 - **使用方法**:`IplImage* img = cvLoadImage("path/to/image.jpg", CV_LOAD_IMAGE...
使用此函数将处理后的视频帧逐帧写入到视频文件中。 #### 20. cvReleaseVideoWriter:释放CvVideoWriter结构开辟的内存空间 处理完成后,应释放由`cvCreateVideoWriter`创建的对象,释放其占用的内存资源。 #### ...
图像采集模块使用cvCaptureFromCAM()函数从相机获取图像,并通过cvSetCaptureProperty()调整帧宽高。接着,使用QTimer定时器每隔一定时间触发槽函数,槽函数通过cvGrabFrame()抓取图像,再用CvRetrieveFrame()读取帧...