6

我正在尝试从 IP 摄像机实时捕获图像。该流在 VLC 中运行良好,但 OpenCVcvQueryFrame()似乎混乱并破坏了传入的图像,以至于无法识别。

同样,从文件中捕获工作正常,但不是实时流。如果有什么不同,我使用的是 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

4 回答 4

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 中运行了流。我正在使用启用了 fffmpeg 的 OpenCV 2.4.1。据我了解,从 OpenCV 2.0 开始可以使用 ffmpeg 与 OpenCV 的集成。

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

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

于 2012-07-23T08:18:44.617 回答
2

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

于 2012-07-23T16:16:28.633 回答
1

这是我用来从网络摄像头捕获帧的代码片段。它对我有用,希望它也对你有用......

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;
}
于 2012-07-18T18:07:19.460 回答
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 键,它会接收输入并连续显示并退出。 这是CV 2.1 的文档,它具有与 CV 2.3 相同的命令集。我猜这些命令是从 2.4 开始的,虽然我不太确定。希望能帮助到你。:)

于 2012-07-19T04:25:24.723 回答