web-dev-qa-db-fra.com

Lire les cadres du flux RTSP en Python

J'ai récemment mis en place une caméra Raspberry Pi et diffuse les images sur RTSP. Bien que cela ne soit peut-être pas complètement nécessaire, voici la commande que j'utilise pour diffuser la vidéo:

raspivid -o - -t 0 -w 1280 -h 800 |cvlc -vvv stream:///dev/stdin --sout '#rtp{sdp=rtsp://:8554/output.h264}' :demux=h264

Cela diffuse parfaitement la vidéo.

Ce que je voudrais maintenant faire, c'est d'analyser ce flux avec Python et de lire chaque image individuellement. J'aimerais faire de la détection de mouvement à des fins de surveillance. 

Je suis complètement perdu par où commencer sur cette tâche. Quelqu'un peut-il m'indiquer un bon tutoriel? Si ceci n'est pas réalisable via Python, quels outils/langages puis-je utiliser pour accomplir cela?

9
fmorstatter

Bit d'une solution de hacky, mais vous pouvez utiliser les liaisons de python VLC (vous pouvez l'installer avec pip install python-vlc) et lire le flux:

import vlc
player=vlc.MediaPlayer('rtsp://:8554/output.h264')
player.play()

Ensuite, prenez un instantané toutes les secondes environ:

while 1:
    time.sleep(1)
    player.video_take_snapshot(0, '.snapshot.tmp.png', 0, 0)

Et vous pouvez ensuite utiliser SimpleCV ou quelque chose pour le traitement (il suffit de charger le fichier image '.snapshot.tmp.png' dans votre bibliothèque de traitement).

11
Samadi

utiliser ouvertement

video=cv2.VideoCapture("rtsp url")

et alors vous pouvez capturer Framse. lire la documentation sur openCV: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html

3

En fonction du type de flux, vous pouvez probablement jeter un coup d'œil à ce projet pour quelques idées.

https://code.google.com/p/python-mjpeg-over-rtsp-client/

Si vous voulez être méga-pro, vous pouvez utiliser quelque chose comme http://opencv.org/ (modules Python disponibles, je crois) pour gérer la détection de mouvement. 

3
synthesizerpatel

Utiliser la même méthode que celle indiquée par "depu" a parfaitement fonctionné pour moi. Je viens de remplacer "fichier vidéo" par "URL RTSP" de la caméra réelle. L'exemple ci-dessous a fonctionné avec une caméra AXIS IP. (Cela ne fonctionnait pas pendant un certain temps dans les versions précédentes d'OpenCV) Fonctionne sous OpenCV 3.4.1 Windows 10) 

import cv2
cap = cv2.VideoCapture("rtsp://root:[email protected]:554/axis-media/media.amp")

while(cap.isOpened()):
    ret, frame = cap.read()
    cv2.imshow('frame', frame)
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
2
venkat

Salut lire des images de la vidéo peut être réalisé en utilisant python et OpenCV. Voici l'exemple de code. Fonctionne bien avec les versions python et opencv2.

import cv2
import os
#Below code will capture the video frames and will sve it a folder (in current working directory)

dirname = 'myfolder'
#video path
cap = cv2.VideoCapture("TestVideo.mp4")
count = 0
while(cap.isOpened()):
    ret, frame = cap.read()
    if not ret:
        break
    else:
        cv2.imshow('frame', frame)
        #The received "frame" will be saved. Or you can manipulate "frame" as per your needs.
        name = "rec_frame"+str(count)+".jpg"
        cv2.imwrite(os.path.join(dirname,name), frame)
        count += 1
    if cv2.waitKey(20) & 0xFF == ord('q'):
        break
cap.release()
cv2.destroyAllWindows()
0
deepu

Voici encore une option

C'est beaucoup plus compliqué que les autres réponses. : -O

Mais de cette manière, avec une seule connexion à la caméra, vous pouvez "transférer" le même flux simultanément vers plusieurs processus multiples, vers l'écran, le reformater en multidiffusion, l'écrire sur un disque, etc. 

.. bien sûr, juste au cas où vous auriez besoin de quelque chose comme ça (sinon vous préférez les réponses précédentes)

Créons deux programmes python indépendants:

(1) Programme serveur (connexion rtsp, décodage) server.py

(2) Programme client (lit les images de la mémoire partagée) client.py

Le serveur doit être démarré avant le client, c.-à-d.

python3 server.py

Et puis dans un autre terminal:

python3 client.py

Voici le code:

(1) server.py

import time
from valkka.core import *

# YUV => RGB interpolation to the small size is done each 1000 milliseconds and passed on to the shmem ringbuffer
image_interval=1000  
# define rgb image dimensions
width  =1920//4
height =1080//4
# posix shared memory: identification tag and size of the ring buffer
shmem_name    ="cam_example" 
shmem_buffers =10 

shmem_filter    =RGBShmemFrameFilter(shmem_name, shmem_buffers, width, height)
sws_filter      =SwScaleFrameFilter("sws_filter", width, height, shmem_filter)
interval_filter =TimeIntervalFrameFilter("interval_filter", image_interval, sws_filter)

avthread        =AVThread("avthread",interval_filter)
av_in_filter    =avthread.getFrameFilter()
livethread      =LiveThread("livethread")

ctx =LiveConnectionContext(LiveConnectionType_rtsp, "rtsp://user:[email protected]", 1, av_in_filter)

avthread.startCall()
livethread.startCall()

avthread.decodingOnCall()
livethread.registerStreamCall(ctx)
livethread.playStreamCall(ctx)

# all those threads are written in cpp and they are running in the
# background.  Sleep for 20 seconds - or do something else while
# the cpp threads are running and streaming video
time.sleep(20)

# stop threads
livethread.stopCall()
avthread.stopCall()

print("bye") 

(2) client.py

import cv2
from valkka.api2 import ShmemRGBClient

width  =1920//4
height =1080//4

# This identifies posix shared memory - must be same as in the server side
shmem_name    ="cam_example"
# Size of the shmem ringbuffer - must be same as in the server side
shmem_buffers =10              

client=ShmemRGBClient(
name          =shmem_name,
n_ringbuffer  =shmem_buffers,
width         =width,
height        =height,
mstimeout     =1000,        # client timeouts if nothing has been received in 1000 milliseconds
verbose       =False
) 

while True:
index, isize = client.pull()
if (index==None):
    print("timeout")
else:
    data =client.shmem_list[index][0:isize]
    img =data.reshape((height,width,3))
    img =cv2.GaussianBlur(img, (21, 21), 0)
    cv2.imshow("valkka_opencv_demo",img)
    cv2.waitKey(1)

Si vous êtes intéressé, jetez un œil à https://elsampsa.github.io/valkka-examples/

0
El Sampsa