c ++ - OpenCV med netværkskameraer

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg bruger openCV 1.1pre1 under Windows.
Jeg har et netværkskamera, og jeg skal gribe rammer fra openCV. Det kamera kan streame en standard mpeg4 stream over RTSP eller mjpeg over http.
Jeg har set mange tråde, der taler om at bruge ffmpeg med openCV, men jeg kan ikke få det til at fungere.


Hvordan kan jeg få fat i rammer fra et IP-kamera med openCV?


Tak


Andrea

Bedste reference


rtsp protokol fungerede ikke for mig.
mjpeg arbejdede første forsøg. Jeg antager, at den er indbygget i mit kamera (Dlink DCS 900).


Syntaks fundet her:
http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/[11]


Jeg behøvede ikke at kompilere OpenCV med ffmpg support.

Andre referencer 1


Jeg vedhæftede C + + -kode til gribende rammer. Det kræver OpenCV version 2.0 eller højere. Koden anvender cv :: mat struktur, som foretrækkes til gammel IplImage struktur.


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


Opdatering Du kan få fat i rammer fra H.264 RTSP-strømme. Se op på dit kamera API for at få oplysninger om at få URL-kommandoen. For et Axis netværkskamera kan URL-adressen f.eks. Være:


// 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

Andre referencer 2


#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
");
    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
",(t2-t1)/(cvGetTickFrequency()*1000.), 1000./((t2-t1)/(cvGetTickFrequency()*1000.)));
        cvShowImage("img",img);
    }
    cvReleaseCapture(&camera);
}

Andre referencer 3


OpenCV kan kompileres med FFMPEG support. Fra ./configure - help :


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


Du kan derefter bruge cvCreateFileCapture\_FFMPEG til at oprette en CvCapture med f.eks. URL'en til kameraets MJPG stream.


Jeg bruger dette til at hente rammer fra et AXIS kamera:


CvCapture *capture = 
    cvCreateFileCapture\_FFMPEG("http://axis-cam/mjpg/video.mjpg?resolution=640x480&req\_fps=10&.mjpg");

Andre referencer 4


Jeg gør det som sådan:


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


Sørg også for, at denne dll er tilgængelig på runtime, ellers vil cvCreateFileCapture returnere NULL


opencv\_ffmpeg200d.dll


Kameraet skal også tillade uautoriseret adgang, sædvanligvis indstillet via sin web-interface. MJPEG-format fungerede via rtsp, men MPEG4 gjorde det ikke.


HTH


Si

Andre referencer 5


Brug ffmpeglib til at oprette forbindelse til strømmen.


Disse funktioner kan være nyttige. Men tag et kig i dokumenterne


av\_open\_input\_stream(...);
av\_find\_stream\_info(...);
avcodec\_find\_decoder(...);
avcodec\_open(...);
avcodec\_alloc\_frame(...);


Du ville have brug for lidt algo for at få en komplet ramme,
som er tilgængelig her


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


Når du har fået en ramme, kan du kopiere videodataene (for hvert fly, hvis det er nødvendigt) til en
IplImage, som er et OpenCV-billedobjekt.


Du kan oprette en IplImage ved hjælp af noget som ...


IplImage *p\_gray\_image = cvCreateImage(size, IPL\_DEPTH\_8U, 1);


Når du har en IplImage, kan du udføre alle mulige billedoperationer, der er tilgængelige i OpenCV lib