Python OpenCV-Streaming von der Kamera – Multithreading, Zeitstempel

Lesezeit: 4 Minuten

Python OpenCV Streaming von der Kamera Multithreading Zeitstempel
lukassz

Ich habe ein einfaches Python-Skript auf Raspberry Pi 3 ausgeführt. Dieses Skript ist dafür verantwortlich, das Videogerät zu öffnen und Daten (800 x 600) mit MJPEG an den HTTP-Endpunkt zu streamen. Wenn ich diesen Stream erhalte, arbeitet einer meiner Raspberry Pi-Kerne zu 100 %. Kann OpenCV mit Multi-Threading ausgeführt werden?

Das ist mein Code

import cv2
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
import time
import argparse
import socket as Socket    
camera = None  

def setUpCameraCV():
    global camera
    camera = cv2.VideoCapture(0)

class mjpgServer(BaseHTTPRequestHandler):

    ip = None
    hostname = None

    def do_GET(self):

        print('connection from:', self.address_string())

        if self.ip is None or self.hostname is None:
            self.ip, _ = 0.0.0.0
            self.hostname = Socket.gethostname()

        if self.path == '/mjpg':

            self.send_response(200)
            self.send_header('Cache-Control', 'no-cache')
            self.send_header('Pragma', 'no-cache')
            self.send_header('Connection', 'close')
            self.send_header(
                'Content-type',
                'multipart/x-mixed-replace; boundary=mjpegstream'
            )
            self.end_headers()

            while True:
                if camera:
                    ret, img = camera.read()

                else:
                    raise Exception('Error, camera not setup')

                if not ret:
                    print('no image from camera')
                    time.sleep(1)
                    continue

                ret, jpg = cv2.imencode('.jpg', img)
                
                self.end_headers()
                self.wfile.write('--mjpegstream')
                self.end_headers()

                self.send_header('Content-type', 'image/jpeg')
                self.send_header('Content-length', str(jpg.size))
                self.end_headers()
                self.wfile.write(jpg.tostring())    

def main():
    try:
        setUpCameraCV()         
        mjpgServer.ip = 0.0.0.0
        mjpgServer.hostname = Socket.gethostname()
        server = HTTPServer((ipv4, args['port']), mjpgServer)
        print("server started on {}:{}".format(Socket.gethostname(), args['port']))
        server.serve_forever()

    except KeyboardInterrupt:
        print('KeyboardInterrupt')

    server.socket.close()


if __name__ == '__main__':
    main()

Eine andere Frage, wie kann man den Zeitstempel jedes Frames auf der Clientseite (Empfänger) erhalten?

Geben Sie hier die Bildbeschreibung ein

  • Schau mal Hier

    – GPPK

    11. März 19 um 10:15 Uhr

1644317885 285 Python OpenCV Streaming von der Kamera Multithreading Zeitstempel
Nathan

Die Verwendung von Threading zur Verarbeitung von E/A-intensiven Operationen (wie z. B. das Lesen von Frames von einer Webcam) ist ein klassisches Programmiermodell. Seit dem Zugriff auf die Webcam/Kamera mit cv2.VideoCapture().read() ist eine blockierende Operation, unser Hauptprogramm wird angehalten, bis das Bild von der Kamera gelesen und an unser Skript zurückgegeben wird. Im Wesentlichen besteht die Idee darin, einen anderen Thread zu erzeugen, um das Erfassen der Frames zu handhaben parallel anstatt sich auf einen einzigen Thread (unseren ‘Haupt’-Thread) zu verlassen, um die Frames aufzunehmen sequentiell bestellen. Dadurch können Frames kontinuierlich aus dem I/O-Thread gelesen werden, während unser Root-Thread den aktuellen Frame verarbeitet. Sobald der Root-Thread die Verarbeitung seines Frames beendet hat, muss er einfach den aktuellen Frame vom E/A-Thread abrufen, ohne auf blockierende E/A-Operationen warten zu müssen.

Daher können wir die Leistung verbessern, indem wir einen neuen Thread erstellen, der nichts anderes tut, als nach neuen Frames abzufragen, während unser Haupt-Thread die Verarbeitung des aktuellen Frames übernimmt. Für eine Implementierung zur Handhabung mehrerer Kamerastreams, werfen Sie einen Blick auf Capture multiple camera streams with OpenCV

from threading import Thread
import cv2, time

class VideoStreamWidget(object):
    def __init__(self, src=0):
        self.capture = cv2.VideoCapture(src)
        # Start the thread to read frames from the video stream
        self.thread = Thread(target=self.update, args=())
        self.thread.daemon = True
        self.thread.start()

    def update(self):
        # Read the next frame from the stream in a different thread
        while True:
            if self.capture.isOpened():
                (self.status, self.frame) = self.capture.read()
            time.sleep(.01)

    def show_frame(self):
        # Display frames in main program
        cv2.imshow('frame', self.frame)
        key = cv2.waitKey(1)
        if key == ord('q'):
            self.capture.release()
            cv2.destroyAllWindows()
            exit(1)

if __name__ == '__main__':
    video_stream_widget = VideoStreamWidget()
    while True:
        try:
            video_stream_widget.show_frame()
        except AttributeError:
            pass

  • Neugierig, i) Warum wird time.sleep(.01) verwendet? ii) Wird es beim Lesen von echten IP-Kameras benötigt? Weil die Lösung, an der ich arbeite, Echtzeit benötigt, aber diese 100-ms-Hinzufügung ist eine große Verzögerung, wenn man sie im Gesamtbild betrachtet.

    – Aakash Basu

    9. November 20 um 10:06 Uhr

  • Können Sie auch hier freundlicherweise einige Expertenratschläge geben: stackoverflow.com/questions/64754236/…

    – Aakash Basu

    9. November 20 um 17:33 Uhr

  • @AakashBasu time.sleep wird verwendet, weil die Kamera nur so schnell abfragen kann, dass es nicht nötig ist, mit einer lächerlichen Rate abzufragen, wenn sich keine neuen Frames im Puffer befinden. Ich kann es nur empfehlen, Sie müssten sich die technischen Daten Ihrer IP-Kamera ansehen. Die meisten IP-Kameras liegen im Bereich von 30–60 FPS, sodass eine schnellere Abfrage keinen Vorteil bringt. Sie können die Verzögerung verringern oder ganz herausnehmen. Ich habe herausgefunden, dass die Verzögerung für meine Kamera nützlich war

    – Nathan

    9. November 20 um 22:12 Uhr


  • Irgendwelche Hilfe dazu? stackoverflow.com/questions/65121094/…

    – Aakash Basu

    3. Dezember 2020 um 6:49 Uhr

  • Ein guter Anhaltspunkt wäre also 1 Sekunde/fps? zB auf einer 30-fps-Kamera sollten Sie bei 1/30 = 0,033 Sekunden oder weniger abfragen?

    – Josch

    9. Februar 21 um 16:12 Uhr

.

821770cookie-checkPython OpenCV-Streaming von der Kamera – Multithreading, Zeitstempel

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy