跳至內容
測試伺服器
開發伺服器

多相機系統#

本主題說明如何設計、設定和操作同時使用多部相機的系統。

多相機設置在工業應用中很常見,例如檢測、3D 重建和同步資料擷取。當單一相機不足以擷取所有所需資訊時,就會使用多相機。

使用

  • 擷取物件的不同視角
  • 增加視場
  • 提高輸送量
  • 並行檢測多個物件

基本挑戰#

使用多部相機會帶來幾個挑戰:

  • 同步(時序)
  • 頻寬限制(尤其是使用 GigE 相機時)
  • CPU 負載(處理多個串流)
  • 裝置識別與對應

裝置識別#

每部相機都必須具備唯一的識別碼,通常是其序號。

for device_info in device_info_list:
    print(device_info.GetSerialNumber())

對應範例:

Camera 40123456 → Left view
Camera 40123478 → Right view

避免使用索引,例如 devices[0] 因為相機列舉的順序可能會改變。如需詳細資訊,請參閱 列舉相機.

建立多個相機執行個體#

from pypylon import pylon

factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()

cameras = []

for device_info in device_info_list:
    camera = pylon.InstantCamera(factory.CreateDevice(device_info))
    camera.Open()
    cameras.append(camera)

這會為每個裝置建立並開啟一個相機執行個體。

擷取方法#

當使用多個相機時,您必須決定擷取方法:序列式或平行式。

序列式擷取#

這表示影像處理是依序對各個相機進行。

Cam1 → Capture → Process
Cam2 → Capture → Process

此方法的主要特點:

  • 易於實作
  • 未進行時間同步
  • 整體速度較慢

平行式擷取#

這表示會同時處理來自多個相機的影像。

Cam1 → Capture →
                → Process
Cam2 → Capture →

此方法的主要特點:

  • 相機同時擷取
  • 同步所需
  • 較高的 CPU 與頻寬需求

同步方法#

若要同步相機,您可以在軟體同步與硬體同步之間進行選擇。其優缺點類似於軟體與硬體觸發。

軟體同步#

此方法的主要特點:

  • 透過軟體觸發相機
  • 精度有限
  • 受作業系統排程影響

範例:

camera.ExecuteSoftwareTrigger()
Master camera → trigger signal → Slave cameras

此方法的主要特點:

  • 精確的計時
  • 具決定性的行為
  • 立體視覺或量測系統所需

頻寬考量(GigE)#

多部 GigE 相機共用相同的網路頻寬。

潛在問題:

  • 封包遺失
  • 掉格
  • 延遲增加

您可以使用以下其中一種策略來降低潛在問題:

  • 使用專用網路介面卡 (NIC)
  • 啟用巨型訊框 (MTU 9000)
  • 減少 ROI 或幅頻
  • 設定封包延遲

處理架構#

單執行緒#

Acquire all → process all
  • 簡單
  • 可擴充性受限
Camera threads → queue → processing threads
  • 可擴充
  • 更好的 CPU 利用率
  • 實作較為複雜

範例模式#

基本多相機迴圈(循序輪詢)#

from pypylon import pylon

def process(image):
    print(image.shape)

factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()

cameras = [pylon.InstantCamera(factory.CreateDevice(device_info)) for device_info in device_info_list]

for camera in cameras:
    camera.Open()
    camera.StartGrabbing()

while any(camera.IsGrabbing() for camera in cameras):
    for camera in cameras:
        if camera.IsGrabbing():
            with camera.RetrieveResult(1000) as grab_result:
                if grab_result.GrabSucceeded():
                    image = grab_result.Array
                    # Do processing on image here, e.g. call a function.
                    process(image)

pypylon 為多相機設定提供專屬的抽象層: InstantCameraArray.

此類別可管理多部相機並提供 單一統一的 RetrieveResult() 呼叫,包含提供哪部相機傳送影像的相關資訊。

from pypylon import pylon

def process(image):
    print(image.shape)

COUNT_OF_IMAGES_TO_GRAB = 100
RETRIEVE_TIMEOUT_MS = 5000

factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()

with pylon.InstantCameraArray(len(device_info_list)) as cameras:

    for i, camera in enumerate(cameras):
        camera.Attach(factory.CreateDevice(device_info_list[i]))
        print("Using device:", camera.DeviceInfo.ModelName)

    cameras.StartGrabbing()

    for i in range(COUNT_OF_IMAGES_TO_GRAB):
        if not cameras.IsGrabbing():
            break

        with cameras.RetrieveResult(
            RETRIEVE_TIMEOUT_MS,
            pylon.TimeoutHandling_ThrowException
        ) as grab_result:

            if grab_result.GrabSucceeded():
                cam_idx = grab_result.CameraContext
                print(f"Camera {cam_idx}: {cameras[cam_idx].DeviceInfo.ModelName}")
                image = grab_result.Array
                # Do processing on image here, e.g. call a function.
                process(image)
            else:
                print("Error:", grab_result.ErrorDescription)

為什麼 InstantCameraArray 如此重要

與手動迴圈相比,此方法提供:

  • 適用於所有相機的單一擷取迴圈
  • 自動相機內容追蹤 (camera.CameraContext)
  • 更簡單的同步處理
  • 更有效率的執行緒使用率

概念:

Multiple Cameras → InstantCameraArray → Unified RetrieveResult() → Processing

實用設計指南#

  • 始終透過序號識別相機。
  • 建議優先使用硬體同步。
  • 在可能的情況下減少頻寬(例如,透過指定 ROI 或降低幀率)。
  • 使用獨立的處理執行緒以確保可擴展性。
  • 監控系統負載(CPU、網路)。

常見陷阱#

  • 依賴裝置索引。
  • 超出網路頻寬。
  • 忽略同步要求。
  • 在擷取迴圈中阻斷處理。

Mental Model#

Multiple Cameras → Acquisition → Buffers → Processing → Results

重點整理#

  • 多相機系統需要周密的設計。
  • 同步對許多應用至關重要。
  • 必須及早考慮頻寬和 CPU。
  • 可擴展架構採用並行處理。