MJPEG потоковое и декодирование - PullRequest
16 голосов
/ 16 мая 2011

Я хочу получать изображения в формате JPEG с IP-камеры (через RTSP).Для этого я попытался cvCreateFileCapture_FFMPEG в OpenCV.Но ffmpeg, похоже, имеет некоторые проблемы с форматом потоковой передачи MJPEG (так как он автоматически пытается определить информацию о потоковой передаче), и я в итоге получаю следующую ошибку

mjpeg: unsupported coding type

Я тогда решил использовать live555для потоковой передачи.До сих пор я могу успешно устанавливать потоковые и захватывать (не декодированные) изображения через openRTSP.

Вопрос в том, как я могу сделать это в моем приложении, например, в OpenCV.Как я могу использовать openRTSP в OpenCV, чтобы получать изображения и сохранять их в формате JPEG?

Я слышал, что данные из openRTSP можно отправить в буфер (или именованный канал), а затем прочитать в OpenCV IplImage.Но я не знаю, как это сделать.

Я буду очень признателен за любую помощь / предложение по этой проблеме.Мне нужны ответы на один из следующих вопросов:

  1. Как отключить автоматическое обнаружение информации о потоке в ffmpeg и указать свой собственный формат (mjpeg), или
  2. Как использовать openRTSP вOpenCV?

С уважением,

1 Ответ

18 голосов
/ 16 августа 2011

Это IP-камера Axis?В любом случае, большинство IP-камер, которые обеспечивают MPEG4 RTSP-поток, могут быть декодированы с использованием OpenCV с использованием cvCreateFileCapture_FFMPEG .Однако кодек MJPEG декодера ffmpeg имеет широко известные нерешенные проблемы.Я уверен, что вы получили бы ошибку , аналогичную

[ingenient @ 0x97d20c0]Could not find codec parameters (Video: mjpeg)

Опция 1: Использование opencv, libcurl и libjpeg

Для просмотра потока mjpegв opencv взгляните на следующую реализацию

http://www.eecs.ucf.edu/~rpatrick/code/onelinksys.c или http://cse.unl.edu/~rpatrick/code/onelinksys.c

Option2: использование gstreamer (без opencv)

Я бы порекомендовал взглянуть на gstreamer, если ваша цель - просто просмотреть или сохранить изображения в формате JPEG

В просмотреть Поток MJPEG можно выполнить строку конвейера мультимедиа следующим образом

gst-launch -v souphttpsrc location="http://[ip]:[port]/[dir]/xxx.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec ! ffmpegcolorspace ! autovideosink

Для RTSP

gst-launch -v rtspsrc location="rtsp://[user]:[pass]@[ip]:[port]/[dir]/xxx.amp" debug=1 ! rtpmp4vdepay ! mpeg4videoparse ! ffdec_mpeg4 ! ffmpegcolorspace! autovideosink

Для работы с C API смотрите

http://wiki.maemo.org/Documentation/Maemo_5_Developer_Guide/Using_Multimedia_Components/Camera_API_Usage

Для простого примера посмотрите на мой другой пост на rtsp по созданию gstreamer CМедиа-конвейер API (Это то же самое, что и строка gst-launch, но скорее реализовано как C API)

Воспроизведение RTSP с python-gstreamer

To save *Поток 1049 * MJPEG в виде нескольких изображений конвейера (Давайте поместим вертикальный переворот BIN и подключим PADS к предыдущему и следующему BINS , чтобы сделать его более интересным)

gst-launch souphttpsrc location="http://[ip]:[port]/[dir]/xxx.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec !  videoflip method=vertical-flip ! jpegenc !  multifilesink location=image-out-%05d.jpg

Также, возможно, стоит взглянуть на gst-opencv

ОБНОВЛЕНИЕ:

Option3: использование gstreamer, Named Pipe и opencv

В Linux можно получить поток mjpeg и преобразовать его в mpeg4и скормить его в именованную трубу.Затем прочитайте данные из именованного канала в opencv

Шаг 1. Создать именованный канал

mkfifo stream_fifo

Шаг 2. Создайте opencvvideo_test.c

// compile with gcc -ggdb `pkg-config --cflags --libs opencv` opencvvideo_test.c -o opencvvideo_test
#include <stdio.h>
#include "highgui.h"
#include "cv.h"


int main( int argc, char** argv){

IplImage  *frame;
    int       key;

    /* supply the AVI file to play */
    assert( argc == 2 );

    /* load the AVI file */
    CvCapture *capture = cvCreateFileCapture(argv[1]) ;//cvCaptureFromAVI( argv[1] );

    /* always check */
    if( !capture ) return 1;    

    /* get fps, needed to set the delay */
    int fps = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FPS );

    int frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
    int frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);

    /* display video */
    cvNamedWindow( "video", CV_WINDOW_AUTOSIZE );

    while( key != 'q' ) {

    double t1=(double)cvGetTickCount();
    /* get a frame */
    frame = cvQueryFrame( capture );
    double t2=(double)cvGetTickCount();
    printf("time: %gms  fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));

    /* always check */
    if( !frame ) break;

    /* display frame */
    cvShowImage( "video", frame );

    /* quit if user press 'q' */
    key = cvWaitKey( 1000 / fps );
    }

    /* free memory */
    cvReleaseCapture( &capture );
    cvDestroyWindow( "video" );

    return 0;
}

Шаг 3.Подготовка к преобразованию из MJPEG в MPEG4 с использованием gstreamer (критическая скорость входящих кадров)

gst-launch -v souphttpsrc location="http://<ip>/cgi_bin/<mjpeg>.cgi" do-timestamp=true is_live=true ! multipartdemux ! jpegdec ! queue ! videoscale ! 'video/x-raw-yuv, width=640, height=480'! queue ! videorate ! 'video/x-raw-yuv,framerate=30/1' ! queue ! ffmpegcolorspace ! 'video/x-raw-yuv,format=(fourcc)I420' ! ffenc_mpeg4 ! queue ! filesink location=stream_fifo

Шаг 4. Отображение потока в OpenCV

  ./opencvvideo_test stream_fifo
...