MJPEG потоковое и декодирование
Я хочу получать изображения JPEG с IP-камеры (через RTSP). Для этого я пытался cvCreateFileCapture_FFMPEG
в OpenCV. Но ffmpeg, похоже, имеет некоторую проблему с форматом потоковой передачи MJPEG (так как он автоматически пытается определить информацию о потоковой передаче), и я получаю следующую ошибку
mjpeg: unsupported coding type
Затем я решил использовать live555 для потоковой передачи. До сих пор я могу успешно устанавливать потоковые и захватывать (не декодированные) изображения через openRTSP.
Вопрос в том, как я могу сделать это в моем приложении, например, в OpenCV. Как я могу использовать openRTSP в OpenCV, чтобы получать изображения и сохранять их в формате JPEG?
Я слышал, что данные из openRTSP можно отправить в буфер (или именованный канал), а затем прочитать в OpenCV IplImage
, Но я не знаю, как это сделать.
Я буду очень признателен за любую помощь / предложение об этой проблеме. Мне нужны ответы на один из следующих вопросов:
- Как я могу отключить автоматическое определение информации о потоке в ffmpeg и указать свой собственный формат (mjpeg), или
- Как я могу использовать openRTSP в OpenCV?
С Уважением,
1 ответ
Это 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
Вариант 2. Использование 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 смотрите
Для простого примера посмотрите на мой другой пост на rtsp по созданию медиа-конвейера gstreamer C API (Это то же самое, что строка gst-launch, но скорее реализовано как C API)
Игра в RTSP с помощью python-gstreamer
Чтобы сохранить поток 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
ОБНОВИТЬ:
Вариант 3: Использование 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