web-dev-qa-db-ja.com

PythonでRTSPストリームからフレームを読み取る

最近Raspberry Piカメラをセットアップし、RTSP経由でフレームをストリーミングしています。完全に必要なわけではないかもしれませんが、これは私がビデオのブロードキャストを使用しているコマンドです:

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

これは完全にビデオをストリーミングします。

次に、Python)を使用してこのストリームを解析し、各フレームを個別に読み取ります。監視の目的でモーション検出を行いたいと思います。

私はこの仕事をどこから始めればよいか完全に迷っています。誰かが私に良いチュートリアルを指摘できますか?これがPython経由で実現できない場合、これを実現するためにどのツール/言語を使用できますか?

11
fmorstatter

ちょっとハッキーなソリューションですが、 VLC python bindingspip install python-vlcでインストールできます)を使用してストリームを再生できます。

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

次に、毎秒程度のスナップショットを作成します。

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

そして、処理に SimpleCV または何かを使用できます(画像ファイル'.snapshot.tmp.png'を処理ライブラリにロードするだけです)。

11
Samadi

「depu」でリストされているのと同じ方法を使用すると、完全にうまくいきました。 「ビデオファイル」を実際のカメラの「RTSP URL」に置き換えたところです。以下の例は、AXIS IPカメラで動作しました。 (これは以前のバージョンのOpenCVではしばらく機能していませんでした)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()
9
venkat

opencvを使用

video=cv2.VideoCapture("rtsp url")

その後、フレームをキャプチャできます。 openCVドキュメントの訪問を読みます: https://docs.opencv.org/3.0-beta/doc/py_tutorials/py_gui/py_video_display/py_video_display.html

ストリームのタイプによっては、おそらくこのプロジェクトをいくつかのアイデアで見ることができます。

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

メガプロになりたい場合は、モーション検出を処理するために http://opencv.org/ (利用可能なPythonモジュール)のようなものを使用できます。

2

pythonおよびOpenCVを使用して、こんにちはビデオからフレームを読み取ることができます。以下はサンプルコードです。pythonおよび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

ここにもう一つのオプションがあります

他の回答よりもはるかに複雑です。 :-O

しかし、この方法では、カメラへの接続が1つだけの場合、同じストリームを複数のマルチプロセスに同時に「フォーク」して画面に送り、マルチキャストに再キャストし、ディスクに書き込むなどができます。

..もちろん、そのようなものが必要になる場合に備えて(そうでない場合は、以前の回答をお勧めします)

2つの独立したpythonプログラムを作成します。

(1)サーバープログラム(rtsp接続、デコード)server.py

(2)クライアントプログラム(共有メモリからフレームを読み取る)client.py

サーバーはクライアントより前に起動する必要があります。

python3 server.py

そして別のターミナルで:

python3 client.py

これがコードです:

(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)

あなたが興味を持ったら、 https://elsampsa.github.io/valkka-examples/ でさらにチェックしてください

0
El Sampsa