2016-09-14 107 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; 
} 
}