23

我在 Windows 下使用 openCV 1.1pre1。我有一个网络摄像机,我需要从 openCV 抓取帧。该摄像机可以通过 RTSP 流式传输标准 mpeg4 流或通过 http 传输 mjpeg。我已经看到很多线程都在谈论将 ffmpeg 与 openCV 一起使用,但我无法使其工作。

如何使用 openCV 从 IP 摄像机中抓取帧?

谢谢

安德烈亚

4

6 回答 6

23

我附上了用于抓取帧的 C++ 代码。它需要 OpenCV 2.0 或更高版本。该代码使用 cv::mat 结构,该结构优于旧的 IplImage 结构。

#include "cv.h"
#include "highgui.h"
#include <iostream>

int main(int, char**) {
    cv::VideoCapture vcap;
    cv::Mat image;

    const std::string videoStreamAddress = "rtsp://cam_address:554/live.sdp"; 
    /* it may be an address of an mjpeg stream, 
    e.g. "http://user:pass@cam_address:8081/cgi/mjpg/mjpg.cgi?.mjpg" */

    //open the video stream and make sure it's opened
    if(!vcap.open(videoStreamAddress)) {
        std::cout << "Error opening video stream or file" << std::endl;
        return -1;
    }

    //Create output window for displaying frames. 
    //It's important to create this window outside of the `for` loop
    //Otherwise this window will be created automatically each time you call
    //`imshow(...)`, which is very inefficient. 
    cv::namedWindow("Output Window");

    for(;;) {
        if(!vcap.read(image)) {
            std::cout << "No frame" << std::endl;
            cv::waitKey();
        }
        cv::imshow("Output Window", image);
        if(cv::waitKey(1) >= 0) break;
    }   
}

更新您可以从 H.264 RTSP 流中抓取帧。查找您的相机 API 以获取详细信息以获取 URL 命令。例如,对于 Axis 网络摄像机,URL 地址可能是:

// H.264 stream RTSP address, where 10.10.10.10 is an IP address 
// and 554 is the port number
rtsp://10.10.10.10:554/axis-media/media.amp

// if the camera is password protected
rtsp://username:password@10.10.10.10:554/axis-media/media.amp
于 2012-01-03T21:57:37.787 回答
10
#include <stdio.h>
#include "opencv.hpp"


int main(){

    CvCapture *camera=cvCaptureFromFile("http://username:pass@cam_address/axis-cgi/mjpg/video.cgi?resolution=640x480&req_fps=30&.mjpg");
    if (camera==NULL)
        printf("camera is null\n");
    else
        printf("camera is not null");

    cvNamedWindow("img");
    while (cvWaitKey(10)!=atoi("q")){
        double t1=(double)cvGetTickCount();
        IplImage *img=cvQueryFrame(camera);
        double t2=(double)cvGetTickCount();
        printf("time: %gms  fps: %.2g\n",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
        cvShowImage("img",img);
    }
    cvReleaseCapture(&camera);
}
于 2011-05-20T11:11:54.937 回答
5

OpenCV 可以在 FFMPEG 支持下编译。从./configure --help

--with-ffmpeg     use ffmpeg libraries (see LICENSE) [automatic]

然后,您可以使用cvCreateFileCapture_FFMPEG创建一个 CvCapture,例如相机的 MJPG 流的 URL。

我使用它从 AXIS 相机中抓取帧:

CvCapture *capture = 
    cvCreateFileCapture_FFMPEG("http://axis-cam/mjpg/video.mjpg?resolution=640x480&req_fps=10&.mjpg");
于 2009-06-18T14:28:02.787 回答
3

我只是这样做:

CvCapture *capture = cvCreateFileCapture("rtsp://camera-address");

还要确保这个 dll 在运行时可用,否则 cvCreateFileCapture 将返回 NULL

opencv_ffmpeg200d.dll

相机也需要允许未经身份验证的访问,通常通过其网络界面设置。MJPEG 格式通过 rtsp 工作,但 MPEG4 没有。

hth

于 2010-02-11T11:48:15.187 回答
3

rtsp 协议对我不起作用。mjpeg 第一次尝试。我假设它内置在我的相机中(Dlink DCS 900)。

在这里找到语法:http: //answers.opencv.org/question/133/how-do-i-access-an-ip-camera/

我不需要编译带有 ffmpg 支持的 OpenCV。

于 2012-11-28T22:21:00.973 回答
1

使用 ffmpeglib 连接到流。

这些功能可能很有用。但是看看文档

av_open_input_stream(...);
av_find_stream_info(...);
avcodec_find_decoder(...);
avcodec_open(...);
avcodec_alloc_frame(...);

您需要一些算法来获得完整的框架,可在此处获得

http://www.dranger.com/ffmpeg/tutorial01.html

一旦你得到一个帧,你可以将视频数据(如果需要的话,对于每个平面)复制到一个 IplImage 中,它是一个 OpenCV 图像对象。

您可以使用类似...的东西创建一个 IplImage

IplImage *p_gray_image = cvCreateImage(size, IPL_DEPTH_8U, 1);

拥有 IplImage 后,您可以执行 OpenCV 库中可用的各种图像操作

于 2009-04-03T09:31:07.800 回答