2010-12-04 2 views
13

OpenCV로 처리하려고하는 33 초 비디오가 있습니다. 내 목표는 각 프레임이 해당하는 시간의 인스턴스 (비디오의 시작 부분에 비례)를 결정하는 것입니다. 저는 다른 프레임 속도로 녹화 된 동일한 장면의 비디오에서 프레임을 비교할 수 있도록이 작업을 수행하고 있습니다.OpenCV가 정확한 프레임 속도/카운트를보고하지 않습니다.

는 무엇의 작업은 :

  • 는 FPS가 제대로 59.75로보고됩니다. 이것은 ffprobe이보고 한 내용과 일치하므로 정확하다고 믿기 때문에 기쁩니다. 나는 데

문제는 다음과 같습니다

  • CAP_PROP_POS_MSEC 반환 잘못된 값. 동영상이 끝날 때까지 최대 557924ms (9 분 이상)입니다. 33 세 비디오의 경우, 이것이 옳지 않을 수 있습니다.
  • CAP_PROP_FRAME_COUNT도 올바르지 않습니다. 33371로보고되었는데, 59.75fps로 9 분 분량의 영상을 제공합니다. 위의 오류와 일치하지만 여전히 올바르지 않습니다.
  • CAP_PROP_POS_FRAME도 마찬가지입니다.

비디오는 here (약 10MB)입니다.

무엇이 잘못 될 수 있는지에 대한 아이디어가 있습니까?

ffprobe 출력 :

FFprobe version SVN-r20090707, Copyright (c) 2007-2009 Stefano Sabatini 
    libavutil  49.15. 0/49.15. 0 
    libavcodec 52.20. 0/52.20. 1 
    libavformat 52.31. 0/52.31. 0 
    built on Jan 20 2010 00:13:01, gcc: 4.4.3 20100116 (prerelease) 
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/misha/Dropbox/Public/sequence.mp4': 
    Duration: 00:00:33.37, start: 0.000000, bitrate: 2760 kb/s 
    Stream #0.0(und): Video: h264, yuv420p, 1920x1080, 59.75 tbr, 1k tbn, 2k tbc 
    Stream #0.1(und): Audio: aac, 44100 Hz, stereo, s16 

전체 코드 :

#include <iostream> 
#include <assert.h> 

#include <cv.h>  
#include <highgui.h> 

#include <cmath> 
#include <iostream> 
#include <string.h> 
#include <stdio.h> 

extern "C" 
{ 
#include "options.h" 
} 

using namespace std; 

#define DEBUG 0 

static void 
print_usage(char *argv0) 
{ 
    cerr << "usage: " << argv0 << " video.avi [options]" << endl; 
} 

int main(int argc, char** argv) 
{ 
    if (argc < 2) 
    { 
     print_usage(argv[0]); 
     return -1; 
    } 

    int   step  = 30; 
    struct Option options[] = 
    { 
     { "step",  1, &step }, 
     { NULL,   0, NULL } 
    }; 

    int ret = parse_options(2, argc, argv, options); 
    if (ret == 0) 
    { 
     print_usage(argv[0]); 
     return -1; 
    } 

    CvCapture *capture = cvCaptureFromFile(argv[1]); 
    int counter = 0; 
    while (cvGrabFrame(capture)) 
    { 
     ++counter; 

     IplImage *frame = cvRetrieveFrame(capture); 
     double millis = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_MSEC); 
     double current = cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES); 
     double total = cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT); 
     printf("%d %d/%d %f\n", counter, (int)current, (int)total, millis); 
     int min = (int)(millis/1000/60); 
     millis -= min*60000; 
     int sec = (int)(millis/1000); 
     millis -= sec*1000; 

     printf("%d %02d:%02d:%f\n", counter, min, sec, millis); 
    } 
    cvReleaseCapture(&capture); 

    return 0; 
} 
+0

다음 중 어느 것을 사용하고 있습니까? Windows/Linux/Mac? – karlphillip

+0

Linux (Ubuntu 10.04 LTS) – misha

+1

많은 설명이 있습니다. OpenCV는 여전히 Linux에서 비디오 파일의 지원을 개선하기 위해 노력하고 있습니다. – karlphillip

답변

5

항상 사용중인 소프트웨어 버전 통보 :되는 OpenCV의 버전은 당신이를 위해 사용하고 있습니까? 귀하의 버전은 구 버전 일 수 있으므로 최대한 최신 버전으로 업데이트하십시오.

CV_CAP_PROP_POS_MSEC - film current position in milliseconds or video capture timestamp 

OpenCV의 단순히 분명히 잘못된 파일 헤더에서 모든 물건을 읽을 수 있습니다 : 비디오 파일을 다른 더 큰 영상의 일부인 경우

,이 정보는 사실 때문에, 정확한 수 있습니다. 누군가가 도끼 (또는 다른 중세 도구)를 사용하여 원본 비디오에서이 조각을 떼어 내면 이런 일이 발생할 수 있습니다.

변경 한 적이없는 비디오로 시도해야합니다.

최악의 시나리오 인 경우 이러한 기능을 직접 구현해야합니다. 더 이상.

편집 : 나는 당신이 사용하고 있는지 처음에는 알아 차리지 않았다 @misha : 당신이 할 수있는 경우

CvCapture *capture = cvCaptureFromFile(argv[1]); 

위해 교체 cvCaptureFromAVI(), 반환 값 항상 확인 OpenCV 전화 번호 :

CvCapture *capture = cvCaptureFromAVI(argv[1]); 
if(!capture) 
{ 
    printf("!!! cvCaptureFromAVI failed (file not found?)\n"); 
    return -1; 
} 

며칠 전 uses OpenCV to read a video file and then save the frames as JPG images on the disk 코드를 공유했습니다. 또한 기존의 cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);을 사용하여 현재 FPS를보고하므로 재미있을 수도 있습니다. 가서 확인해.

편집 :

또한 OpenCV의를 사용하여 프레임 수에 대한 this thread을 확인해야합니다; 그런데

은, 난 그냥 내 우분투 시스템에 일부 라이브러리를 업데이트 OpenCV의-2.1.0.tar.bz2이 ( cmake를 사용하여) 다시 컴파일. 내 소스 코드 ( cvCaptureFromAVI())를 사용하여 각 프레임의 디버그 방법을 사용하여 내용을 인쇄했습니다. 작동하는 것 같습니다 :

* Filename: sequence.mp4 
* FPS: 59 
... 
... 
... 
17 00:00:567.000000 
18 601/33371 601.000000 
18 00:00:601.000000 
19 634/33371 634.000000 
19 00:00:634.000000 
20 668/33371 668.000000 
20 00:00:668.000000 
21 701/33371 701.000000 
21 00:00:701.000000 
22 734/33371 734.000000 
22 00:00:734.000000 
23 768/33371 768.000000 
23 00:00:768.000000 
24 801/33371 801.000000 
24 00:00:801.000000 
25 835/33371 835.000000 
25 00:00:835.000000 
26 868/33371 868.000000 
26 00:00:868.000000 
27 901/33371 901.000000 
27 00:00:901.000000 
28 935/33371 935.000000 
... 
+0

아, 뭔가 잊고 있다는 것을 알았습니다. 'cout << "OpenCV 버전 :"<< CV_VERSION << endl;은'OpenCV 버전 : 2.0.0'을 제공합니다. – misha

+0

OpenCV 2.1 (최신 버전은 아닙니다)을 사용하고 있습니다. 컴퓨터에서 OpenCV를 업데이트하고 다시 시도하십시오. – karlphillip

+0

2.1을 설치했습니다. 결과는 여전히 동일합니다. (이 기능을 다시 쓰기 위해 마음에 들지는 않습니다. 당신이 말했듯이, 그것은 큰 문제가 아닙니다. 내 질문은 : 헤더의 fps 값을 신뢰할 수 있음을 어떻게 알 수 있습니까? 무엇이 변수 fps 비디오입니까? – misha

관련 문제