Question

I'm using openCV 1.1pre1 under Windows. I have a network camera and I need to grab frames from openCV. That camera can stream a standard mpeg4 stream over RTSP or mjpeg over http. I've seen many threads talking about using ffmpeg with openCV but I cannot make it work.

How I can grab frames from an IP camera with openCV?

Thanks

Andrea

Was it helpful?

Solution

rtsp protocol did not work for me. mjpeg worked first try. I assume it is built into my camera (Dlink DCS 900).

Syntax found here: http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/

I did not need to compile OpenCV with ffmpg support.

OTHER TIPS

I enclosed C++ code for grabbing frames. It requires OpenCV version 2.0 or higher. The code uses cv::mat structure which is preferred to old IplImage structure.

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

Update You can grab frames from H.264 RTSP streams. Look up your camera API for details to get the URL command. For example, for an Axis network camera the URL address might be:

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

OpenCV can be compiled with FFMPEG support. From ./configure --help:

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

You can then use cvCreateFileCapture_FFMPEG to create a CvCapture with e.g. the URL of the camera's MJPG stream.

I use this to grab frames from an AXIS camera:

CvCapture *capture = 
    cvCreateFileCapture_FFMPEG("http://axis-cam/mjpg/video.mjpg?resolution=640x480&req_fps=10&.mjpg");

I just do it like this:

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

Also make sure this dll is available at runtime else cvCreateFileCapture will return NULL

opencv_ffmpeg200d.dll

The camera needs to allow unauthenticated access too, usually set via its web interface. MJPEG format worked via rtsp but MPEG4 didn't.

hth

Si

Use ffmpeglib to connect to the stream.

These functions may be useful. But take a look in the docs

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

You would need a little algo to get a complete frame, which is available here

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

Once you get a frame you could copy the video data (for each plane if needed) into a IplImage which is an OpenCV image object.

You can create an IplImage using something like...

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

Once you have an IplImage, you could perform all sorts of image operations available in the OpenCV lib

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top