Python程式設計指南#
Basler pylon 的官方 Python 語言綁定是pypylon專案。pypylon 是一個託管於 GitHub 上的開源專案。若要使用 Basler 3D 攝影機,必須使用 4.0 版或更高版本。
除了官方的 Python 封裝函式外,亦可透過 PythonHarvester函式庫來操作相機。Harvester 是一個 Python 函式庫,旨在簡化電腦視覺應用中的影像擷取流程。它能透過 GenTL Producers 進行影像擷取。
資訊
本主題中的所有資訊均適用於所有 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#
在命令列中,執行以下指令:
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 產生器的路徑。
在範例程式碼中,請搜尋以下內容的出現位置: /opt/pylon/lib/gentlproducer/gtl 並調整路徑。
使用 Harvester 存取 Blaze 攝影機#
請依照以下步驟,使用 Harvester 搜尋所有可用的 Blaze 攝影機:
- 匯入 Harvester 模組。
- 建立一個 Harvester 物件。
-
載入 Blaze 攝影機的 GenTL 產生器。
-
更新可用裝置清單。
- 取得有關可用裝置的資訊。
若要連接攝影機,請使用 h.create() 函式。
以下指令會連線至第一個可用的 Blaze 攝影機:
若要開啟特定的攝影機,您可以透過由 device_info_list Harvester 類別物件的屬性。
範例:
請注意,這些指定條件必須能唯一識別您要開啟的裝置。若有多台攝影機符合條件,則無法開啟任何裝置。
若要與相機斷開連線,請執行以下指令:
存取相機參數#
可透過影像擷取器的 remote_device 屬性。遠端裝置的 node_map 此屬性可讓您存取所有相機參數。
範例:
# Get a parameter.
operatingMode = ia.remote_device.node_map.OperatingMode.value
# Set a parameter.
ia.remote_device.node_map.OperatingMode.value = 'ShortRange'
若要取得所有可用相機參數的清單,請使用以下指令:
請參閱SimpleGrab 範例,以了解更多關於如何設定及取得 Blaze 攝影機參數的範例。
資料蒐集#
資訊
由於 Harvester 不支援GenICam GenDC 串流格式,因此在擷取資料之前,您必須先停用GenDC 串流格式。要停用GenDC 串流格式,請使用以下指令:
從火焰攝影機擷取的緩衝區可能包含多個組成部分。其中包括「範圍」、「強度」和「可信度」這三個組成部分。
以下程式碼片段會啟用所有可用的元件,並設定 Range 元件的像素格式,使深度資料以點雲形式呈現。在點雲中,每個感測器像素都會被賦予一組 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"
若您想使用深度圖而非點雲,請依下列方式設定「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 陳述式,並會在您離開作用域時被銷毀。若您想在 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 元件的像素格式。如果像素格式等於 Coord3D_ABC32f, Range 元件以點雲的形式呈現,也就是說,每個像素都有 3 個浮點數值。結果是一個三維陣列,用來儲存每個像素的 x、y 和 z 座標。
若像素格式等於 Coord3D_C16, 「範圍」元件以 16 位元灰階影像的形式呈現,也就是說,每個像素對應一個 16 位元整數值。
有關如何將深度圖的灰階值轉換為毫米的詳細資訊,請參閱「處理測量結果」一節。
完成資料擷取後,請呼叫 stop() 函數:
除了如上所述實作抓取迴圈外,Harvester 還能提供一個背景執行緒,該執行緒負責實作抓取迴圈,並透過發出回呼來通知應用程式。此方法在SimpleGrab_Callback 範例中有所說明。
應用程式除錯與 GigE Vision 心跳訊號的控制#
像 blaze 相機這樣的 GigE Vision 相機,需要應用程式透過定期向相機發送特殊的網路封包,來定期存取相機。如果相機未收到這些心跳訊號,它會將連線視為中斷,並不再接受來自應用程式的任何指令。
當您執行應用程式時,Blaze 攝影機的 GenTL 產生器通常會產生這些心跳訊號。若您在應用程式中設定了中斷點,且該中斷點被觸發,除錯器將會暫停所有執行緒,包括負責傳送心跳訊號的執行緒。 因此,當您在除錯應用程式並以單步執行程式碼時,系統將不會向攝影機傳送心跳訊號。結果,攝影機會偵測到心跳超時,並關閉連線。心跳超時的預設值為 3000 毫秒。
為了解決這個問題,您必須在開發期間延長心跳超時時間。您可以透過設定一個名為 GEV_HEARTBEAT_TIMEOUT 並指定所需的超時時間(以毫秒為單位)。
此外,您也可以在應用程式中像這樣設定心跳超時:
資訊
若您將心跳超時設定為較高數值,並在未正確關閉裝置的情況下停止應用程式,您將無法再次開啟相機,且會收到錯誤訊息,指出裝置目前正在使用中。此情況可能發生於您使用除錯器停止應用程式,或應用程式意外終止時。若要再次開啟相機,您必須等待超時結束,或將網路線從相機上拔除。