Computer Vision: Gleichzeitige Aufnahme mit mehreren Kameras und Hardware

Sensorsynchronisation

Derzeit gibt es zwei Hauptmethoden, um Informationen von verschiedenen Sensoren (Frames, IMU-Pakete, ToF usw.) zu synchronisieren:

  • Hardware-Synchronisation (basierend auf Hardware-Signaltrigger, hohe Synchronisationsgenauigkeit, erfordert Hardware-Unterstützung)
  • Software-Synchronisation (Synchronisation basierend auf Zeitstempel oder Seriennummer, geringe Synchronisationsgenauigkeit, keine Hardware-Unterstützung)

Dieser Blog konzentriert sich auf die Hardware-Synchronisierung, die eine präzise Synchronisierung zwischen mehreren Kamerasensoren und möglicherweise mit anderer Hardware wie Blitz-LEDs, externen IMUs oder anderen Kameras ermöglicht.

Hardware-Synchronisierungssignal

FSYNC-Signal

Das FSYNC/FSIN-Signal (Frame-Sync) ist ein Impuls, der zu Beginn jeder Frame-Erfassung auf High gesetzt wird. Seine Länge ist nicht proportional zur Belichtungszeit, es kann ein- oder ausgegeben werden und die Arbeitsspannung beträgt 1,8 V.

Bei einer binokularen Stereokamera (OAK-D*) möchten wir, dass die binokularen Schwarz-Weiß-Kameras vollständig synchronisiert sind, sodass für einen Kamerasensor (z. B. die linke Kamera) FSYNC auf INPUT (Eingang) eingestellt ist, während für den anderen Kamerasensor ( (z. B. rechte Kamera) FSYNC ist auf OUTPUT (Ausgabe) eingestellt. In einer solchen Konfiguration steuert die rechte Kamera die linke Kamera.

Hinweis: Derzeit kann nur OV9282/OV9782 ein FSYNC-Signal ausgeben, und IMX378/477/577 usw. sollten ebenfalls über diese Fähigkeit verfügen, sie unterstützen sie jedoch noch nicht (diese Signale können also kein FSYNC-Signal ansteuern, sie können es). nur davon angetrieben werden). AR0234 unterstützt nur das Eingangs-FSYNC-Signal.

Wenn wir die Kamera mit einem externen Signal ansteuern möchten, müssen wir FSIN als EINGANG des Kamerasensors festlegen. Schließen Sie einen Signalgenerator an alle FSIN-Pins an, damit die Kamera jedes Bild entsprechend dem Triggersignal des Signalgenerators erfasst.

STROBE-Signal

Das STROBE-Signal ist der Ausgang des Bildsensors und ist während der Belichtungszeit des Bildsensors aktiv (hoher Pegel). Damit lässt sich eine externe LED-Beleuchtung ansteuern, sodass die Beleuchtung nur während der Belichtungszeit aktiviert wird, statt ständig eingeschaltet zu sein, was den Stromverbrauch und die Wärmeentwicklung reduziert.

Verwenden Sie das STROBE-Signal der Kamera der OAK-D-Pro-Serie (sie verfügt über eine integrierte IR-LED und einen IR-Laserpunktsender), um Laser/LED anzusteuern.

Hardware-Verkabelung

Hardware-Ausstattung

Die von uns verwendeten Hardwaregeräte sind wie folgt:
OV9782 Weitwinkelkamera × 4
OAK-FFC-4P-Kameramodul × 1

Produktmerkmale der Weitwinkelkamera OV9782 :

  • CMOS lichtempfindlich
  • Globaler Verschluss
  • Maximale Bildrate: 120 FPS
  • Maximale Auflösung: 1 MP (1280 x 800)
  • DFOV: 89,5°
  • HFOV: 80°
  • VFOV: 55°
  • Fokusbereich: Fester Fokus: 19,6 cm – ∞

Das Kameramodul OAK-FFC-4P ist ein geteiltes OAK, das über flexible Kabel mit 4 unabhängigen MIPI-Kameramodulen verbunden werden kann. Seine Produktmerkmale sind wie folgt:

  • 4T Rechenleistung;
  • 4K H.265-Streaming;
  • Messgenauigkeit im Zentimeterbereich;
  • Unterstützte Plattformen und Sprachen: Windows10, Ubuntu, Raspberry Pi, Linux, macOS, Jetson, Python, C++, ROS, Android (Tiefeai≥2.16.0 erforderlich).

Verdrahtungsschritte:

1. Verbinden Sie zunächst den FSIN-Testpunkt an jedem Kabel mit einem Jumper mit dem FSIN-Pin auf der entsprechenden Kameraplatine (Sie können auch alle FSIN-Pins auf der Kameraplatine direkt verbinden): 2. Verbinden Sie dann die 4 OV9782-
Fügen Sie hier eine Bildbeschreibung ein
Breitbandkabel Die Winkelkamera ist über ein Kabel mit dem OAK-FFC-4P-Kameramodul verbunden:
Fügen Sie hier eine Bildbeschreibung ein
3. Zum Schluss versorgen Sie das Kameramodul mit Strom und verbinden es über USB mit dem Computer-PC.

Software-Treiber

Schreiben Sie den Testcode und drucken Sie den Zeitstempel des Geräts aus. camera_driver.pyDie Datei lautet wie folgt:

import depthai as dai
import time
import cv2
import collections

set_fps = 30

class FPS:
    def __init__(self, window_size=30):
        self.dq = collections.deque(maxlen=window_size)
        self.fps = 0

    def update(self, timestamp=None):
        if timestamp == None: timestamp = time.monotonic()
        count = len(self.dq)
        if count > 0: self.fps = count / (timestamp - self.dq[0])
        self.dq.append(timestamp)

    def get(self):
        return self.fps

cam_list = ['rgb', 'left', 'right', 'camd']
cam_socket_opts = {
    
    
    'rgb'  : dai.CameraBoardSocket.RGB,   # Or CAM_A
    'left' : dai.CameraBoardSocket.LEFT,  # Or CAM_B
    'right': dai.CameraBoardSocket.RIGHT, # Or CAM_C
    'camd' : dai.CameraBoardSocket.CAM_D,
}

pipeline = dai.Pipeline()
cam = {
    
    }
xout = {
    
    }
for c in cam_list:
    cam[c] = pipeline.create(dai.node.MonoCamera)
    cam[c].setResolution(dai.MonoCameraProperties.SensorResolution.THE_800_P)
    if c == 'rgb':
        cam[c].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.OUTPUT)
    else:
        cam[c].initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
    cam[c].setBoardSocket(cam_socket_opts[c])
    xout[c] = pipeline.create(dai.node.XLinkOut)
    xout[c].setStreamName(c)
    cam[c].out.link(xout[c].input)


config = dai.Device.Config()
config.board.gpio[6] = dai.BoardConfig.GPIO(dai.BoardConfig.GPIO.OUTPUT,
                                            dai.BoardConfig.GPIO.Level.HIGH)

with dai.Device(config) as device:
    device.startPipeline(pipeline)
    q = {
    
    }
    fps_host = {
    
    }  # FPS computed based on the time we receive frames in app
    fps_capt = {
    
    }  # FPS computed based on capture timestamps from device
    for c in cam_list:
        q[c] = device.getOutputQueue(name=c, maxSize=1, blocking=False)
        cv2.namedWindow(c, cv2.WINDOW_NORMAL)
        cv2.resizeWindow(c, (640, 480))
        fps_host[c] = FPS()
        fps_capt[c] = FPS()

    while True:
        frame_list = []
        for c in cam_list:
            pkt = q[c].tryGet()
            if pkt is not None:
                fps_host[c].update()
                fps_capt[c].update(pkt.getTimestamp().total_seconds())
                print(c+":",pkt.getTimestampDevice())
                frame = pkt.getCvFrame()
                cv2.imshow(c, frame)
        print("-------------------------------")
        # print("\rFPS:",
        #       *["{:6.2f}|{:6.2f}".format(fps_host[c].get(), fps_capt[c].get()) for c in cam_list],
        #       end='', flush=True)

        key = cv2.waitKey(1)
        if key == ord('q'):
            break

laufen

python camera_driver.py

Verweise

1. Realisieren Sie synchrone Aufnahmen zwischen OAK-Mehrfachkameras durch Hardware-Triggersignale.
2. Offizielles Dokument: Hardware-Synchronisation.
3. Offizielles Dokument: Oak-ffc-4p.
4. Schematische Darstellung
. 5. Oak_deptahi_external_trigger_fsync.py

#!/usr/bin/env python3
import depthai as dai
import cv2
import time

pipeline = dai.Pipeline()

camRgb = pipeline.create(dai.node.ColorCamera)
camRgb.setColorOrder(dai.ColorCameraProperties.ColorOrder.RGB)
camRgb.setIspScale(2,3)
camRgb.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
camRgb.initialControl.setExternalTrigger(4,3)

xoutRgb = pipeline.create(dai.node.XLinkOut)
xoutRgb.setStreamName("color")
camRgb.isp.link(xoutRgb.input)

monoLeft = pipeline.create(dai.node.MonoCamera)
monoLeft.setResolution(dai.MonoCameraProperties.SensorResolution.THE_720_P)
monoLeft.setBoardSocket(dai.CameraBoardSocket.LEFT)
monoLeft.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
monoLeft.initialControl.setExternalTrigger(4,3)

xoutLeft = pipeline.create(dai.node.XLinkOut)
xoutLeft.setStreamName("left")
monoLeft.out.link(xoutLeft.input)

monoRight = pipeline.createMonoCamera()
monoRight.setResolution(dai.MonoCameraProperties.SensorResolution.THE_720_P)
monoRight.setBoardSocket(dai.CameraBoardSocket.RIGHT)
monoRight.initialControl.setFrameSyncMode(dai.CameraControl.FrameSyncMode.INPUT)
monoRight.initialControl.setExternalTrigger(4,3)

xoutRight = pipeline.create(dai.node.XLinkOut)
xoutRight.setStreamName("right")
monoRight.out.link(xoutRight.input)

# Connect to device with pipeline
with dai.Device(pipeline) as device:
    arr = ['left', 'right', 'color']
    queues = {
    
    }
    frames = {
    
    }

    for name in arr:
        queues[name] = device.getOutputQueue(name)

    print("Starting...")

    while True:
        for name in arr:
            if queues[name].has():
                frames[name]=queues[name].get().getCvFrame()

        for name, frame in frames.items():
            cv2.imshow(name, frame)

        key = cv2.waitKey(1)
        if key == ord('q'):
            break

Supongo que te gusta

Origin blog.csdn.net/weixin_43603658/article/details/131460786
Recomendado
Clasificación