Python程式設計指南#
Basler pylon 的官方 Python 語言繫結為 pypylon 專案。pypylon 是一個裝載於 GitHub 上的開源專案。若要使用 Basler 3D 相機,必須使用 4.0 或更高版本。
作為官方 python wrapper 的替代方案,也可以透過 Python Harvester 程式庫來操作相機。Harvesters 是一個旨在簡化電腦視覺應用程式中影像擷取流程的 Python 程式庫。它能夠透過 GenTL Producer 進行影像擷取。
資訊
本主題中的所有資訊均適用於所有 blaze 與 Smart blaze 相機型號。為求簡潔,文中以 "blaze" 統稱所有型號。
pypylon#
安裝 pypylon#
- 安裝 pylon(7.5 或更高版本)以及 pylon Supplementary Package for blaze(1.7 或更高版本)
- 安裝 pypylon:
pip3 install pypylon
Python 程式設計範例#
pylon Supplementary Package for blaze 包含一些 Python 程式設計範例,說明如何使用 Python 和 pypylon 存取 blaze 相機。
To open the folder containing the programming samples for blaze cameras, press the Win key, go to the Basler folder, and choose blaze Samples. A File Explorer window opens. The Python programming samples are located in the Python folder.
The Python samples are located in the /opt/pylon/share/pylon/Samples/blaze/Python/pypylon folder.
資訊
在建置範例之前,請將包含範例的資料夾複製到您具有寫入權限的自選位置。
每個範例都有一個 README.md 檔案,提供關於範例功能以及執行範例所需條件的資訊。
使用 pypylon 存取 blaze 相機#
查看 SimpleGrab/simple_grab.py 或使用以下程式碼片段:
from pypylon import pylon
dc = pylon.DeviceInfo()
dc.SetDeviceClass("BaslerGTC/Basler/GenTL_Producer_for_Basler_blaze_101_cameras")
camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice(dc))
camera.Open()
camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)
while camera.IsGrabbing():
grabResult = camera.RetrieveResult(1000, pylon.TimeoutHandling_ThrowException)
if grabResult.GrabSucceeded():
pylonDataContainer = grabResult.GetDataContainer()
for componentIndex in range(pylonDataContainer.DataComponentCount):
pylonDataComponent = pylonDataContainer.GetDataComponent(componentIndex)
if pylonDataComponent.ComponentType == pylon.ComponentType_Intensity:
intensity = pylonDataComponent.Array
_2d_intensity = intensity.reshape(pylonDataComponent.Height, pylonDataComponent.Width)
pylonDataComponent.Release()
grabResult.Release()
camera.StopGrabbing()
Harvester#
安裝 Harvester#
在命令列中執行以下指令:
Python Harvester 程式設計範例#
pylon Supplementary Package for blaze 包含一些 Python 程式設計範例,說明如何使用 Python 和 Harvester 存取 blaze 相機。
To open the folder containing the programming samples for blaze cameras, press the Win key, go to the Basler folder, and choose blaze Samples. A File Explorer window opens. The Python programming samples are located in the Python folder.
The Python Harvester samples are located in the /opt/pylon/share/pylon/Samples/blaze/Python/Harvester folder.
資訊
在建置範例之前,請將包含範例的資料夾複製到您具有寫入權限的自選位置。
每個範例都有一個 README.md 檔案,提供關於範例功能以及執行範例所需條件的資訊。
Linux
如果您已將 pylon Software Suite 與 pylon Supplementary Package for blaze 安裝至 /opt/pylon 以外的位置,則必須調整 Harvester 載入 blaze 相機 GenTL Producer 的路徑。
在範例程式碼中搜尋出現的位置 /opt/pylon/lib/gentlproducer/gtl 並調整路徑。
使用 Harvester 存取 blaze 相機#
執行以下步驟以使用 Harvester 尋找所有可用的 blaze 相機:
- 匯入 Harvester 模組。
- 實例化一個 Harvester 物件。
-
載入適用於 blaze 相機的 GenTL Producer。
-
更新可用裝置清單。
- 取得有關可用裝置的資訊。
若要連線至相機,請使用 h.create() 函數。
下列敘述會連線至第一個可用的 blaze 相機:
如果您想要開啟特定的相機,可以使用透過 device_info_list Harvester 類別物件的 property 所提供的屬性來指定。
範例:
請注意,指定器必須能夠唯一識別您想要開啟的裝置。如果有超過一部相機符合條件,將無法開啟任何裝置。
若要與相機中斷連線,請發出下列指令:
存取相機參數#
您可透過影像擷取器的 remote_device property 存取相機參數。遠端裝置的 node_map property 則提供所有相機參數的存取權。
範例:
# Get a parameter.
operatingMode = ia.remote_device.node_map.OperatingMode.value
# Set a parameter.
ia.remote_device.node_map.OperatingMode.value = 'ShortRange'
若要取得所有可用相機參數的清單,請使用下列指令:
請參閱 SimpleGrab sample 以取得更多關於如何設定和取得 blaze 相機參數的範例。
擷取資料#
資訊
由於 Harvester 不支援 GenICam GenDC 串流格式,因此在擷取資料之前,您必須一律停用 GenDC 串流格式。若要停用 GenDC 串流格式,請使用下列指令:
從 blaze 相機擷取的緩衝區可以包含多個組件。其中包含 Range、Intensity 和 Confidence 組件。
下列程式碼片段會啟用所有可用的組件,並設定 Range 組件的 Pixel Format,以便以點雲(point cloud)形式提供深度資料。在點雲中,每個感測器像素都會被指派一個 x、y、z 座標三元組。
ia.remote_device.node_map.ComponentSelector.value = "Range"
ia.remote_device.node_map.ComponentEnable.value = True
ia.remote_device.node_map.PixelFormat.value = "Coord3D_ABC32f"
ia.remote_device.node_map.ComponentSelector.value = "Intensity"
ia.remote_device.node_map.ComponentEnable.value = True
ia.remote_device.node_map.PixelFormat.value = "Mono16"
ia.remote_device.node_map.ComponentSelector.value = "Confidence"
ia.remote_device.node_map.ComponentEnable.value = True
ia.remote_device.node_map.PixelFormat.value = "Confidence16"
如果您想要使用深度圖(depth map)而非點雲,請進行如下設定來組態 Range 組件:
ia.remote_device.node_map.ComponentSelector.value = "Range"
ia.remote_device.node_map.ComponentEnable.value = True
ia.remote_device.node_map.PixelFormat.value = "Coord3D_C16"
若要開始擷取,請呼叫影像擷取器的 start() 函數:
典型的擷取迴圈如下所示:
資訊
緩衝區僅在 with 敘述內有效,並會在您離開該範圍(scope)時遭到銷毀。如果您想要在 with 範圍之外使用緩衝區,您必須使用 np.copy() 以進行深度複製。
以下程式碼片段示範了如何存取緩衝區的元件:
with ia.fetch() as buffer:
depth = buffer.payload.components[0]
intensity = buffer.payload.components[1]
confidence = buffer.payload.components[2]
Harvester 會將組件傳回為一維 NumPy 陣列。
為了便於後續處理,可將一維陣列轉換為二維或三維陣列:
depth_arr = depth.data.reshape(pointcloud.height, pointcloud.width,
int(pointcloud.num_components_per_pixel))
intenstiy_arr = intensity.data.reshape(intensity.height, intensity.width)
confidence_arr = confidence.data.reshape(confidence.height, confidence.width)
num_components_per_pixel 取決於 Range 組件的 Pixel Format。如果 Pixel Format 等於 Coord3D_ABC32f,Range 組件會以點雲的形式表示,也就是每個像素都有 3 個浮點數值。其結果是一個三維陣列,可用來儲存每個像素的 x、y 和 z 座標。
如果 Pixel Format 等於 Coord3D_C16,Range 組件會以 16 位元灰階影像的形式表示,也就是每個像素有一個 16 位元整數值。
如需如何將深度圖的灰階值轉換為 mm 的詳細資訊,請參閱處理量測結果主題。
完成資料擷取後,請呼叫 stop() 函數:
除了如上所示實作擷取迴圈之外,另一種方法是讓 Harvester 提供一個背景執行緒來實作擷取迴圈,並透過發出回呼 (Callback) 來通知應用程式。SimpleGrab_Callback 範例中說明了這種方法。
偵錯應用程式與控制 GigE Vision Heartbeat#
像是 blaze 相機這類的 GigE Vision 相機,需要應用程式透過定期傳送特殊的網路封包給相機,來定期存取相機。如果相機沒有接收到這些心跳訊號,它會認為連線已中斷,並將不再接受來自應用程式的任何指令。
當您執行應用程式時,針對 blaze 相機的 GenTL Producer 通常會產生這些心跳訊號。如果您在應用程式中設定了中斷點並觸發了該中斷點,偵錯工具將會暫停所有執行緒,包括傳送心跳訊號的執行緒。因此,當您在對應用程式進行偵錯並逐步執行程式碼時,不會有心跳訊號傳送給相機。結果,相機偵測到心跳逾時並關閉連線。心跳逾時的預設值為 3000 ms。
為了因應這種情況,您必須在開發期間增加心跳逾時時間。您可以透過設定名為 GEV_HEARTBEAT_TIMEOUT 的環境變數,並指定所需的逾時時間(以毫秒為單位)來達成。
或者,您也可以在應用程式中這樣設定心跳逾時時間:
資訊
如果您將心跳逾時時間增加到一個很高的高度,並且在沒有正確關閉裝置的情況下停止應用程式,您將無法再次開啟相機,並會收到一則指出裝置目前正在使用的錯誤訊息。如果您使用偵錯工具停止應用程式,或者應用程式非預期終止,就可能會發生這種情況。若要再次開啟相機,您必須等待逾時時間結束,或是拔除相機的網路線。