简体   繁体   中英

extract frame from a video for detection with opencv

i'm developing a program to detect object in video or image. It works with the image, but now i want to use it with video. I use a specific folder to pick the image so i wanted to save frames from video in that folder before the detection. The variable video and salvataggio are alredy setted. In the following code i navigate throw the folder to analize the video:

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

The function estraiframe save the frame in the output folder.

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

Apparently it works but after the last frame it gave me the following error:

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

Your video contains various stream indexes, eg 3 audios, and 1 video stream would result in 4 stream indexes. I recommend that you check the amount of streams your video contains and print ogg->nstreams to check if this corresponds. Looking at the source code in oggdec.c at line 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 */

You're clearly going out of bounds here.

Apparently I manage to solve it, I modified the function that extract the frame.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM