用opencv从视频中提取帧进行检测
extract frame from a video for detection with opencv
我正在开发一个程序来检测视频或图像中的物体。它适用于图像,但现在我想用它与视频。我使用一个特定的文件夹来选择图像,所以我想在检测之前将视频中的帧保存在该文件夹中。可变视频和salvataggio已经设置好了。在下面的代码中,我打开文件夹来分析视频:
DIR *dir;
dir = opendir(video.c_str());
string vidName;
struct dirent *ent;
if (dir != NULL) {
while ((ent = readdir (dir)) != NULL) {
vidName= ent->d_name;
if(vidName.compare(".")!= 0 && vidName.compare("..")!= 0)
{
//string vidPath(neg + vidName);
estraiframe(video, vidName, salvataggio);
}
}
closedir (dir);
}
else {
cout<<"directory "<< video << " not present"<<endl;
}
}
函数estraiframe将帧保存在输出文件夹中。
void estraiframe(string path, string vidName, string output){
string vidPath(path + vidName);
VideoCapture cap(vidPath);
if( !cap.isOpened()){
cout << "Cannot open the video file" << endl;
return;
}
double count = cap.get(CV_CAP_PROP_FRAME_COUNT);
double rate = cap.get(CV_CAP_PROP_FPS);
int counter = 0;
for (int i=1; i< count; i+=rate*5)
{
cap.set(CV_CAP_PROP_POS_FRAMES,i);
Mat frame;
cap.read(frame);
counter++;
string nomeframe = to_string(counter) + "-frame_from"+vidName+".jpg";
string percorso (output+nomeframe);
cout << percorso;
imwrite(percorso,frame);
}
}
显然它工作,但在最后一帧后,它给了我以下错误:
断言stream_index
您的视频包含各种流索引,例如3个音频,1个视频流将产生4个流索引。我建议您检查您的视频包含的流的数量,并打印ogg->nstreams来检查这是否对应。查看oggdec.c中的源代码,第898行
static int ogg_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags) { struct ogg *ogg = s->priv_data; struct ogg_stream *os = ogg->streams + stream_index; int ret; av_assert0(stream_index < ogg->nstreams); /* Line 898 */
你显然越界了
显然我设法解决了这个问题,我修改了提取框架的函数。
void estraiframe(string path, string vidName, string output){
string vidPath(path + vidName);
VideoCapture cap(vidPath);
if( !cap.isOpened()){
cout << "Cannot open the video file" << endl;
return;
}
double rate = cap.get(CV_CAP_PROP_FPS);
int counter = 0;
Mat frame;
int i=1;
while(1)
{
cap.read ( frame);
if( frame.empty()) break;
counter++;
if (counter == rate*5*i){
i++;
string nomeframe = to_string(counter) + "-frame_from"+vidName+".jpg";
string percorso (output+nomeframe);
imwrite(percorso, frame);
}
char key = waitKey(10);
if ( key == 27) break;
}
}
相关文章:
- 从包含m行的文件中提取n行,必要时(惰性地)重复该文件
- 使用CMake检测支持的C++标准
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么istream不支持右值提取
- 当套接字连接断开时检测C/C++Unix
- C/C++预处理器是否可以检测一些编译器选项
- WMI检测进程创建事件-c++
- 基于树莓pi的tensorflow lite量化ssd目标检测
- 下面是我为检测链接列表中的循环而制作的代码
- 如何设置一个范围来提取我想要获得的信息
- 落砂模拟碰撞检测C++和SFML
- 我可以检测和更改 gcc/g++ 中结构的当前数据对齐设置吗?
- 为什么C++编译器没有检测到正确声明的类?
- 检测win32服务创建和删除的最佳方法
- 使用 istream 提取运算符进行 csv 解析:如何检测缺失的字段值?
- Gabor特征提取用于检测人
- Istream提取操作符:如何检测解析失败
- 用opencv从视频中提取帧进行检测
- 从Blob检测中提取OpenCV轮廓阵列
- 如何在图像处理中提取模式识别算法中的特定特征以进行对象检测