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

C++程式設計指南#

本主題提供有關 Basler blaze 及 Smart blaze 攝影機的特定資訊,並非旨在對 pylon C++ API 進行全面概述。

如果您是初次接觸 pylon,Basler 建議您先閱讀《pylon C++ 程式設計師指南》中的「入門」章節,以熟悉 pylonC++ API。

資訊

本主題中的所有資訊均適用於所有 blaze 及 Smart blaze 攝影機型號。為簡明起見,此處以「blaze」統稱所有型號。

C++ 程式設計範例#

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 C++ programming samples are located in the cpp folder.

The C++ samples are located in the /opt/pylon/share/pylon/Samples/blaze/cpp folder.

建置範例的先決條件#

  • CMake 3.3 or above
  • Optional: Aravis

On an Ubuntu system, you can install the prerequisites by issuing the following command:

    sudo apt -y install build-essential cmake libopencv-dev libpcl-dev libboost-all-dev

Info

There is no Debian package available for the Aravis library. Aravis must be built from sources instead.

如何建置範例程式#

資訊

在建置範例之前,請將包含範例的資料夾複製到您自選的、且您具有讀寫權限的位置。

CMake 被用作編譯 C++ 範例的建置系統。

Windows#

  1. Start Visual Studio.
  2. On the start page, choose the Open Folder or Open a local folder option, and navigate to the folder you copied the samples to.
  3. Open the cpp subfolder and click the Select Folder button.

Visual Studio runs CMake in the background. It will take a moment until you can build the samples by selecting Build All in the Build menu.

When you don't want to use Visual Studio's CMake integration, you can use the cmake-gui tool to generate Visual Studio solution and project files that you can open with Visual Studio.

If there is no CMake >= 3.3 installed, download a CMake Windows installer from the CMake website. Launch the .msi installer and follow the instructions.

To generate Visual Studio project and solution files for the blaze samples:

  1. Start cmake-gui.
  2. Click the Browse Source… button, and navigate to the folder you copied the samples to.
  3. Open the cpp folder by clicking the Select folder button.
  4. Specify a folder where the binaries will be built by clicking the Browse Build… button and choosing or creating a folder of your choice.
    Basler advises against choosing the root folder of the source tree, i.e., the folder this document is located in. Common practice is to create a subfolder (e.g., named build).
  5. Click the Configure button.
    A dialog opens.
  6. Choose the desired Visual Studio version and platform.
    Make sure that the selected platform (x86 or x64) matches the architecture that the OpenCV and PCL libraries are built for.
  7. Click the Finish button to close the dialog.
    The configuration procedure starts.
  8. Once the configuration procedure has succeeded, click the Generate button to create the Visual Studio project and solution files.
    The files will be generated in the build folder that you specified earlier.
  9. Navigate to that build folder and open the .sln file.

Now, you can build the samples by selecting Build All in the Build menu.

若在建置和執行範例時遇到問題,請參閱「疑難排解」主題。

Linux#

要建立範例,請開啟命令列視窗,導航至您複製範例的資料夾。接著,切換至cpp子資料夾,並執行以下指令:

mkdir build
cd build
cmake ..
make -j$(nproc)

如果 CMake 無法找到 pylon SDK,請檢查 pylon SDK 和pylon Supplementary Package for blaze 是否已正確安裝。

若您將軟體安裝在/opt/pylon 以外的位置,請確保環境變數 PYLON_ROOT 已設定為您安裝 pylon 及補充套件的資料夾。

範例:

PYLON_ROOT=$HOME/pylon cmake ..

如果 CMake 無法找到 OpenCV 函式庫或 PCL,請確認已安裝 OpenCV 函式庫和 PCL 的開發套件。

若在建置和執行範例時遇到問題,請參閱「疑難排解」主題。

安裝 OpenCV 函式庫#

Windows#

您可以從GitHub 下載 OpenCV。

請務必下載與您即將使用的 Visual Studio 版本相容的 OpenCV 函式庫版本。若沒有合適的預編譯版本可用,您必須使用您打算用於編譯應用程式的 Visual Studio 版本,從原始碼編譯 OpenCV。

如果 CMake 無法找到 OpenCV,請將 OpenCV_DIR 變數設定為包含OpenCVConfig.cmake檔案的資料夾。

範例

  1. Open the CMakeSettings.json file (CMake -> Change CMake Settings -> blazeCppSamples).
  2. Add the following to the cmakeCommandArgs list:
    -DOpenCV_DIR=\"C:\\Program Files\\OpenCV\\build\\x64\\vc16\\lib\"
  "configurations": [
    {
      "name": "x64-Debug",
      ...
      "cmakeCommandArgs": "-DOpenCV_DIR=\"C:\\Program Files\\OpenCV\\build\\x64\\vc16\\lib\"",
      ...
    },
    {
      "name": "x64-Release",
      ...
      "cmakeCommandArgs": "-DOpenCV_DIR=\"C:\\Program Files\\OpenCV\\build\\x64\\vc16\\lib\"",
      ...
    }
  ]
  1. Open the CMake Settings dialog (Project -> CMakeSettings for blazeCppSamples).
  2. Enter the following in the CMake command arguments field:
    -DOpenCV_DIR="C:\Program Files\OpenCV\build\x64\vc16\lib"
  3. Press Ctrl S to save the changes.

Before you can access the OpenCV_DIR in the CMake GUI, make sure that the Grouped check box is deselected in the CMake GUI.

cmake -DOpenCV_DIR="C:\Program Files\OpenCV\build\x64\vc16\lib" ..
將 OpenCV 加入 PATH 環境變數#

您必須加入 OpenCV bin 目錄至 PATH 環境變數。

  1. 按下 Win 鍵。
  2. 請輸入「environment」。
  3. 請點選「編輯您的帳戶環境變數」。
  4. 按下「環境變數…」按鈕。
  5. 在「使用者變數」區域中,選取「路徑」。
  6. 點擊「編輯」按鈕。
  7. 點擊「新增」。
  8. 請輸入您的 OpenCV 安裝路徑,例如:C:\Program Files\OpenCV\build\x64\vc16\bin。
  9. 按一下 OK。

Linux#

如果 CMake 無法找到 OpenCV 函式庫,您必須安裝 libopencv 開發套件,或是從原始碼編譯 OpenCV 函式庫。

在 Ubuntu 系統上,可透過執行以下指令來安裝 libopencv 開發套件:

sudo apt-get -y install libopencv-dev

當您從原始碼編譯 OpenCV 函式庫,並將其安裝至非標準位置時,該 OpenCV_DIR CMake 變數可用於指定 OpenCVConfig.cmake 檔案所在的位置。

範例:

cmake -DOPENCV_DIR=$HOME/OpenCV/lib ..

安裝點雲函式庫#

Windows#

您可以從GitHub 下載適用於Windows 的 PCL 整合安裝程式。

請務必下載與您即將使用的 Visual Studio 版本相容的 PCL 版本。

如果 CMake 無法找到 PCL,請設定 PCL_DIR 將變數設定為包含該檔案的資料夾 PCLConfig.cmake 檔案。

範例

  1. Open the CMakeSettings.json file (CMake -> Change CMake Settings -> blazeCppSamples)
  2. Add the following to the cmakeCommandArgs list:
    -DPCL_DIR=\"C:\\Program Files\\PCL 1.9.1\\cmake\"
  "configurations": [
    {
      "name": "x64-Debug",
      ...
      "cmakeCommandArgs": "-DPCL_DIR=\"C:\\Program Files\\PCL 1.9.1\\cmake\"",
      ...
    },
    {
      "name": "x64-Release",
      ...
      "cmakeCommandArgs": "-DPCL_DIR=\"C:\\Program Files\\PCL 1.9.1\\cmake\"",
      ...
    }
  ]
  1. Open the CMake Settings dialog (Project -> CMakeSettings for blazeCppSamples).
  2. Enter the following in the CMake command arguments field:
    -DPCL_DIR="C:\Program Files\PCL 1.12.1\cmake"
  3. Press Ctrl S to save the changes.
  1. Open the CMake Settings dialog (Project -> CMakeSettings for blazeCppSamples).
  2. Enter the following in the CMake command arguments field:
    -DPCL_DIR="C:\Program Files\PCL 1.14.0\cmake"
  3. Press Ctrl S to save the changes.

Before you can access the PCL_DIR in the CMake GUI, make sure that the Grouped check box is deselected in the CMake GUI.

cmake -DPCL_DIR="C:\Program Files\PCL 1.14.0\cmake" ..

當使用 PCL 整合安裝程式安裝 PCL 時,安裝程式會自動處理 PCL 的新增作業 bin 目錄至 PATH 環境變數。若您使用的是其他安裝方式,則必須新增 bin 目錄至 PATH 請自行設定環境變數。

PCL 一体化安裝程式會安裝 OpenNI2.dll 進入 %ProgramFiles%\OpenNI2\Redist 資料夾。執行時必須有「DLL 」資料夾。請將此資料夾新增至您的 PATH 環境變數,或複製該 OpenNI2.dll 前往存放 PCL 二進位檔的資料夾,例如: %ProgamFiles%\PCL 1.13.0\bin.

Linux#

如果 CMake 無法找到 PCL 函式庫,您必須安裝libpcl開發套件,或是從原始碼編譯 PCL 函式庫。

在 Ubuntu 系統上,可透過執行以下指令來安裝libpcl開發套件:

sudo apt-get -y install libpcl-dev

當您從原始碼編譯 PCL 並將其安裝至非標準位置時,該 PCL_DIR CMake 變數可用於指定 PCLConfig.cmake 檔案所在的位置。

範例:

cmake -DPCL_DIR=$HOME/PCL/cmake ..

注意

使用 Point Cloud Library (PCL) 的範例程式可能會發生當機,具體情況取決於您系統上安裝的 PCL 和 VTK 函式庫版本。此當機問題源於 VTK 函式庫中的錯誤,而 PCL 會使用該函式庫進行 3D 可視化。
來源:https://github.com/PointCloudLibrary/pcl/issues/5237
解決方案:PCL 1.13.1 已包含修復程式,可繞過該 VTK 錯誤。
請將 PCL 更新至 1.13.1 或更高版本。如有需要,請卸載Linux 發行版所提供的 PCL 函式庫,並從原始碼(可從GitHub 取得)編譯 PCL 1.13.1 或更高版本。

安裝 Boost 函式庫#

Windows#

如果您已從原始碼編譯 Point Cloud Library (PCL),或是依照上述說明使用「全功能安裝程式」進行安裝,那麼用於編譯 PCL 的 Boost 函式庫,也將自動用於編譯 blaze 範例程式。

如果沒有可用的 PCL 函式庫,但您仍想編譯需要 Boost 函式庫的 Blaze 範例程式,您必須從原始碼編譯 Boost 函式庫,或安裝這些函式庫(例如,使用可從sourceforge.net 下載的預編譯二進位檔)。請下載適合您所使用的 Visual Studio 版本,以及您要為其編譯應用程式的架構的安裝程式。

如果 CMake 無法偵測到已安裝的 Boost 函式庫,您必須設定 Boost_DIR CMake 變數。該變數必須指向包含該 BoostConfig.cmake 檔案。

範例

  1. Open the CMakeSettings.json file (CMake -> Change CMake Settings -> blazeCppSamples).
  2. Add the following to the cmakeCommandArgs list:
    -DBoost_DIR=\"C:\\local\\boost_1_84_0\\lib64-msvc-14.1\\cmake\\Boost-1.84.0\"
  "configurations": [
    {
      "name": "x64-Debug",
      ...
      "cmakeCommandArgs": "-DBoost_DIR=\"C:\\local\\boost_1_84_0\\lib64-msvc-14.1\\cmake\\Boost-1.84.0\"",
      ...
    },
    {
      "name": "x64-Release",
      ...
      "cmakeCommandArgs": "-DBoost_DIR=\"C:\\local\\boost_1_84_0\\lib64-msvc-14.1\\cmake\\Boost-1.84.0\"",
      ...
    }
  ]
  1. Open the CMake Settings dialog (Project -> CMakeSettings for blazeCppSamples).
  2. Enter the following in the CMake command arguments field:
    -DBoost_DIR="C:\local\boost_1_84_0\lib64-msvc-14.2\cmake\Boost-1.84.0"
  3. Press Ctrl S to save the changes.
  1. Open the CMake Settings dialog (Project -> CMakeSettings for blazeCppSamples).
  2. Enter the following in the CMake command arguments field:
    -DBoost_DIR="C:\local\boost_1_84_0\lib64-msvc-14.3\cmake\Boost-1.84.0"
  3. Press Ctrl S to save the changes.

Before you can access the Boost_DIR in the CMake GUI, make sure that the Advanced check box is selected and the Grouped check box is deselected in the CMake GUI.

cmake -DOpenCV_DIR="C:\Program Files\OpenCV\build\x64\vc16\lib" ..

Linux#

如果 CMake 無法找到 Boost 函式庫,您必須安裝libboost開發套件,或是從原始碼編譯 Boost 函式庫。

在 Ubuntu 系統上,可透過執行以下指令來安裝libboost開發套件:

sudo apt-get -y install libboost-dev

樣本清單#

  • FirstSample: 本指南介紹如何操作 Blaze 攝影機,並著重說明如何擷取 3D 點雲資料。請參閱以下 pylon C++ 範例套件中的範例,以進一步了解如何使用 pylon 實作擷取迴圈的各種方法:
    • Grab_Strategies
    • Grab_UsingBufferFactory
    • Grab_UsingGrabLoopThread
  • ParametrizeCamera:說明如何存取相機參數。
  • DeviceRemovalHandling:說明如何偵測及處理裝置的移除。
  • GrabDepthMap:說明如何擷取並解讀深度圖,這些深度圖以灰階影像的形式呈現 3D 資訊。
  • ConvertPointCloud2DepthMap:若您希望同時處理 3D 點雲與深度圖,請參閱此範例,該範例說明了如何從 3D 點雲中擷取深度圖。此範例同時也示範了如何對深度圖套用彩虹色映射。
  • ShowPointCloud_PCL:說明如何利用點雲函式庫(PCL)來視覺化透過 Basler blaze 相機擷取的點雲。
  • ConvertAndFilter_PCL:與ShowPointCloud 類似。說明如何對 3D 點雲套用 PCL 濾波器。
  • SavePointCloud:說明 GrabSingleImage 便利方法,以及如何將點雲儲存至.pcd文字檔案。
  • SaveAndLoadPointCloudUsingPCL:說明如何利用 PCL 更有效地將點雲儲存至檔案。此範例同時展示如何從檔案載入點雲。
  • FeatureDumper:列出所有相機參數及其屬性。此範例用以展示如何使用 GenApi 的進階應用。
  • 畸變校正:說明如何停用畸變校正功能,以便使用您自己的校準資料。
  • 外變換:說明如何在點雲中偵測主平面,以及如何計算外變換並將其傳遞給相機。
  • MultiCam/ColorAndDepth/ColorAndDepthPtp:說明如何同時從 Basler blaze 和 Basler GigE 彩色攝影機擷取影像,以及如何存取影像與深度資料。這兩台攝影機是透過PTP 及Synchronous Free Run 功能進行同步的。
  • MultiCam/ColorAndDepth/Calibration:說明如何對由 Basler GigE 彩色相機和 Basler blaze 相機組成的系統進行校準。
  • MultiCam/ColorAndDepth/ColorAndDepthFusion:說明如何將 Basler GigE 彩色相機與 Basler blaze 的資料融合成彩色點雲。
  • MultiCam/ColorAndDepth/RgbdCamera: 類似於 色彩與深度融合, 此範例說明如何將 Basler Blaze 與 Basler GigE 彩色攝影機的資料融合成彩色點雲。此範例採用 RgbdCamera 此類別可將 2D 彩色攝影機與 Blaze 結合,並將這兩台攝影機整合為單一的 RGB-D 攝影機。透過「PTP 」(IEEE 1588)及「Synchronous Free Run 」功能,可同步觸發這兩台整合後的攝影機。該的原始碼為 RgbdCamera 該類別位於同一個資料夾中。若要在您自己的應用程式中使用 RgbdCamera 類別,請將 RgbdCamera.h 和 RgbdCamera.cpp 檔案加入您的專案中。此外,您還必須將 Multicam/MultiCamHelper 資料夾中的 .h 和 .cpp 檔案一併加入。
  • MultiCam/DepthFusion/校準:說明如何對由多台 Basler blaze 相機組成的系統進行校準。
  • MultiCam/DepthFusion/DepthFusion:說明如何將深度資料進行合併,以顯示由任意數量相機所產生的融合點雲。
  • MultiCam/MultiChannel/MultiChannelFreeRun:說明如何同時操作多台 Blaze 攝影機,同時確保其光源不會相互干擾。這些攝影機均以自由運行模式運作。
  • MultiCam/MultiChannel/MultiChannelSwTrigger:說明如何同時操作多台 Blaze 攝影機,同時確保其光源不會相互干擾。這些攝影機是透過軟體觸發器來觸發的。
  • MultiCam/SynchronousFreeRun/SynchronousFreeRun:說明如何利用PTP 時鐘同步功能以及Synchronous Free Run 功能,讓多台Blaze相機同時運作,同時避免其光源相互干擾。
  • MultiCam/MultiCamHelper:一個提供便利類別的函式庫,可透過PTP (IEEE1588)輕鬆同步多台攝影機的時鐘,並同步擷取多台攝影機的影像。所有使用「Synchronous Free Run 」功能從多台攝影機擷取影像的範例程式,均採用此函式庫。若要將此函式庫加入您的專案,只需將此資料夾中的.h和.cpp檔案加入您的專案即可。
  • Aravis/BasicSample:(僅限Linux )示範如何使用開源的 Aravis 函式庫來設定 Blaze 攝影機並從中擷取資料。
  • Aravis/PointCloudSample:(僅限Linux )說明如何根據使用 Aravis 函式庫所取得的資料,計算 3D 座標(即點雲)。此範例同時說明如何使用 OpenCV 儲存及視覺化點雲。

如何開發應用程式#

Windows#

使用 Visual Studio 解決方案#

Refer to the Common Settings for Building Applications with pylon section of the pylon C++ Programmer's Guide to learn how to set up a project for building applications using pylon.

Refer to the Common Settings for Building Applications with pylon section of the pylon C++ Programmer's Guide to learn how to set up a project for building applications using pylon.

使用 CMake#

pylon Supplementary Package for blaze 包含一個 Findpylon.cmake 用於確定 pylon 安裝位置的模組,以及pylon Supplementary Package for blaze 。find 模組導出 pylon::pylon CMake 目標。將此目標作為參數傳遞給 target_link_libraries, 而 CMake 會自動處理包含路徑、函式庫路徑等設定。

一個基本的 CMakeLists.txt CMake 檔案可能如下所示:

project (hello)

# Locate the CMake find module for pylon ...
# for Unix system. All other OS PYLON_ROOT will be empty
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_ROOT})
# for Windows system. All other OS PYLON_DEV_DIR will be empty
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_DEV_DIR})

find_package(pylon 7.1 REQUIRED)

add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)
project (hello)

# Locate the CMake find module for pylon ...
find_path(pylon_cmake Findpylon.cmake
    HINTS "$ENV{PYLON_DEV_DIR}/lib/cmake"
          "$ENV{ProgramFiles}/Basler/pylon 7/Development/lib/cmake"
          "$ENV{ProgramFiles}/Basler/pylon 6/Development/lib/cmake"
)
# ... and extend the CMake module path accordingly.
list(APPEND CMAKE_MODULE_PATH ${pylon_cmake})
# Locate pylon.
find_package(pylon 6.2 REQUIRED)

add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)

Linux#

使用 CMake#

project (hello)

# Locate the CMake find module for pylon ...
# for Unix system. All other OS PYLON_ROOT will be empty
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_ROOT})
# for Windows system. All other OS PYLON_DEV_DIR will be empty
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_DEV_DIR})

find_package(pylon 7.1 REQUIRED)

add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)
project (hello)

# Locate the CMake find module for pylon ...
find_path(pylon_cmake Findpylon.cmake
    HINTS "/opt/pylon/lib/cmake"
)
# ... and extend the CMake module path accordingly.
list(APPEND CMAKE_MODULE_PATH ${pylon_cmake})
# Locate pylon.
find_package(pylon 6.2 REQUIRED)

add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)

使用 Make 檔案#

請參閱《pylon C++ 程式設計師指南》中「使用 pylon 建置應用程式的常見設定」一節,以了解如何調整編譯器和連結器的設定,以便使用 pylon 建置應用程式。

blaze 相機的即時相機類別#

pylon 提供了不同類型的類別,用於存取攝影機裝置。除了低階的 IPylon 裝置方面,有所謂的 Instant Camera 這些類別為相機提供了便利的高階 API。

當 Pylon::CInstantCamera 此類別提供對所有 Basler 攝影機(包括 blaze 系列攝影機)的通用存取功能。

當 Pylon::CBaslerUniversalInstantCamera 類別延伸了泛型 Pylon::CInstantCamera 透過參數存取器物件來定義類別,讓使用者能輕鬆地透過 IntelliSense/程式碼自動完成功能來設定和取得相機參數。

當 Pylon::CBaslerUniversalInstantCamera 該類別並未針對每個 Blaze 攝影機功能提供參數存取器。因此,pylon Supplementary Package for blaze 包含 Pylon::CBlazeInstantCamera 類別。Basler 建議改為搭配 Basler blaze 攝影機使用該類別。

如果您選擇 CBaslerUniversalInstantCamera 類別,而不是 CBlazeInstantCamera 類別中,您仍然可以設定和取得 Blaze 相機所提供的所有相機參數。如果該類別未提供存取器物件,則 CBaslerUniversalInstantCamera 類別,請使用所謂的 泛型參數存取 如前所述,若要依據參數名稱存取參數,請參閱 泛型參數存取 該部分的 pylon C++ 程式設計師指南.

範例:

using namespace Pylon;
GenApi::INodeMap& nodemap = camera.GetNodeMap();
CIntegerParameter filterStrength(nodemap, "FilterStrength" );
std::cout << "Filter strength: " << filterStrength.GetValue() << std::endl;

開啟並存取 Blaze 攝影機#

建立並開啟一個 blaze 攝影機物件需經過三個步驟:

  1. 為您要存取的攝影機建立一個攝影機物件。
    通常,您應該建立一個 Pylon::CBlazeInstantCamera 類別。
  2. 註冊與火災相關的 Pylon::CBlazeDefaultConfiguration 會套用預設設定的設定事件處理常式。
    請參閱 註冊相機配置處理常式 請參閱該節,以了解有關 Blaze 配置事件處理常式類別的更多詳細資訊。
  3. 請致電 Open() 用於與攝影機裝置建立連線的方法。

以下範例說明這三個步驟:

#include <pylon/PylonIncludes.h>
using namespace Pylon;

// ....

// Before using any pylon methods, the pylon runtime must be initialized.
PylonInitialize();

try {
  // 1: Create a camera object for the first available blaze camera.
  CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice(
      CDeviceInfo().SetDeviceClass(BaslerGenTlBlazeDeviceClass))
  );

  // 2. Register the default configuration.
  camera.RegisterConfiguration(
    new CBlazeDefaultConfiguration,
    RegistrationMode_ReplaceAll,
    Cleanup_Delete);

  // 3. Open the camera, i.e., establish a connection to the camera device.
  camera.Open();

  // Use the camera.
  std::cout << "Connected to camera "
    << camera.GetDeviceInfo().GetFriendlyName() << std::endl;
  // .....

  // Close the connection.
  camera.Close();
} catch (const GenICam::GenericException& e) {
  std::cerr << "Exception occurred: " << std::endl
    << e.GetDescription() << std::endl;
}

// Releases all pylon resources.
PylonTerminate();

若發生錯誤,由 GenICam::GenericException 被拋出。

常見的錯誤狀況:

  • 未發現火災監視器:該 CreateFirstDevice() 該函式會拋出例外。
  • 無法開啟相機,例如因為它已被其他應用程式(如 Blaze Viewer)開啟:該 Open() 該方法會拋出一個例外。

以下各小節將提供更詳細的資訊,說明如何建立及開啟相機物件。

為第一個可用的 Blaze 攝影機建立攝影機物件#

請使用 Pylon::CTlFactory::CreateFristDevice() 用於建立第一個可用攝影機的攝影機物件的方法。您應始終為 Blaze 攝影機指定 pylon 裝置類別識別碼,以防止 CreateFirstDevice() 從為可能連接至您的系統或可透過網路存取的另一種相機類型建立相機類別開始:

CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice(
    CDeviceInfo().SetDeviceClass(BaslerGenTlBlazeDeviceClass)));
);

若找不到 Blaze 攝影機,請檢查攝影機及您的網路介面卡的 IP 設定。有關設定網路的更多資訊,請參閱「網路設定」一節。

為特定的 Blaze 攝影機建立攝影機物件#

《pylon C++ 程式設計師指南》中「進階主題」一章的「建立特定攝影機」節,提供了有關選擇特定攝影機的相關資訊。

若您想開啟特定的 Blaze 攝影機(例如透過指定其序號),除了將 Blaze 攝影機的 pylon 裝置類別識別碼傳遞給 CreateFirstDevice(), 您可以進一步指定其他屬性。

以下程式碼片段示範了如何根據序號開啟 Blaze 攝影機。

CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice(
  CDeviceInfo()
  .SetDeviceClass(BaslerGenTlBlazeDeviceClass)
  .SetSerialNumber("23298299")
));

若要以使用者自訂的名稱開啟 Blaze 攝影機,請使用以下指令:

CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice(
  CDeviceInfo()
  .SetDeviceClass(BaslerGenTlBlazeDeviceClass)
  .SetUserDefinedName("MyCamera")));

使用者自訂名稱

您可以使用 DeviceUserID 參數。您可以在 Blaze Viewer、PylonIP Configurator 或pylon API 中執行此操作:

camera.DeviceUserID.SetValue("MyCamera");

根據 IP 位址建立裝置

目前,您無法使用 CreateFirstDevice() 函式。原因在於目前該 Pylon::CDeviceInfo() 該類別中並未包含任何關於相機 IP 位址的資訊。

若要建立並開啟具有特定 IP 位址的攝影機,您必須先列出所有攝影機,遍歷回傳的清單,並逐一開啟各台攝影機,才能查詢其 IP 位址及其他網路相關資訊。此程序詳見「列出 blaze 攝影機」一節。

若找不到所需的 Blaze 攝影機,請檢查屬性值是否設定正確,並確認攝影機與網路介面卡的 IP 設定。有關網路設定的更多資訊,請參閱「網路設定」章節。

清點火災監控攝影機#

以下程式碼片段示範了如何擷取所有已連線的 Blaze 攝影機清單。針對清單中的每個元素,程式會開啟該攝影機,並輸出部分攝影機參數值。

#include <pylon/PylonIncludes.h>
#include <ostream>
using namespace Pylon;

// ....

// Before using any pylon methods, the pylon runtime must be initialized.
PylonInitialize();

// ....

// Enumerate all blaze cameras.
CTlFactory& TlFactory = CTlFactory::GetInstance();
DeviceInfoList_t lstDevices;
DeviceInfoList_t filter;
filter.push_back(CDeviceInfo().SetDeviceClass(BaslerGenTlBlazeDeviceClass));
TlFactory.EnumerateDevices(lstDevices, filter);
if (!lstDevices.empty()) {
    DeviceInfoList_t::const_iterator it;
    for (it = lstDevices.begin(); it != lstDevices.end(); ++it) {
        std::cout << it->GetFullName();

    // Open camera, i.e., establish a connection to the camera device.
    CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateDevice(*it));
    camera.RegisterConfiguration(
      new CBlazeDefaultConfiguration,
      RegistrationMode_ReplaceAll, Cleanup_Delete);
    camera.Open();

    // Print out some information.
    std::cout << "Connected to camera "
      << camera.GetDeviceInfo().GetFriendlyName() << std::endl;
    std::cout << "IP Address: "
      << camera.GevCurrentIPAddress.GetValue() << std::endl;
    std::cout << "User-defined name: "
      << camera.DeviceUserID.GetValue() << std::endl;
    std::cout << "Serial Number: "
      << camera.DeviceSerialNumber.GetValue() << std::endl;
}  // The connection will be closed automatically when leaving the scope here.
else {
    std::cerr << "No devices found!" << std::endl;
}

註冊相機配置處理常式#

pylon 即時攝影機類別允許您註冊配置事件處理常式物件,這些物件可用於在特定事件發生時套用攝影機設定,例如當 Open() 方法被呼叫。

pylon Supplementary Package for blaze 包含以下內容: Pylon::CBlazeDefaultConfiguration 類別。Basler 建議針對該類別的每個實例,都應註冊此設定。 CBlazeInstantCamera 您所建立的類別。

camera.RegisterConfiguration(
      new CBlazeDefaultConfiguration,
      RegistrationMode_ReplaceAll, Cleanup_Delete);

當 CBlazeDefaultConfiguration::OnOpened() 此方法會將資料流設定為包含深度、強度及置信度資訊。深度資訊以點雲形式傳送。每個點雲皆包含每個感測器像素的 3D 座標。該 CBlazeDefaultConfiguration::OnOpened() 此方法也會將攝影機切換至所謂的「自由運行模式」。在自由運行模式下,一旦開始擷取,攝影機便會持續傳輸資料,無需任何軟體或硬體觸發。

如果已註冊預設設定,則 CBlazeDefaultConfiguration::OnOpened() 該方法會由 CBlazeInstantCamera::Open().

當 CBlazeDefaultConfiguration 該類別是一個僅有標頭檔案的類別。您可以開啟 BlazeDefaultConfiguration.h 位於 Pylon SDK 的 includes 資料夾中的檔案:

  • Windows: %Program Files%\pylon\Development\include\pylon
  • Linux: /opt/pylon/include/pylon

您可以註冊多個配置事件處理常式類別。

以下範例說明如何註冊一個會套用額外設定的配置事件處理常式:

class MyConfigurationHandler : public CBlazeConfigurationEventHandler
{
public:
    // Sets exposure time to minimum possible value.
    void OnOpened(CBlazeInstantCamera& camera) override
    {
        camera.ExposureTime.SetToMinimum();
    }
};

// ....

// Register the default configuration first.
camera.RegisterConfiguration(
      new CBlazeDefaultConfiguration,
      RegistrationMode_ReplaceAll, Cleanup_Delete);

// Then, register additional configuration event handlers.
camera.RegisterConfiguration(
      new MyConfigurationHandler,
      RegistrationMode_Append, Cleanup_Delete);

// ....

camera.Open(); // Configurations will be applied.

有關 pylon 攝影機事件處理程式類別的更多資訊,請參閱《pylon C++ 程式設計師指南》中的「即時攝影機事件處理程式基礎」一節。

您無需透過提供設定事件處理常式來套用所需的設定。相反地,您可以在呼叫該方法之後的任何時候,設定您想要變更的參數。 CBlazeInstantCamera::Open() 方法。

有關如何設定及取得攝影機參數值的資訊,請參閱「存取參數」一節。

連接相機#

建立相機物件並註冊配置事件處理常式後,可透過呼叫 CBlazeInstantCamera::Open() 方法。

該連線將保持活躍,直到 CBlazeInstantCamera::Close() 方法被呼叫。的析構函式 CBlazeInstantCamera 自動撥打 Close() 如果尚未明確呼叫該函式。

若相機未定期收到來自應用程式的心跳請求,則會關閉連線。當應用程式當機或遭除錯器中斷時,便會發生心跳請求遺漏的情況。更多詳細資訊請參閱「除錯應用程式與控制 GigE Vision 心跳」一節。

存取參數#

請參閱《pylon C++ 程式設計師指南》中的「存取參數」一節,以熟悉如何使用 `pylon API` 存取攝影機參數。

pylon 的 C++ 範例 `Parametrize_NativeParameterAccess` 和 `Parametrize_GenericParameterAccess` 展示了使用 pylon 存取攝影機參數的典型方法。

以下程式碼範例說明如何使用 CBlazeInstantCamera 類別。

// Include files to use the pylon API
#include <pylon/PylonIncludes.h>
#include <pylon/BlazeInstantCamera.h>

// Namespaces for using the pylon API and the blaze camera parameters
using namespace Pylon;
using namespace BlazeCameraParams_Params;

// ...

// Set the operating mode of the camera. The choice you make here
// affects the working range of the camera, i.e., the Minimum Working
// Range and Maximum Working Range parameters.
OperatingModeEnums oldOperatingMode = camera.OperatingMode.GetValue();
camera.OperatingMode.SetValue(OperatingMode_LongRange);

// Exposure time of the camera. If the operating mode is changed, the
// exposure time is set to the recommended default value.
camera.ExposureTime.SetValue(750); // us

// Enable and configure image filtering.

// The spatial noise filter uses the values of neighboring pixels to
// filter out noise in an image.
camera.SpatialFilter.SetValue(true);

// The temporal noise filter uses the values of the same pixel at
// different points in time to filter out noise in an image.
camera.TemporalFilter.SetValue(true);
camera.TemporalFilterStrength.SetValue(220);

// The outlier removal removes pixels that differ significantly from
// their local environment.
camera.OutlierRemoval.SetValue(true);

// Some properties have restrictions.
// We use API functions that automatically perform value corrections.
// Alternatively, you can use GetInc() / GetMin() / GetMax() to make sure you
// set a valid value.
camera.ConfidenceThreshold.SetValue(321, IntegerValueCorrection_Nearest);

// Not all functions are available in older cameras.
// Therefore, we must use "Try" functions that only perform the action
// when parameters are writable. Otherwise, we would get an exception.
camera.MultiCameraChannel.TrySetValue(1);

std::cout << "Operating Mode           : "
    << camera.OperatingMode.GetValue() << std::endl;
std::cout << "Exposure Time            : "
    << camera.ExposureTime.GetValue() << std::endl;
std::cout << "Spatial Filter           : "
    << camera.SpatialFilter.GetValue() << std::endl;
std::cout << "Temporal Filter          : "
    << camera.TemporalFilter.GetValue() << std::endl;
std::cout << "Temporal Filter Strength : "
    << camera.TemporalFilterStrength.GetValue() << std::endl;
std::cout << "Outlier Removal          : "
    << camera.OutlierRemoval.GetValue() << std::endl;
std::cout << "Confidence Threshold     : "
    << camera.ConfidenceThreshold.GetValue() << std::endl;
if (camera.MultiCameraChannel.IsReadable())
    std::cout << "Multi-Camera Channel : "
    << camera.MultiCameraChannel.GetValue() << std::endl;

// Restore the old operating mode.
camera.OperatingMode.SetValue(oldOperatingMode);

// Close the camera.
camera.Close();

Blaze Viewer提供了一個「文件」窗格。當您在「功能」窗格中選取某個相機參數時,「文件」窗格便會顯示該參數的相關資訊,以及用來示範如何取得和設定該相機參數值的 C++ 與 C# 程式碼片段。

資料蒐集#

請參閱《pylon C++ 程式設計師指南》中「擷取影像」一節,以熟悉如何使用 `pylon API` 擷取資料。

pylon 將擷取的影像以名為 GrabResults 的資料結構來表示。由 2D 攝影機擷取的 GrabResults 包含單張灰階或彩色影像。

由 Blaze 攝影機擷取的 GrabResults 包含多個組件。預設情況下,每個 GrabResult 會儲存一張亮度影像、一張信心圖以及深度資訊。

根據「Range」元件所設定的像素格式,深度資料可呈現為 2D 深度圖或 3D 點雲。預設情況下,深度資料會以點雲形式呈現。

若要啟用深度圖,請將「範圍」元件的像素格式設定為 PixelFormat_Coord3D_16C:

// Enable depth maps by enabling the Range component and setting the
// appropriate pixel format.
camera.ComponentSelector.SetValue(ComponentSelector_Range);
camera.ComponentEnable.SetValue(true);
camera.PixelFormat.SetValue(PixelFormat_Coord3D_C16);

若要啟用點雲功能,請將「Range」元件的像素格式設定為 PixelFormat_Coord3D_ABC32f:

// Enable point clouds by enabling the Range component and setting the
// appropriate pixel format.
camera.ComponentSelector.SetValue(ComponentSelector_Range);
camera.ComponentEnable.SetValue(true);
camera.PixelFormat.SetValue(PixelFormat_Coord3D_ABC32f);

請參閱 Component Selector 以及 Pixel Format 相關主題以獲取更多詳細資訊。

資訊

無法讓相機同時以點雲和深度圖的形式傳送深度資訊。

「處理測量結果」主題說明了如何根據深度圖計算點雲。

此轉換方式亦展示於適用於 Blaze 攝影機的GrabDepthMap C++ 程式設計範例中。

如何從點雲中擷取深度圖,請參閱適用於 Blaze 攝影機的ConvertPointCloud2DepthMapC++ 程式設計範例。

抓環#

pylon 支援多種建立抓取迴圈的方法,並提供多種處理記憶體緩衝區的策略。

更多詳細資訊,請參閱《Pylon C++ 程式設計師指南》中的「擷取影像」章節。

以下程式碼片段展示了一個典型的擷取迴圈:

#include <pylon/PylonIncludes.h>
#include <pylon/BlazeInstantCamera.h>

using namespace Pylon;
using namespace BlazeCameraParams_Params;

// ....
PylonInitialize();

CBlazeInstantCamera camera(CTlFactory::GetInstance().CreateFirstDevice(
  CDeviceInfo().SetDeviceClass(BaslerGenTlBlazeDeviceClass)));
camera.RegisterConfiguration(
  new CBlazeDefaultConfiguration, RegistrationMode_ReplaceAll, Cleanup_Delete);
camera.Open();

size_t nBuffersGrabbed= 0;

// This smart pointer will receive the grab result data.
CGrabResultPtr ptrGrabResult;

camera.StartGrabbing();

while (camera.IsGrabbing() && nBuffersGrabbed < 10) {
  // Wait for an image and then retrieve it. A timeout of 1000 ms is used.
  camera.RetrieveResult(1000, ptrGrabResult, TimeoutHandling_ThrowException);

  // Data grabbed successfully?
  if (ptrGrabResult->GrabSucceeded()) {
      nBuffersGrabbed++;
      // Access the data.
      // ....
  } else {
    // Error handling
    std::cerr << "Grab error occurred: " << ptrGrabResult->GetErrorDescription() << std::endl;
  }
}
// Clean-up
camera.StopGrabbing();
camera.Close();

存取元件#

若要存取 GrabResult 的個別元件,您可以使用 Pylon::CPylonDataContainer 進行明確的生命週期管理即呼叫 Pylon::CPylonDataComponent 類別。一個容器可以包含一個或多個元件。您可以使用該容器查詢元件的數量,並擷取特定的元件。容器中的每個元件皆包含實際資料(例如深度值)及其元資料。

請使用 Pylon::CGrabResultData::GetDataContainer() 取得 GrabResult 的 CPylonDataContainer。使用 Pylon::CPylonDataContainer::GetDataComponent() 透過指定元件的索引來存取該元件的方法。

有關 pylon 如何提供存取包含多個組件的GrabResults 的相關資訊,請參閱《pylon C++ 程式設計師指南》中「進階主題」一章的「多組件 Grab 結果」節。

範例:

#pragma pack(push, 1)
struct Point
{
    float x;
    float y;
    float z;
};
#pragma pack(pop)

// ...

// By registering the CBlazeDefaultConfiguration, depth, intensity, and confidence data will be delivered.
// Depth data is represented as point clouds.
camera.RegisterConfiguration(new CBlazeDefaultConfiguration, RegistrationMode_ReplaceAll, Cleanup_Delete);
camera.Open();

//....

if (ptrGrabResult->GrabSucceeded())
{
  // Get access to the container.
  auto container = ptrGrabResult->GetDataContainer();

  // Access the container's components.
  // Iterate through all components in the container.
  for (size_t i = 0; i < container.GetDataComponentCount(); ++i)
  {
      // Get one component from the container.
      const Pylon::CPylonDataComponent component = container.GetDataComponent(i);
      if ( !component.IsValid() )
          continue;

      // Is this the intensity component?
      if ( component.GetComponentType() == Pylon::ComponentType_Intensity )
      {
          const Pylon::EPixelType pixelType = component.GetPixelType();

          // Get a pointer to the pixel data.
          const void* pPixels = component.GetData();

          // Process intensity values here (pixel data).
          // [...]
      }
  }

  auto rangeComponent = container.GetDataComponent(0);
  auto intensityComponent = container.GetDataComponent(1);
  auto confidenceComponent = container.GetDataComponent(2);

  // Retrieve the 3D coordinates corresponding to the center pixel.
  const auto width = rangeComponent.GetWidth();
  const auto height = rangeComponent.GetHeight();
  const uint32_t u = (int)(0.5 * width);
  const uint32_t v = (int)(0.5 * height);
  auto pPoint =
    reinterpret_cast<const Point*>(rangeComponent.GetData()) + u + v * width;
  uint16_t* pIntensity =
    (uint16_t*)intensityComponent.GetData() +  v * width + u;
  uint16_t* pConfidence
    = (uint16_t*)confidenceComponent.GetData() + v * width + u;
  if (pPoint->z != 0)
      std::cout << "x=" << pPoint->x
        << " y=" << pPoint->y
        << " z=" << pPoint->z << "\n";
  else
      std::cout << "x=   n/a y=   n/a z=   n/a\n";
  std::cout << " intensity=" << *pIntensity
            << " confidence=" << *pConfidence << "\n";
}
else
{
    // Error handling
    std::cerr << "Grab error occurred: " << ptrGrabResult->GetErrorDescription() << std::endl;
}

使用 ComponentSelector 進行明確的生命週期管理即呼叫 ComponentEnable 在相機參數中,您可以啟用或停用個別元件。對於 Blaze 相機,容器中元件的順序始終如下:

  • Range
  • 強度
  • 自信

舉例來說,如果「範圍」和「信心」元件已啟用,而「強度」元件已停用, container.GetDataComponent(0) 將取得 Range 元件並 container.GetDataComponent(1) 將回傳「Confidence」元件。若嘗試存取 container.GetDataComponent(2) 這將導致錯誤,因為在停用「強度」元件後,容器中僅剩兩個元件。

如果您的應用程式中負責處理抓取結果的那部分無法預先得知會收到哪些元件,您應選擇一種更通用的方式來存取這些元件,方法是透過遍歷容器,並使用 CPylonDataComponent::GetComponentType() 方法。

範例:

camera.RetrieveResult(1000, ptrGrabResult, TimeoutHandling_ThrowException);
// Data grabbed successfully?
if (ptrGrabResult->GrabSucceeded()) {
  // Access the data.
  auto container = ptrGrabResult->GetDataContainer();

  CPylonDataComponent rangeComponent;
  CPylonDataComponent intensityComponent;
  CPylonDataComponent confidenceComponent;

  // Iterate through all components in the container.
  for (size_t i = 0; i < container.GetDataComponentCount(); ++i) {
      const Pylon::CPylonDataComponent component = container.GetDataComponent(i);
      if (!component.IsValid())
          continue;
      switch (component.GetComponentType())
      {
      case ComponentType_Intensity:
          intensityComponent = component;
          break;
      case ComponentType_Confidence:
          confidenceComponent = component;
          break;
      case ComponentType_Range:
          rangeComponent = component;
          break;
      }
  }
  if (rangeComponent.IsValid()) {
    const auto width = rangeComponent.GetWidth();
    const auto height = rangeComponent.GetHeight();
    // Process depth data.
  }
  if (intensityComponent.IsValid()) {
    // Process intensity image.
  }
  if (confidenceComponent.IsValid())
  {
    // Process confidence data.
  }
}

深度資料的解讀#

「處理測量結果」主題提供了有關儲存於「Range」元件中的深度資料格式的相關資訊。

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

像 blaze 相機這樣的 GigE Vision 相機,需要應用程式定期與相機進行通訊,以便相機能檢查控制它的應用程式是否仍在運行。 因此,傳輸層會定期向攝影機發送網路請求(心跳訊號)。若攝影機在由其心跳超時設定所指定的時間內未接收到這些心跳訊號,便會視為連線中斷並關閉連線,也就是說,它將不再接受來自應用程式的任何指令。心跳超時的預設值為 3000 毫秒。

當您在除錯應用程式並觸發中斷點時,除錯器會暫停所有執行緒,包括傳送心跳訊號的執行緒。為了防止在應用程式暫停或單步執行程式碼時,相機關閉連線,傳輸層會自動延長心跳超時時間(若使用 pylon 7.1 或更高版本,則延長至 1 小時;否則延長至 5 分鐘)。 若您使用的是 pylon 7.1 或更高版本,當應用程式終止或發生當機時,與相機的連線會自動關閉。

使用 pylon 7.0 或更早版本時出現的重新連線問題

如果應用程式在尚未正確關閉與攝影機的連線前即遭終止或當機,攝影機將維持連線開啟狀態,直至心跳超時到期為止。在心跳超時到期之前,攝影機將拒絕任何進一步的連線嘗試。當您重新啟動應用程式,或啟動另一個要求存取攝影機的應用程式時,系統會顯示錯誤訊息,指出該裝置目前正在使用中。

這種情況通常發生在您使用除錯器停止應用程式,或應用程式意外終止時。若要再次開啟相機,您必須等待超時結束,或暫時將相機從網路中斷開連接。

要解決此問題,您可以透過設定名為 GEV_HEARTBEAT_TIMEOUT 設定為所需的超時時間(以毫秒為單位)。此外,您也可以依照以下示例所示,透過 `pylon API ` 在應用程式中設定心跳超時時間: DeviceRemovalHandling 範例程式。