2016-09-14 103 views
0

我正在开发一个程序来检测视频或图像中的对象。 它适用于图像,但现在我想用它与视频。我使用特定的文件夹来选择图像,所以我想在检测之前将视频中的帧保存在该文件夹中。 可变视频和salvataggio arered设置。 在下面的代码我导航扔的文件夹analize视频:从视频中提取帧用opencv检测

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); 
} 
} 

显然,它的工作原理,但最后一帧后,它给了我下面的错误:

Assertion stream_index < ogg->nstreams failed at libavformat/oggdec.c:898 I locked for it but i didin't find where is the error

+0

这是因为你没有给出任何条件出来的循环。读取图像后,在for循环中使用此条件。 “if(frame.empty())break”; – Arjun

回答

0

您的视频包含各种流指标,例如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 */ 

你很明显在这里出界。

+0

我使用了ubuntu的默认视频,即文件夹示例中的视频。感谢指出问题在哪里。 –

0

显然我设法解决它,我修改了提取帧的功能。

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; 
} 
}