2012-07-03 19 views
6

Sto provando a catturare immagini da una telecamera IP in tempo reale. Lo stream funziona perfettamente in VLC, ma OpenCV cvQueryFrame() sembra intaccare e corrompere le immagini in arrivo fino al punto di non riconoscimento.Problemi di acquisizione di immagini OpenCV/FFMpeg

Ancora una volta, l'acquisizione da file funziona correttamente, ma non in diretta. Nel caso in cui faccia la differenza, sto usando un URL di connessione rtsp; Ho anche provato questo con due diversi modelli di fotocamera (marche diverse), e il problema rimane.

Inoltre, il codec (sto assumendo) sta emettendo diversi errori del tipo seguente: Error at MB: 1746 e concealing 6000 DC, 6000 AC, 6000 MV errors.

Cosa posso fare?

Update: Il primo errore nella sequenza è sempre cannot parallelize deblocking type 1, decoding such frames in sequential order

Aggiornamento 2: Va bene, sembra che OpenCV/FFMPEG ha un problema con i flussi RTSP/H264. Ho provato la libreria Qt Phonon, che inoltre non funziona, e ho dato alla libreria Live555 una rapida panoramica. Quest'ultimo sembra funzionare, nel senso che tutti dicono che lo fa, e l'esempio di applicazione (OpenRTSP) in effetti riproduce bene il mio stream. Tuttavia, per essere onesti, fare i conti con il codice Live555 sembra una questione lunga che difficilmente posso permettermi in questo momento. Salvo altre alternative, credo che dovrò seguire questa strada.

C'è qualche altra soluzione che viene in mente?

Update 3: ho preso il test RTSP client dal codice LIVE555 di lavorare, quindi so come estrarre H264 informazioni fotogramma di un corso d'acqua, ma ora ho bisogno di ricombinare le informazioni telaio in fotogrammi effettivi visualizzabili, che non sembra qualcosa di semplice! Chiunque abbia familiarità con Live555 sa come farlo? Grazie.

+0

Quale versione di OpenCV stai usando? in esso su Linux o Windows? – Mohammad

+0

OpenCV 2.3.1 su Win 7. –

+0

'cvQueryFrame()' potrebbe restituire un'immagine NULL. Assicurati di testare questo prima di fare qualcosa con esso. – karlphillip

risposta

2

Sembra è necessario uno strato software aggiuntivo per acquisire i pacchetti di streaming e ricostruire i frame localmente, quindi inviarli a openCV. Puoi facilmente ottenerlo con libVLC. Ciò eviterebbe anche i problemi di codec poiché è possibile analizzare quasi tutti i codec con libVLC e quindi alimentare i raw frame in openCV.

+0

Ecco fatto. libVLC ha funzionato bene. Grazie molto! –

+2

Sto lavorando su un problema simile. Potresti per favore postare il codice per l'alimentazione di frame grezzi da libVLC a openCV? – Sergiy

1

Ecco uno snippet di codice che ho utilizzato per acquisire frame da WebCam. Ha funzionato per me, spero che funziona per voi pure ...

int main(int argc, char* argv[]) 
{ 
    CvCapture *capture = NULL; 
    IplImage* frame=NULL; 
    int key =0; 
    capture = cvCaptureFromCAM(0); 

    if (!capture) { 
     printf("Cannot initailize webcam"); 
     return 1; 
    } 

    cvNamedWindow("result",CV_WINDOW_AUTOSIZE); 

    while(key != 'q') 
    { 
     frame=cvQueryFrame(capture); 

     if(!frame) break; 

     cvShowImage("result",frame); 
     key=cvWaitKey(10); 
     frame=NULL; 
    } 
    cvDestroyWindow("result"); 
    cvReleaseCapture(&capture); 
    return 0; 
} 
+0

Come tale, il problema non è in OpenCV, ma nelle librerie FFMpeg sottostanti che utilizza. Questo non funziona. –

0

Per OpenCV 2.3.1 Ho scritto questo codice e funziona normalmente, cioè, ottengo le immagini dal feed fotocamera.

VideoCapture cap(0); 
if(!cap.isOpened()) 
{ 
    cout<<"Camera is not connected"<<endl; 
    getchar(); 
} 
namedWindow("Camera Feed",1); 
for(;;) 
{ 
    Mat frame; 
    cap >> frame; 
    imshow("Camera Feed", frame); 
    if(!frame.empty()) 
     detectAndDisplay(frame); 
    else 
     cout<<"No frame as input"<<endl; 
    int c=waitKey(10); 
    if(c==27) 
     break; 
} 
return 0; 

Come si può vedere, prende l'input e lo visualizza continuamente ed esce se si preme ESC sulla tastiera. Here's la documentazione per CV 2.1 che ha lo stesso set di comandi del CV 2.3. I comandi sono cambiati da 2.4, suppongo, anche se non ne sono troppo sicuro. Spero che sia d'aiuto :)

+0

Bene, sono sempre riuscito a ottenere le immagini dalle telecamere, anche in questo caso, anche se in questo caso le immagini sono danneggiate. Questa è la versione C++ di acquisizione di un video in OpenCV, ma il risultato è lo stesso perché avvolge la stessa funzionalità FFMpeg. –

+0

@ KristianD'Amato Questo è tutto ciò che ho. Le immagini sono corrotte? Questo non succede –

+0

Grazie Prakhar; sì le immagini sembrano distorte e sbagliate. –

3

Non so se sia d'aiuto (dal momento che non sono un esperto C++ dev), ma di recente sono riuscito a ottenere un flusso da uno IP Camera. Ecco un test rapido:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <iostream> 
#include <stdio.h> 

using namespace cv; 
using namespace std; 

int main(int, char**) 
{ 
    VideoCapture ipCam; 
    Mat frame; 
    const string LOCATION = "rtsp://192.168.0.200:554/rtsph264vga"; 

    if(!ipCam.open(LOCATION)) { 
     cout << "Error opening video stream or file" << endl; 
     return -1; 
    } 

    for(;;) { 
     if(!ipCam.read(frame)) { 
      cout << "No frame" << endl; 
      waitKey(); 
     } 
     imshow("cam", frame); 
     if(waitKey(1) >= 0) break; 
    } 

    return 0; 
} 

Prima di dirigersi verso C++ Ho installato la telecamera di esportare in H264 VGA (in quanto non è stato abilitato di default sulla camma sto lavorando con) e fatto in modo che 'ho il flusso in esecuzione in VLC. Sto usando OpenCV 2.4.1 con fffmpeg abilitato. Per quanto ho capito, l'integrazione di ffmpeg con OpenCV è disponibile da OpenCV 2.0 verso l'alto.

Mi sono imbattuto in alcuni problemi quando ho dovuto integrare unire il codice cv con altro codice C++ in quanto ho le dipendenze OpenCV e ffmpeg + create per l'arco a 64 bit. e l'altro codice faceva affidamento su molte librerie a 32 bit. La classe VideoCapture fa parte della libreria highgui e principalmente quella di cui ti devi preoccupare. Se non è compilato con il supporto ffmpeg, si otterrà un errore o un avvertimento poiché VideoCapture non sarà in grado di transcodificare il contenuto.

Non sono sicuro che è la scelta migliore, ma si potrebbe provare per lo streaming/transcodifica del flusso da VLC (barrando Streaming/Salvataggio nella scheda Open Source/Rete)