简体   繁体   English

OpenCV / FFMpeg图像捕获问题

[英]OpenCV/FFMpeg image capture problems

I'm trying to capture images from an IP camera in real time. 我正在尝试从IP摄像头实时捕捉图像。 The stream works perfectly well in VLC, but OpenCV's cvQueryFrame() seems to jumble and corrupt the incoming images to the point of no recognition. 该流在VLC中运行得非常好,但是OpenCV的cvQueryFrame()似乎混杂并破坏了传入的图像到了无法识别的程度。

Again, capturing from file works fine, but not a live stream. 同样,从文件捕获工作正常,但不是实时流。 In case it makes a difference, I'm using an rtsp connection URL; 如果它有所作为,我正在使用rtsp连接URL; I've also tried this with two different camera models (different brands), and the problem remains. 我也尝试过两种不同的相机型号(不同的品牌),问题仍然存在。

Besides, the (I'm assuming) codec is outputting several errors of the following kind: Error at MB: 1746 and concealing 6000 DC, 6000 AC, 6000 MV errors . 此外,(我假设)编解码器输出以下几种错误: Error at MB: 1746concealing 6000 DC, 6000 AC, 6000 MV errors

What can I do? 我能做什么?

Update: The first error in the sequence is always cannot parallelize deblocking type 1, decoding such frames in sequential order 更新:序列中的第一个错误始终cannot parallelize deblocking type 1, decoding such frames in sequential order

Update 2: Alright, it seems that OpenCV/FFMPEG has an issue with rtsp/h264 streams. 更新2:好吧,似乎OpenCV / FFMPEG与rtsp / h264流有问题。 I've tried the Qt Phonon library, which also doesn't work, and I've given the Live555 library a quick overview. 我已经尝试过Qt Phonon库,它也不起作用,我已经给Live555库快速概述了。 This last appears to work, in the sense that everyone says it does, and the application example (OpenRTSP) in fact plays my stream well. 这个最后似乎工作,在每个人都说它的意义上,应用程序示例(OpenRTSP)实际上很好地播放我的流。 However, to be quite honest, getting to grips with the Live555 code seems like a lengthy affair which I can hardly afford right now. 但是,说实话,掌握Live555代码似乎是一件很长的事情,我现在几乎买不起。 Barring any other alternative, I guess I'll have to go that route. 除非有其他选择,我想我必须走那条路。

Is there any other solution that comes to mind? 是否还有其他解决方案?

Update 3: I got the test RTSP client from the Live555 code to work, so I know how to extract h264 frame information from a stream, but now I need to recombine that frame information into actual displayable frames, which doesn't seem like something straightforward! 更新3:我从Live555代码中获得了测试RTSP客户端,所以我知道如何从流中提取h264帧信息,但现在我需要将帧信息重新组合成实际的可显示帧,这似乎不是什么东西直截了当! Anyone familiar with Live555 know how to do this? 熟悉Live555的人都知道如何做到这一点? Thanks. 谢谢。

I don't know if it helps (since I'm not an experienced c++ dev), but I've recently managed to get a stream from an IP Camera . 我不知道它是否有帮助(因为我不是一个经验丰富的c ++开发者),但我最近设法从IP摄像头获得了一个流。 Here's a quick test: 这是一个快速测试:

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

Before heading to c++ I've setup the camera to export to H264 VGA (as it wasn't enabled by default on the cam I'm working with) and made sure I've got the stream running in VLC. 在前往c ++之前,我已将相机设置为导出到H264 VGA(因为我正在使用的凸轮上没有默认启用)并确保我在VLC中运行了流。 I'm using OpenCV 2.4.1 with fffmpeg enabled. 我正在使用OpenCV 2.4.1并启用了fffmpeg。 As far I understand the ffmpeg integration with OpenCV is available from OpenCV 2.0 upwards. 据我所知,从OpenCV 2.0向上可以获得与OpenCV的ffmpeg集成。

I did run into a few issues when I had to integrate merge the cv code with other c++ code as I have OpenCV and ffmpeg + dependencies built for 64bit arch. 当我必须将cv代码与其他c ++代码合并时,我确实遇到了一些问题,因为我有为64位arch构建的OpenCV和ffmpeg +依赖项。 and the other code was relying on many 32bit libraries. 而其他代码依赖于许多32位库。 The VideoCapture class is part of the highgui lib and that mainly the one you need to worry about. VideoCapture类是highgui lib的一部分,主要是您需要担心的类。 If it's not compiled with ffmpeg support you will get an error or a warning as VideoCapture won't be able to transcode the content. 如果没有使用ffmpeg支持编译,您将收到错误或警告,因为VideoCapture将无法对内容进行转码。

Not sure it it's the best option, but you could try to stream/transcode the stream from VLC (by ticking Streaming/Saving in the Open Source/Network tab) 不确定它是最好的选择,但您可以尝试从VLC流式传输/转码流(通过在开源/网络选项卡中勾选流式传输/保存)

It seems you need an extra software layer to capture the stream packets and reconstruct the frames locally, and then feed them to openCV. 您似乎需要一个额外的软件层来捕获流数据包并在本地重建帧,然后将它们提供给openCV。 You can easily achieve this with libVLC. 您可以使用libVLC轻松实现此目的。 This would also avoid codec problems since you can parse almost all codecs with libVLC and then feed raw frames to openCV. 这也可以避免编解码器问题,因为您可以使用libVLC解析几乎所有编解码器,然后将原始帧提供给openCV。

Here is a code snippet, that I used to capture frames from WebCam. 这是一段代码片段,我用它来捕获WebCam中的帧。 It worked for me, Hope it works for you as well... 它对我有用,希望它也适合你...

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

For OpenCV 2.3.1 I have written this code and it works normally, that is, I get the images from the camera feed. 对于OpenCV 2.3.1,我已经编写了这段代码并且它正常工作,也就是说,我从相机源获取图像。

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;

As you can see, it takes the input and displays it continuously and exits if you press ESC on your keyboard. 如您所见,它会接受输入并连续显示它,如果您按下键盘上的ESC,它将退出。 Here's the documentation for CV 2.1 which has the same set of commands as CV 2.3. 这是 CV 2.1的文档,它与CV 2.3具有相同的命令集。 The commands changed from 2.4 I guess, although I am not too sure about it. 命令从2.4变为我猜,虽然我对它不太确定。 Hope it helps.:) 希望能帮助到你。:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM