Synchronous Free Run (blaze)#
使用功能#
為何要使用Synchronous Free Run#
若要使用多台 Blaze 攝影機拍攝同一場景,必須將各台攝影機的曝光時間錯開,以免其光源相互干擾。與環境光類似,各台攝影機的光源也會導致影像品質下降。
透過 PTP,您可以讓一群相機以同步自由運行模式進行拍攝,同時確保各相機的曝光時間以精確對齊的時間間隔依次啟動,並依時間順序進行。如此一來,某台相機接收的光線便不會干擾其他相機的測量結果。
運作原理#
配置同步自由運行有兩種方式。為了幫助您決定哪種選項最適合您,您必須了解 Blaze 攝影機在影像擷取方面的基本運作原理。
在擷取影像時,每個幀由八個子幀組成(若 Fast Mode 已啟用時則為 4 個子幀)。每個子幀均可視為一次獨立的曝光,因為在每個子幀曝光完成後,照明會被關閉,且感光元件會被重置。
幀曝光階段#
在曝光過程中,會發生以下幾個階段:
- 啟動:此情況發生在第一個與第五個子幀之前。
- 重置:感測器已重置。此操作會在每次擷取子幀之前進行。
- 曝光:快門開啟,感光元件接受光線照射。此過程會針對每個子幀重複進行。
- 讀出:從感測器讀出在子幀期間所收集的資料。
相機僅在曝光階段才會發光。
下圖顯示了幀曝光的各個階段(僅顯示子幀 1、2 和 8)。
Synchronous Free Run#
在自由運行模式下操作攝影機,意指攝影機會透過內建的週期性觸發計時器自行觸發。
在同步自由運行模式下,相機時鐘是透過 PTP。同步後的時鐘會使內部觸發計時器也隨之同步。
在設定相機進行同步自由運行時,可透過為各台相機指定個別的擷取開始時間,來對齊各台相機的擷取時序。一旦某台相機的擷取開始時間(由 SyncFreeRunTimerStartTimeHigh 進行明確的生命週期管理即呼叫 SyncFreeRunTimerStartTimeLow 當達到(參數)時,內部觸發計時器便會啟動,相機隨即以固定的幀率進行資料擷取。
資訊
可以設定一個位於過去的開始時間。這種情況會被視為內部計時器是在過去啟動的。
資訊
相機在以下情況發生之前不會開始擷取影像: AcquisitionStart 下達該指令。
同步 Blaze 與 Ace/Ace 2 攝影機
- 若您的應用程式設定中包含ACE 攝影機,則開始時間必須設定在不久的將來。
- 若您的應用程式設定中包含一台ace 2 攝影機,則 blaze 攝影機的開始時間必須設為 0。
使用同步自由運行有兩種方式:
交錯模式#
若要同時操作兩台 Blaze 相機,請選擇交錯模式。在此模式下,當其中一台相機發光時,另一台相機則進行感測器讀出。
資訊
各台攝影機的感測器時序必須完全一致,也就是說,您必須將 ExposureTime, FastMode以及 HDRMode 參數。
感測器的時序也取決於感測器的讀出時間,由於這是感測器的固有特性,因此無法更改。不過,感測器的讀出時間可能會因相機的硬體版本而異。若屬此情況,請改用連續模式。
連續模式#
在大多數情況下,以交錯模式同時運作超過兩台攝影機並不實際。由於網路封包接連不斷,您極可能面臨網路封包遺失的情況,進而導致抓取到的資料不完整。若要獲得更好的效果,請使用連續模式,在此模式下,攝影機會依序連續擷取畫面。
若您希望同時操作多台具有不同感測器時序的攝影機,也必須使用此模式。
為了將可達成的幀率最大化,可將攝影機的擷取起始時間設定為前一台攝影機的讀出階段中的某個時間點。
設定相機#
資訊
pylon Supplementary Package for blaze 包含MultiCamHelperC++ 函式庫。此函式庫屬於 C++ 範例集合的一部分,並位於MultiCam/MultiCamHelper資料夾中。
該圖書館提供 BlazeSynchronousFreeRunHelper 此類別由 Basler 推薦用於設定多台 Blaze 攝影機進行同步自由運行、擷取資料,以及匹配時間上相互關聯的影像幀。此類別的使用方法詳見 同步自由運行 C++ 範例。
MultiCamHelper函式庫還提供了GenericSynchronousFreeRunHelper類別,若您想同步 blaze 相機與 2D GigE 相機,此類別將非常實用。此類別的使用方法,可參閱Multicam/ColorAndDepth資料夾中的範例程式。
若您使用的是 C++ 以外的程式語言,或者不希望使用MultiCamHelper函式庫所提供的類別,本節將說明如何將攝影機設定為「同步自由運行」模式。此設定程序亦適用於交錯模式與連續模式。
使用的變數#
t_startup[i]: 第 i 台攝影機的幀啟動時間長度。t_reset[i]: 第 i 台攝影機的重置時間長度(重置於每個子幀的開始時進行)。t_exp[i]: 第 i 台攝影機對單一子幀的曝光時間長度。t_read[i]: 第 i 台攝影機讀取單一子幀所需的讀出時間。t_frame[i]: 第 i 台攝影機擷取一幀中所有子幀所需的總時間。
實際數值可從相機中讀取。下表列出了您必須讀取的參數名稱:
| 變數 | 相機參數 |
|---|---|
t_startup | StartupTime |
t_reset | ResetTime |
t_exp | ExposureTime |
t_read | ReadoutTime |
t_frame | FrameDuration |
上述所有相機參數的回傳值單位皆為微秒 (µs)。
要設定攝影機並啟動同步自由運行模式:
-
在每台相機上,啟用「PTP 」,並等待主時鐘選定完成且時鐘已充分同步。
詳情請參閱Precision Time Protocol (blaze)。 -
在每台攝影機上,為以下項目設定所需的設定:
ExposureTime,FastMode以及HDRMode.資訊
在將攝影機設定為交錯同步自由運行模式時,您必須將以下參數設定為相同的數值:
ExposureTime,FastMode以及HDRMode. -
計算可能的最高幀率
fps_max如所述 下方. -
在每台攝影機上,請設定
AcquisitionFrameRateEnable參數設為true透過設定來指定所需的幀率AcquisitionFrameRate將參數設定為等於或小於該值的數值fps_max.資訊
您必須將所有攝影機的幀率設定為相同。
-
針對每台攝影機,請依照以下說明計算所需的觸發偏移量,並設定相應的擷取起始時間。
-
準備應用程式的擷取迴圈。
-
在每台攝影機上,執行
StartAcquisition指令。 -
從每台攝影機擷取影像。
確定最高幀率#
當使用連續同步自由運行模式時,每台攝影機的最大幀率會受到攝影機數量及每台攝影機幀持續時間的限制。
當使用交錯式同步自由運行模式時,攝影機可運行於最高可能的幀率。
以下, fps_max[i] 表示第 i 台攝影機的 AcquisitionFrameRate 參數。要讀取 fps_max[i] 以了解 相機 i 透過使用 Pylon SDK 的 API,您可以參考以下程式碼片段:
C++
C#
交錯模式#
由於在交錯模式下,所有攝影機的感測器時序必須完全相同,因此請設定 fps_max 設定為任一台攝影機的最高幀率值。
連續模式#
您可以計算最高幀率 fps_max 以連續模式運作,如下列偽程式碼片段所示:
fmax_min = min(fps_max[0], ... ,fps_max[n-1])
t_total = 0
for i = 0 to n-1
t_total = t_total + t_frame[i] - t_startup[i] - t_reset[i] - t_read[i]
endif
t_total = t_total + t_startup[0] + t_reset[0]
fps = 1e6 / t_total
fps_max = min(fps, fmax_min)
計算觸發偏移量並設定Acquisition Start 時間#
各個採集起始時間必須錯開的時間長度,取決於感測器的時序設定,以及所採用的是交錯模式還是連續同步自由運行模式。
收視調查的開始時間 t_acq_start[i] 應設定為未來某個時間點,以確保在您的應用程式完成所有攝影機的配置並設定擷取迴圈之前,沒有任何攝影機會開始進行擷取。您應預留約 400 毫秒的時間來配置一台攝影機。
以下這段偽代碼片段說明了如何計算相機的觸發偏移量,以及如何設定擷取起始時間。
所用變數的涵義:
n: 攝影機數量。camera[]: 一組攝影機。t_0: 當前PTP 的時間戳記 [ns]。若僅連接相機,該時間戳記會計算自主裝置開機以來經過的「滴答」次數。這意味著該時間尺度是任意的、相對的,且僅在該網路內有效。若需絕對時間尺度,請連接一個與協調世界時(例如 TAI 或 UTC)同步的裝置。fps_max: 最高可能的幀率 [Hz]。trigger_offset: 與前一台攝影機相比,這台攝影機的觸發時間延遲了多少。t_acq_start[]: 採集起始時間 [ns]。t_safety: 為補償抖動,應將採樣延遲的額外時間 [µs]。建議值:250 µs。
camera[0].TimestampLatch.Execute()
t_0 = camera[0].TimestampLatchValue.GetValue()
t_acq_start[0] = t_0 + n * 400 * 1000000
for i = 0 to n-1
camera[i].SyncFreeRunTimerStartTimeLow.SetValue(t_acq_start[i] & 0xffffffff)
camera[i].SyncFreeRunTimerStartTimeHigh.SetValue(t_acq_start[i] >> 32)
camera[i].SyncFreeRunTimerUpdate.Execute()
camera[i].SyncFreeRunEnable.SetValue(true)
if i < n-1
if interleaved_mode
trigger_offset = 1000 * (t_safety + t_exp[i])
else
trigger_offset =
1000 * (t_safety + t_frame[i] - t_read[i] - t_startup[i+1] - t_reset[i+1]
endif
t_acq_start[i+1] = t_acq_start[i] + trigger_offset
endif
endfor