2010-12-04 9 views
13

की रिपोर्ट नहीं करता है मेरे पास 33 सेकंड वीडियो है जिसे मैं ओपनसीवी के साथ संसाधित करने की कोशिश कर रहा हूं। मेरा लक्ष्य यह निर्धारित करना है कि समय में कौन सा उदाहरण (वीडियो की शुरुआत के सापेक्ष) प्रत्येक फ्रेम के अनुरूप है। मैं यह वही दृश्य के वीडियो से फ्रेम की तुलना करने में सक्षम होने के लिए कर रहा हूं जो अलग-अलग फ्रेम दरों पर दर्ज किया गया है।ओपनसीवी सटीक फ्रेम दर/गिनती

क्या काम कर रहा है:

  • एफपीएस सही ढंग से 59.75 के रूप में रिपोर्ट किया गया है। यह ffprobe रिपोर्ट के साथ संगत है, इसलिए मुझे विश्वास है कि यह सही है।

समस्याओं मैं आ रही हैं:

  • CAP_PROP_POS_MSEC रिटर्न गलत मान। वीडियो के अंत तक, यह 557924ms (9 मिनट से अधिक) तक है। 33 के वीडियो के लिए, यह सही नहीं हो सकता है।
  • CAP_PROP_FRAME_COUNT भी गलत है। यह 33371 के रूप में रिपोर्ट किया गया है, जो 59.75 एफपीएस पर 9 मिनट से अधिक फुटेज प्रदान करेगा। उपरोक्त त्रुटि के अनुरूप, लेकिन अभी भी गलत है।
  • CAP_PROP_POS_FRAME इसी तरह गलत है।

वीडियो here (लगभग 10 एमबी) पाया जा सकता है।

क्या गलत हो सकता है पर कोई विचार?

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

आप किस का उपयोग कर रहे हैं: विंडोज/लिनक्स/मैक? – karlphillip

+0

लिनक्स (उबंटू 10.04 एलटीएस) – misha

+1

जो बहुत कुछ बताता है। ओपनसीवी अभी भी लिनक्स के तहत वीडियो फ्लस के समर्थन में सुधार करने के लिए काम कर रहा है, क्षमा करें। – 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() यदि आप कर सकते हैं, और हमेशा जांच वापसी मान ओपनसीवी कॉल:

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); का उपयोग कर वर्तमान एफपीएस की रिपोर्ट भी करता है, इसलिए यह देखने के लिए आपके लिए दिलचस्प हो सकता है। इसे देखें।

संपादित करें:

तुम भी OpenCV का उपयोग कर this thread फ्रेम गिनती के बारे में जांच होनी चाहिए;

वैसे, मैं सिर्फ अपनी Ubuntu पर कुछ पुस्तकालयों अद्यतन और 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 <<" ओपनसीवी संस्करण: "<< CV_VERSION << endl;' ओपनसीवी संस्करण देता है: 2.0.0' – misha

+0

मैं ओपनसीवी 2.1 (जो नवीनतम नहीं है) का उपयोग कर रहा हूं और यह ठीक काम करता है। अपनी मशीन पर ओपनसीवी अपडेट करें और पुनः प्रयास करें। – karlphillip

+0

मैंने 2.1 स्थापित किया। नतीजा अभी भी वही है :(मुझे इस समस्या को फिर से लिखने में कोई फर्क नहीं पड़ता - जैसा आपने कहा था, यह कोई बड़ी बात नहीं है। मेरे प्रश्न हैं: मुझे कैसे पता चलेगा कि मैं हेडर में एफपीएस मूल्य पर भरोसा कर सकता हूं परिवर्तनीय एफपीएस वीडियो के बारे में क्या? – misha