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

Python程式設計人員指南#

本主題提供針對 Basler blaze 和 Smart blaze 相機的專屬資訊,並未旨在提供 pypylon 的完整概覽。

Basler pylon 的官方 Python 語言繫結為 pypylon 專案。pypylon 是託管於 GitHub 上的開源專案。若要使用 Basler 3D 相機,必須使用 4.0 或更高版本。

作為官方 Python 包裝函式的替代方案,您可以透過 Python Harvester 函式庫來操作相機。Harvesters 是一個 Python 函式庫,旨在簡化電腦視覺應用程式中的影像擷取程序。它可透過 GenTL Producer 進行影像擷取。

資訊

本主題中的所有資訊均適用於所有 blaze 和 Smart blaze 相機型號。為求簡潔,文中以「blaze」統稱所有型號。

pypylon#

安裝 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#

在命令列中執行以下指令:

pip3 install harvesters

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 相機:

  1. 匯入 Harvester 模組。
    from harvesters.core import Harvester
    
  2. 將 Harvester 物件執行個체化。
    h = Harvester()
    
  3. 載入適用於 blaze 相機的 GenTL Producer。

    h.add_file(r"C:\Program Files\Basler\pylon\Runtime\x64\ProducerBaslerBlazePylon.cti")
    
    h.add_file("/opt/pylon/lib/gentlproducer/gtl/ProducerBaslerBlazePylon.cti")
    
  4. 更新可用裝置清單。

    h.update()
    

  5. 取得可用裝置的相關資訊。
    h.device_info_list
    

若要連線至相機,請使用 h.create() 函式搭配使用。

下列敘述會連線至第一個可用的 blaze 相機:

ia = h.create(0)

若要開啟特定的相機,您可以使用透過以下方式提供的 Property 來指定: device_info_list Harvester 類別物件的 Property。

範例:

ia = h.create(serial_number='9032635')

請注意,指定名稱必須能唯一識別您要開啟的裝置。如果有多部相機符合條件,將無法開啟任何裝置。

若要中斷與相機的連線,請發出下列指令:

ia.destroy()

存取相機 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'

若要取得所有可用相機參數的清單,請使用下列指令:

dir(ia.remote_device.node_map)

如需有關如何設定和取得 blaze 相機參數的更多範例,請參閱 SimpleGrab sample。

擷取資料#

資訊

由於 Harvester 不支援 GenICam GenDC 串流格式,因此在擷取資料之前,您必須一律停用 GenDC 串流格式。若要停用 GenDC 串流格式,請使用下列指令:

ia.remote_device.node_map.GenDCStreamingMode.value = "Off"

從 blaze 相機擷取的 Buffer 可能包含多個元件。其中包含 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() 函式:

ia.start()

典型的擷取迴圈如下所示:

ia.start()
while True:
    with ia.fetch() as buffer:
        # Do something with the buffer.
ia.stop()

資訊

Buffer 僅在 with 敘述內有效,並將在您離開範圍時被摧毀。如果您想要在外部使用 Buffer 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 陣列。

為了便於後續處理,將一維陣列重新塑造(reshape)為二維或三維陣列可能會很方便:

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)的更多詳細資訊,請參閱Processing Measurement Results主題。

完成資料擷取後,請呼叫 stop() 函式:

ia.stop()

作為實作如上所示擷取迴圈的替代方案,Harvester 可以提供一個背景執行緒來實作擷取迴圈,並透過發出回呼(callback)來通知應用程式。SimpleGrab_Callbacksample中說明了這種方法。

偵錯應用程式與控制GigE Vision心跳訊號#

諸如 blaze 相機等 GigE Vision 相機要求應用程式透過定期傳送特殊的網路封包給相機,來定期存取相機。如果相機未收到這些心跳信號(heartbeats),它將認為連線已中斷,並不再接受來自應用程式的任何命令。

當你執行應用程式時,用於 blaze 相機的 GenTL Producer 通常會產生這些心跳信號。如果你在應用程式中設定了中斷點(breakpoint)且觸發了該中斷點,偵錯工具將暫停所有執行緒,包括負責傳送心跳信號的執行緒。因此,當你在對應用程式進行偵錯並在程式碼中進行單步執行時,將不會有心跳信號傳送給相機。結果,相機偵測到心跳逾時並關閉連線。心跳逾時的預設值為 3000 毫秒。

為了迴避此問題,你必須在開發期間增加心跳逾時時間。你可以透過設定名為 GEV_HEARTBEAT_TIMEOUT 的環境變數,並指定所需的逾時時間(以毫秒為單位)來做到這一點。

或者,你可以在應用程式中這樣設定心跳逾時時間:

ia.device.node_map.HeartbeatTimeout.value=600000

資訊

如果你將心跳逾時時間增加到一個很大的數值,並在未正確關閉裝置的情況下停止應用程式,你將無法再次開啟相機,並且會收到一則指出該裝置目前正在使用的錯誤訊息。如果你使用偵錯工具停止應用程式,或者你的應用程式非預期終止,就可能會發生這種情況。若要再次開啟相機,你必須等待逾時時間過期,或者拔除相機的網路線。