gpt4 book ai didi

c++ - MJPEG 流和解码

转载 作者:IT老高 更新时间:2023-10-28 22:20:31 24 4
gpt4 key购买 nike

我想从 IP 摄像机(通过 RTSP)接收 JPEG 图像。为此,我在 OpenCV 中尝试了 cvCreateFileCapture_FFMPEG。但是ffmpeg似乎对流媒体的MJPEG格式有一些问题(因为它会自动尝试检测流媒体信息),我最终得到以下错误

mjpeg: unsupported coding type

然后,我决定使用 live555 进行流式传输。到目前为止,我可以通过 openRTSP 成功建立流式传输和捕获(非解码)图像。

问题是如何在我的应用程序中执行此操作,例如在 OpenCV 中。如何在 OpenCV 中使用 openRTSP 获取图像并将其保存为 JPEG 格式?

我听说来自 openRTSP 的数据可以发送到缓冲区(或命名管道),然后在 OpenCV 的 IplImage 中读取。但我不知道该怎么做。

我将非常感谢有关此问题的任何帮助/建议。我需要以下任一问题的答案:

  1. 如何禁用ffmpeg的自动流信息检测并指定我自己的格式(mjpeg),或者
  2. 如何在 OpenCV 中使用 openRTSP?

问候,

最佳答案

这是 Axis IP 摄像机吗?无论哪种方式,大多数提供 MPEG4 RTSP 流的 IP 摄像机都可以使用 OpenCV 使用 cvCreateFileCapture_FFMPEG 进行解码。但是,ffmpeg 解码器的 MJPEG 编解码器有一个众所周知的未解决问题。我相信您会收到类似于

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

选项1:使用opencv、libcurl和libjpeg

要在 opencv 中查看 mjpeg 流,请查看以下实现

http://www.eecs.ucf.edu/~rpatrick/code/onelinksys.c或者 http://cse.unl.edu/~rpatrick/code/onelinksys.c

选项 2:使用 gstreamer(无 opencv)

如果您的目标只是查看或保存 jpeg 图像,我建议您查看 gstreamer

查看 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)

Playing RTSP with 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、命名管道和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 步。准备使用 gstreamer 将 MJPEG 转换为 MPEG4(输入帧的速率至关重要)

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

关于c++ - MJPEG 流和解码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6022423/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com