OpenCV / FFMpeg图像捕获问题

时间:2012-07-03 08:41:24

标签: c++ video opencv codec live555

我正在尝试从IP摄像头实时捕捉图像。该流在VLC中运行得非常好,但OpenCV的cvQueryFrame()似乎混杂并破坏了传入的图像,使其无法识别。

同样,从文件捕获工作正常,但不是实时流。如果它有所作为,我正在使用rtsp连接URL;我也尝试过两种不同的相机型号(不同的品牌),问题仍然存在。

此外,(我假设)编解码器输出以下几种错误: Error at MB: 1746concealing 6000 DC, 6000 AC, 6000 MV errors

我该怎么办?

更新:序列中的第一个错误始终为cannot parallelize deblocking type 1, decoding such frames in sequential order

更新2:好吧,似乎OpenCV / FFMPEG与rtsp / h264流有问题。我已经尝试了 Qt Phonon 库,这也不起作用,我已经快速概述了 Live555 库。这个最后似乎工作,在每个人都说它的意义上,应用程序示例(OpenRTSP)实际上很好地播放我的流。但是,说实话,掌握Live555代码似乎是一件很长的事情,我现在几乎买不起。除非有其他选择,我想我必须走那条路。

是否还有其他解决方案?

更新3:我从Live555代码中获得了测试RTSP客户端,因此我知道如何从流中提取h264帧信息,但现在我需要将该帧信息重新组合到实际中可显示的框架,看起来不是直截了当的!熟悉Live555的人都知道如何做到这一点?感谢。

4 个答案:

答案 0 :(得分:3)

我不知道它是否有帮助(因为我不是一位经验丰富的c ++开发者),但我最近设法从IP Camera获得了一个流。 这是一个快速测试:

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

在前往c ++之前,我已将相机设置为输出到H264 VGA(因为我正在使用的凸轮上没有默认启用)并确保我在VLC中运行了流。 我正在使用OpenCV 2.4.1并启用了fffmpeg。据我所知,从OpenCV 2.0向上可以获得与OpenCV的ffmpeg集成。

当我必须将cv代码与其他c ++代码合并时,我遇到了一些问题,因为我有为64位arch构建的OpenCV和ffmpeg +依赖项。而其他代码依赖于许多32位库。 VideoCapture类是highgui lib的一部分,主要是您需要担心的类。如果没有使用ffmpeg支持编译,您将收到错误或警告,因为VideoCapture将无法对内容进行转码。

不确定它是最佳选择,但您可以尝试从VLC流式传输/转码流(通过在开源/网络选项卡中勾选流式传输/保存)

答案 1 :(得分:2)

您似乎需要一个额外的软件层来捕获流数据包并在本地重建帧,然后将它们提供给openCV。您可以使用libVLC轻松实现此目的。这也可以避免编解码器问题,因为您可以使用libVLC解析几乎所有编解码器,然后将原始帧提供给openCV。

答案 2 :(得分:1)

这是一段代码片段,我用它来捕获WebCam中的帧。它对我有用,希望它对你也有用......

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

答案 3 :(得分:0)

对于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;

正如您所看到的,它会接受输入并连续显示它,如果您按下键盘上的ESC,它将退出。 Here's CV 2.1的文档,它与CV 2.3具有相同的命令集。命令从2.4变为我猜,虽然我对它不太确定。希望它有所帮助。:)