25

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

Grifo
  • 999
  • 4
  • 12
  • 16

6 Answers6

23

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
Alexey
  • 5,898
  • 9
  • 44
  • 81
  • Do you know if this works with MJPEG only or also with H.264 RTSP/UDP streaming? – Matthias Jun 18 '13 at 13:38
  • @Matthias It works for H.264 RTSP streaming too. I have OpenCV version 2.4.4 and can grab frames from a camera streaming with H.264. – Alexey Jun 18 '13 at 13:59
  • Thanks for your fast answer. – Matthias Jun 18 '13 at 14:19
  • I had to add some code `counter++;` and `if (counter % 10 != 0) continue;` within the for-loop so that only every 10th frame is displayed. This is because the frame are received so fast, that imshow(...) will display destroyed/warped images. If you supply only every 10th frame to imshow(...), the result will be okay. In case the IP camera delivers 1080p on 30fps, I had to show only every 30th or 40th frame. – Matthias Jun 25 '13 at 10:17
  • Is there another way to specify user name and password? I set a password on the camera and if I use VLC it works fine. If I use your code above (OpenCV) it says unauthorized. – Matthias Jun 25 '13 at 10:41
  • As for the authentication, it seems that `rtsp://username:password@...` is the only OpenCV supported method to authenticate with cameras. If you find another way, let me know! – Alexey Jun 27 '13 at 19:43
  • Thanks for sharing the answer. I can access RTSP stream from the IP camera. It stops receiving frames after certain number of frames, like 134, 160, 240, 658, 1040 etc. Most frequent one being 134. It crashes with the following error: No frame OpenCV Error: Assertion failed (size.width>0 && size.height>0) in unknown functi on, file C:\Users\Abdullah\Downloads\opencv-.4.6\modules\highgui\src\window.cpp, line 261, Can anyone help me solve this problem? – Tariq Jul 08 '14 at 12:06
  • This method also worked for rtmp protocol. like rtmp://192.168.173.1:1935/live/test.flv – GPrathap Aug 27 '15 at 11:45
  • 1
    Great man... thank you so much... your code is the best way and i wast 4 days on this problem and your solution make me so much happy now. – Rashed DIP Jun 05 '18 at 17:42
  • @Alexey What about the CPU usage? It clocked +100% for me. – Sleeba Paul Mar 28 '19 at 05:51
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);
}
RvdK
  • 19,580
  • 4
  • 64
  • 107
lolong
  • 101
  • 1
  • 2
5

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");
f3lix
  • 29,500
  • 10
  • 66
  • 86
3

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.

john k
  • 6,268
  • 4
  • 55
  • 59
3

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

sipickles
  • 1,637
  • 1
  • 19
  • 30
  • The library version says that he is using openCV 2.0 - that's the `200` part in `opencv_ffmpeg200d.dll` – jamuraa Mar 17 '10 at 20:41
  • This is in my opinion the correct answer. I am using windows and I had to copy `opencv_ffmpeg300.dll` to my project folder. To open the stream I am using `VideoCapture cap("rtsp://abc:123@192.168.178.101/live0.264");` – Anonymous Dec 04 '15 at 09:15
1

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

Indy9000
  • 8,651
  • 2
  • 32
  • 37
  • I've seen in many threads that ffmpeg is already included and used inside openCV, is this right? Maybe I need to recompile openCV with ffgmpeg support? In this case how I can do this under windows? Thanks – Grifo Apr 03 '09 at 12:36
  • I'm not aware of this. However, ffmpeg is an application where as ffmpeglib is a library. If you are new to these please look at the dranger.com tutorials. – Indy9000 Apr 03 '09 at 13:19