2013-02-12 16 views
6

Ho un video engine2.avi che voglio leggere e mostrare con openCV. Ecco il mio codice:Leggere un video con openCV

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <iostream> 

using namespace cv; 

int main(int argc, char** argv) 
{ 
    string filename = "D:\\BMDvideos\\engine2.avi"; 
    VideoCapture capture(filename); 
    Mat frame; 

    if(!capture.isOpened()) 
     throw "Error when reading steam_avi"; 

    namedWindow("w", 1); 
    for(; ;) 
    { 
     capture >> frame; 
     //if(!frame) 
     // break; 
     imshow("w", frame); 
     waitKey(20); // waits to display frame 
    } 
    waitKey(0); 
} 

Questo codice non funziona se il file ha il codec YUV 4:2:2 (UYVY) (ho registrato il video utilizzando Diretto-Show), ma funziona quando uso un video che ho afferrato OpenCV Pentecoste !!

Qualcuno ha un'idea di come potrebbe funzionare?

UPDATE:

Dopo aver letto alcuni link, il che suggerisce che la cattura eccezione risolverà il problema, ho modificato il mio codice. E non ha aiutato, ma qui è il codice modificato:

cv::VideoCapture cap("d:\\BMDvideos\\engine2.avi"); 
cv::Mat frame; 

try 
{ 
    cap >> frame; 
} 
catch(cv::Exception ex) 
{ 
    std::cout << ex.what() << std::endl; 
} 
catch(...) 
{ 
    std::cout << "Unknown exception" << std::endl; 
} 

Il programma si blocca in cap>>frame. Ho letto domande simili ma usano un frame in YUV (4: 2: 0), mentre il mio video ha UYVY (4: 2: 2). Come posso convertirlo in un modello di colore RGB?

UPDATE 2:

Dopo il suggerimento di karlphillip, ho usato OpenCV2.4.3, ma ho ancora ottenuto lo stesso errore usando il codice seguente:

#include <opencv2\core\core.hpp> 
#include <opencv2\highgui\highgui.hpp> 
#include <opencv2\opencv.hpp> 
using namespace cv; 
using namespace std; 

int main(){ 
    cv::Mat frame; 
    cv::VideoCapture cap("d:\\BMDvideos\\B\\Aufnahme.avi"); 
    if(!cap.isOpened()) 
    { 
     cout << "Error can't find the file"<<endl; 
    } 

    while(1){ 
     if(!cap.read(frame)) 
      imshow("",frame); 

     cv::waitKey(33); 
    } 
    return 0; 
} 

risposta

6

Ecco un paio di link che potrebbero aiutare:

Edit:

devo chiarire qualcosa prima: OpenCV è in grado di leggere fotogrammi YUV da un file video perché è la libreria sottostante (FFmpeg/GStreamer) che fa il lavoro. OpenCV supporta anche la conversione tra un tipo specifico di YUV and RGB tramite cvCvtColor() con CV_YCrCb2RGB o CV_RGBYCrCb.

Dopo aver esaminato nuovamente la tua domanda, ho notato che non hai specificato il tipo di errore che si è verificato. È possibile allo dealing con un possiblefailure dall'interfaccia di acquisizione stampando un messaggio sullo schermo anziché throw.

ho testato il file video che avete condiviso e non ho avuto problemi a giocare su una finestra utilizzando il seguente codice:

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

#include <iostream> 

int main(int argc, char* argv[]) 
{ 
    cv::VideoCapture cap(argv[1]); 
    if (!cap.isOpened()) 
    { 
     std::cout << "!!! Failed to open file: " << argv[1] << std::endl; 
     return -1; 
    } 

    cv::Mat frame; 
    for(;;) 
    { 

     if (!cap.read(frame))    
      break; 

     cv::imshow("window", frame); 

     char key = cvWaitKey(10); 
     if (key == 27) // ESC 
      break; 
    } 

    return 0; 
} 

Se, per qualche motivo, l'interfaccia di acquisizione non riesce ad aprire il file si annullerà l'applicazione immediatamente, invece di andare ulteriormente solo per crash al cap.read(frame).

+0

grazie @karlphilip per la risposta. Ma in quei link ci spiegano come convertire un frame che è in YUV 4: 2: 2 in RGB, ho un video quando provo a ottenere un frame da esso per l'intero crash del programma !! – Engine

+0

Carica il video da qualche parte e facci testarlo. – karlphillip

+0

è 1 GB per 10s – Engine

0

Se stai solo cercando di visualizzare il video, ecco il codice che ha funzionato per me, Controlla se ti aiuta in alcun modo.

#include <stdio.h> 
#include <opencv2/opencv.hpp> 
int main(){ 
CvCapture *camera=cvCaptureFromFile("C:\\test.avi"); 
if (camera==NULL) 
    printf("camera is null\n"); 
else 
    printf("camera is not null"); 

cvNamedWindow("img"); 
while (cvWaitKey(10)!=atoi("q")){ 
    double t1=(double)cvGetTickCount(); 
    IplImage *img=cvQueryFrame(camera); 
    /*if(img){ 
     cvSaveImage("C:/opencv.jpg",img); 
    }*/ 
    double t2=(double)cvGetTickCount(); 
    printf("time: %gms fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.))); 
    cvShowImage("img",img); 
} 
cvReleaseCapture(&camera); 
} 

Spero che questo ti aiuti.

+0

questo codice basta leggere un video che era il mio problema, il codec era il problema! ma grazie comunque ! – Engine

+0

Se il problema riguardava il codec e se il problema persiste, assicurati di installare il codec ffmpeg. [Controlla questo link per l'installazione di ffmpeg] (http://www.wikihow.com/Install-FFmpeg-on-Windows). – Mayur

-1

Ho capito che l'oggetto VideoCapture ha bisogno di opencv_ffmpeg310_64.dll. Dopo aver copiato questa dll nella cartella binaria, l'oggetto VideoCapture dovrebbe essere in grado di leggere il file video.