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

Python程式設計指南#

本主題提供有關 Basler blaze 及 Smart blaze 攝影機的具體資訊,並非旨在對 pypylon 進行全面概述。

Basler pylon 的官方 Python 語言綁定是pypylon專案。pypylon 是一個託管於 GitHub 上的開源專案。若要使用 Basler 3D 攝影機,必須使用 4.0 版或更高版本。

除了官方的 Python 封裝函式外,亦可透過 PythonHarvester函式庫來操作相機。Harvester 是一個 Python 函式庫,旨在簡化電腦視覺應用中的影像擷取流程。它能透過 GenTL Producers 進行影像擷取。

資訊

本主題中的所有資訊均適用於所有 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#

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

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 產生器的路徑。

在範例程式碼中,請搜尋以下內容的出現位置: /opt/pylon/lib/gentlproducer/gtl 並調整路徑。

使用 Harvester 存取 Blaze 攝影機#

請依照以下步驟,使用 Harvester 搜尋所有可用的 Blaze 攝影機:

  1. 匯入 Harvester 模組。
    from harvesters.core import Harvester
    
  2. 建立一個 Harvester 物件。
    h = Harvester()
    
  3. 載入 Blaze 攝影機的 GenTL 產生器。

    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)

若要開啟特定的攝影機,您可以透過由 device_info_list Harvester 類別物件的屬性。

範例:

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

請注意,這些指定條件必須能唯一識別您要開啟的裝置。若有多台攝影機符合條件,則無法開啟任何裝置。

若要與相機斷開連線,請執行以下指令:

ia.destroy()

存取相機參數#

可透過影像擷取器的 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'

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

dir(ia.remote_device.node_map)

請參閱SimpleGrab 範例,以了解更多關於如何設定及取得 Blaze 攝影機參數的範例。

資料蒐集#

資訊

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

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

從火焰攝影機擷取的緩衝區可能包含多個組成部分。其中包括「範圍」、「強度」和「可信度」這三個組成部分。

以下程式碼片段會啟用所有可用的元件,並設定 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() 函數:

ia.start()

一個典型的抓取迴圈看起來像這樣:

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

資訊

緩衝區僅在 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() 函數:

ia.stop()

除了如上所述實作抓取迴圈外,Harvester 還能提供一個背景執行緒,該執行緒負責實作抓取迴圈,並透過發出回呼來通知應用程式。此方法在SimpleGrab_Callback 範例中有所說明。

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

像 blaze 相機這樣的 GigE Vision 相機,需要應用程式透過定期向相機發送特殊的網路封包,來定期存取相機。如果相機未收到這些心跳訊號,它會將連線視為中斷,並不再接受來自應用程式的任何指令。

當您執行應用程式時,Blaze 攝影機的 GenTL 產生器通常會產生這些心跳訊號。若您在應用程式中設定了中斷點,且該中斷點被觸發,除錯器將會暫停所有執行緒,包括負責傳送心跳訊號的執行緒。 因此,當您在除錯應用程式並以單步執行程式碼時,系統將不會向攝影機傳送心跳訊號。結果,攝影機會偵測到心跳超時,並關閉連線。心跳超時的預設值為 3000 毫秒。

為了解決這個問題,您必須在開發期間延長心跳超時時間。您可以透過設定一個名為 GEV_HEARTBEAT_TIMEOUT 並指定所需的超時時間(以毫秒為單位)。

此外,您也可以在應用程式中像這樣設定心跳超時:

ia.device.node_map.HeartbeatTimeout.value=600000

資訊

若您將心跳超時設定為較高數值,並在未正確關閉裝置的情況下停止應用程式,您將無法再次開啟相機,且會收到錯誤訊息,指出裝置目前正在使用中。此情況可能發生於您使用除錯器停止應用程式,或應用程式意外終止時。若要再次開啟相機,您必須等待超時結束,或將網路線從相機上拔除。