web-dev-qa-db-fra.com

OpenCV avec caméras réseau

J'utilise openCV 1.1pre1 sous Windows. J'ai une caméra réseau et je dois saisir des images d'OpenCV. Cette caméra peut diffuser un flux mpeg4 standard sur RTSP ou mjpeg sur http. J'ai vu de nombreuses discussions parler de l'utilisation de ffmpeg avec openCV mais je ne peux pas le faire fonctionner.

Comment puis-je saisir des images d'une caméra IP avec openCV?

Merci

Andrea

23
Grifo

le protocole rtsp n'a pas fonctionné pour moi. mjpeg a travaillé du premier coup. Je suppose qu'il est intégré à mon appareil photo (Dlink DCS 900).

Syntaxe trouvée ici: http://answers.opencv.org/question/133/how-do-i-access-an-ip-camera/

Je n'avais pas besoin de compiler OpenCV avec le support ffmpg.

3
john ktejik

J'ai inclus du code C++ pour saisir des cadres. Il nécessite OpenCV version 2.0 ou supérieure. Le code utilise la structure cv :: mat qui est préférée à l'ancienne structure 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;
    }   
}

pdate Vous pouvez récupérer des trames à partir de flux H.264 RTSP. Recherchez votre API de caméra pour plus de détails pour obtenir la commande URL. Par exemple, pour une caméra réseau Axis, l'adresse URL peut être:

// 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:[email protected]:554/axis-media/media.amp
21
Alexey
#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);
}
10
lolong

OpenCV peut être compilé avec le support FFMPEG. De ./ configure --help:

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

Vous pouvez ensuite utiliser cvCreateFileCapture_FFMPEG pour créer un CvCapture avec par exemple l'URL du flux MJPG de la caméra.

J'utilise ceci pour saisir des images d'une caméra AXIS:

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

Je fais juste ça comme ça:

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

Assurez-vous également que cette DLL est disponible au moment de l'exécution, sinon cvCreateFileCapture renverra NULL

opencv_ffmpeg200d.dll

La caméra doit également autoriser l'accès non authentifié, généralement défini via son interface Web. Le format MJPEG fonctionnait via rtsp mais pas MPEG4.

hth

Si

3
sipi

Utilisez ffmpeglib pour vous connecter au flux.

Ces fonctions peuvent être utiles. Mais jetez un oeil dans les documents

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

Vous auriez besoin d'un petit algo pour obtenir un cadre complet, qui est disponible ici

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

Une fois que vous obtenez une image, vous pouvez copier les données vidéo (pour chaque avion si nécessaire) dans un IplImage qui est un objet image OpenCV.

Vous pouvez créer un IplImage en utilisant quelque chose comme ...

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

Une fois que vous avez un IplImage, vous pouvez effectuer toutes sortes d'opérations d'image disponibles dans la bibliothèque OpenCV

1
Indy9000