2012-07-03 22 views
6

Estoy tratando de capturar imágenes de una cámara IP en tiempo real. La transmisión funciona perfectamente en VLC, pero el cvQueryFrame() de OpenCV parece desordenar y corromper las imágenes entrantes hasta el punto de no reconocimiento.Problemas de captura de imagen OpenCV/FFMpeg

Una vez más, la captura desde el archivo funciona bien, pero no es una transmisión en vivo. En caso de que haga una diferencia, estoy usando una URL de conexión rtsp; También probé esto con dos modelos diferentes de cámaras (diferentes marcas) y el problema persiste.

Además, el códec (estoy asumiendo) está produciendo varios errores del siguiente tipo: Error at MB: 1746 y concealing 6000 DC, 6000 AC, 6000 MV errors.

¿Qué puedo hacer?

Actualización: El primer error en la secuencia es siempre cannot parallelize deblocking type 1, decoding such frames in sequential order

Actualización 2: bien, parece que OpenCV/FFMPEG tiene un problema con los flujos RTSP/h264. He intentado con la biblioteca Qt Phonon, que tampoco funciona, y proporcioné la biblioteca Live555 una visión general rápida. Esto último parece funcionar, en el sentido de que todos dicen que sí, y el ejemplo de la aplicación (OpenRTSP) de hecho reproduce bien mi secuencia. Sin embargo, para ser honesto, entender el código de Live555 parece un asunto largo que no me puedo permitir en este momento. Salvo cualquier otra alternativa, supongo que tendré que seguir esa ruta.

¿Hay alguna otra solución que se le ocurra?

Actualización 3: Tengo la prueba cliente RTSP desde el código de Live555 para trabajar, así que sé cómo extraer h264 información de la trama de una corriente, pero ahora tengo que volver a combinar esa información trama en tramas que se pueden visualizar reales, los cuales no parece algo sencillo! ¿Alguien familiarizado con Live555 sabe cómo hacer esto? Gracias.

+0

¿Qué versión de OpenCV estás usando? ¿en Linux o en Windows? – Mohammad

+0

OpenCV 2.3.1 en Win 7. –

+0

'cvQueryFrame()' puede devolver una imagen NULL. Asegúrate de probar esto antes de hacer algo con él. – karlphillip

Respuesta

2

Parece que necesita una capa de software adicional para capturar los paquetes de flujo y reconstruir los marcos localmente, y luego alimentarlos para abrirCV. Puedes lograr esto fácilmente con libVLC. Esto también evitaría los problemas del códec ya que puede analizar casi todos los códecs con libVLC y luego alimentar los marcos sin procesar a openCV.

+0

Eso es todo. libVLC funcionó bien. ¡Muchas gracias! –

+2

Estoy trabajando en un problema similar. ¿Podría publicar el código para alimentar marcos sin procesar de libVLC a openCV? – Sergiy

1

Aquí hay un fragmento de código, que utilicé para capturar fotogramas de WebCam. Se trabajó para mí, Espero que funcione para usted también ...

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

Como tal, el problema no está en OpenCV, sino en las bibliotecas FFMpeg subyacentes que utiliza. Esto no funciona. –

0

Para OpenCV 2.3.1 He escrito el código y funciona con normalidad, es decir, consigo las imágenes de la cámara de alimentación.

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; 

Como puede ver, toma la entrada y la muestra continuamente y sale si presiona ESC en su teclado. Here's la documentación para CV 2.1 que tiene el mismo conjunto de comandos que CV 2.3. Los comandos cambiaron de 2.4, supongo, aunque no estoy muy seguro al respecto. Espero que ayude :) :)

+0

Bueno, siempre he logrado obtener las imágenes de las cámaras, incluso en este caso, aunque en este caso las imágenes están dañadas. Esta es la versión de C++ de obtener una captura de video en OpenCV, pero el resultado es el mismo porque envuelve la misma funcionalidad de FFMpeg. –

+0

@ KristianD'Amato Esto es todo lo que tengo. Las imágenes son corruptas? Eso no sucede. –

+0

Gracias Prakhar; sí, las imágenes se ven distorsionadas y mal. –

3

No sé si ayuda (ya que no soy un experimentado desarrollador de C++), pero recientemente logré obtener una transmisión de un IP Camera. Aquí es una prueba rápida:

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

Antes de dirigirse a C++ he configurar la cámara para exportar a H264 VGA (ya que no se ha habilitado de forma predeterminada en la leva que estoy trabajando) y me aseguré Tengo la secuencia ejecutándose en VLC. Estoy usando OpenCV 2.4.1 con fffmpeg habilitado. Hasta donde entiendo, la integración de ffmpeg con OpenCV está disponible desde OpenCV 2.0 en adelante.

Me topé con algunos problemas cuando tuve que integrar fusionar el código cv con otro código C++ ya que tengo las dependencias OpenCV y ffmpeg + creadas para 64bit arch. y el otro código confiaba en muchas bibliotecas de 32 bits. La clase VideoCapture es parte de la lib de highgui y principalmente de la que debe preocuparse. Si no se compila con el soporte de ffmpeg, recibirá un error o una advertencia ya que VideoCapture no podrá transcodificar el contenido.

No estoy seguro de que es la mejor opción, pero se podría tratar de transmitir/transcodificar la corriente de VLC (marcando Transmisión/verano en la pestaña Open Source/Red)

Cuestiones relacionadas