C++程式設計人員指南#
如果您是 pylon 的新手,Basler 建議您先閱讀 pylon C++ Programmer's Guide 的 Getting Started 章節,以熟悉 pylon C++ API。
C++ Programming Samples#
The C++ samples are located in the C:\Program Files\Basler\pylon\Development\Samples\Stereo_ace\C++ folder.
The C++ samples are located in the /opt/pylon/share/pylon/Samples/Stereo_ace/C++/ folder.
The C++ samples are located in the /opt/pylon/share/pylon/Samples/Stereo_ace/C++/ folder.
建置範例的前置作業#
- pylon 26.06 或更新版本
- Visual Studio 2019 or above
- CMake 3.3 or above
- CMake 3.3 or above
- 選用:OpenCV 程式庫
- 選用:Point Cloud Library (PCL)
建構範例#
- Copy the Development\Samples\Stereo_ace\C++ folder to a location where you have write permissions.
- Launch Microsoft Visual Studio.
- Click the Open a local folder button, navigate to the Samples\Stereo_ace\C++ folder, and press the Select button.
Wait until Visual Studio has finished generating the CMake cache. Once the cache generation has succeeded, the samples can be built and executed.
Open a command shell and enter the following commands:
如果找不到 OpenCV 或 PCL,CMake 只會略過需要該缺失程式庫的範例。其他範例仍然可以建構。
如果在建構和執行範例時遇到問題,請查看 Troubleshooting 主題。
安裝 OpenCV Library#
You can download OpenCV here: https://github.com/opencv/opencv/releases
Make sure that you download a version of the OpenCV library that is compatible with the Visual Studio version you are going to use. If there is no suitable prebuilt version available, you have to build OpenCV from sources using the Visual Studio version you want to use for building your application.
If CMake fails to find OpenCV, set the OpenCV_DIR variable to the folder containing the OpenCVConfig.cmake file.
Examples
- Open the CMake Settings dialog (Project -> CMakeSettings for "Stereo ace samples")
- Enter the following command in the CMake command arguments field:
-DOpenCV_DIR="C:\Program Files\OpenCV\build\x64\vc16\lib" - 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.
Adding OpenCV to PATH Environment Variable#
You have to add the OpenCV bin directory to the PATH environment variable.
- Press the Win key.
- Type "environment".
- Click Edit environment variables for your account.
- In the User variables area, select Path.
- Click the Edit button.
- Click New.
- Enter the path of your OpenCV installation, e.g.:
C:\Program Files\OpenCV\build\x64\vc16\bin - Click OK.
If CMake fails to find the OpenCV library, you either have to install the libopencv development package or to build the OpenCV library from sources.
On Ubuntu systems, the libopencv development package can be installed by issuing the following command:
If you build the OpenCV library from sources and install it to a non-standard location, you can use the OpenCV_DIR CMake variable to specify the location where the OpenCVConfig.cmake files are located.
Example:
If CMake fails to find the OpenCV library, you either have to install the OpenCV development package or to build the OpenCV library from sources.
If you build the OpenCV library from sources and install it to a non-standard location, you can use the OpenCV_DIR CMake variable to specify the location where the OpenCVConfig.cmake files are located.
Example:
安裝 Point Cloud Library#
You can download the PCL All-in-one Installer for Windows here: https://github.com/PointCloudLibrary/pcl/releases
Make sure that you download a version of the PCL that is compatible with the Visual Studio version you are going to use.
If CMake fails to find the PCL, set the PCL_DIR variable to the folder containing the PCLConfig.cmake file.
Examples
- Open the CMakeSettings.json file (CMake -> Change CMake Settings -> "Stereo ace samples").
- Add
-DPCL_DIR=\"C:\\Program Files\\PCL 1.9.1\\cmake\"to thecmakeCommandArgslist:
- Open the CMake Settings dialog (Project -> CMakeSettings for "Stereo ace samples").
- Enter the following string in the CMake command arguments field:
-DPCL_DIR="C:\Program Files\PCL 1.14.0\cmake". - 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.

If the PCL is installed using the PCL All-in-one Installer, the installer takes care of adding the PCL bin directory to the PATH environment variable. If you're using a different installation method, you have to add the bin directory to the PATH environment variable yourself.
The PCL All-in-one Installer installs the OpenNI2.dll into the %ProgramFiles%\OpenNI2\Redist folder. The DLL is required at runtime. Either add this folder to your PATH environment variable, or copy the OpenNI2.dll to the folder the PCL binaries are located, e.g., %ProgamFiles%\PCL 1.13.0\bin.
If CMake fails to find the PCL library, you either have to install the libpcl development package or to build the PCL library from sources.
On Ubuntu systems, the libpcl development package can be installed by issuing the following command:
If you build the PCL from sources and install it to a non-standard location, the PCL_DIR CMake variable can be used to specify the location where the PCLConfig.cmake files is located.
Example:
Info
Samples using the Point Cloud Library (PCL) may crash depending on the versions of the PCL and VTK libraries installed on your system. The crash is due to a bug in the VTK libraries that are used by PCL for 3D visualization.
Source: https://github.com/PointCloudLibrary/pcl/issues/5237
Solution: PCL 1.13.1 contains fixes to work around the VTK bug.
Update to PCL 1.13.1 or higher. If required, uninstall the PCL libraries provided by your Linux distribution and build PCL version 1.13.1 or higher from sources (these can be retrieved from https://github.com/PointCloudLibrary/pcl).
If CMake fails to find the PCL library, you either have to install the PCL development package or to build the PCL library from sources.
If you build the PCL from sources and install it to a non-standard location, the PCL_DIR CMake variable can be used to specify the location where the PCLConfig.cmake files is located.
Example:
Info
Samples using the Point Cloud Library (PCL) may crash depending on the versions of the PCL and VTK libraries installed on your system. The crash is due to a bug in the VTK libraries that are used by PCL for 3D visualization.
Source: https://github.com/PointCloudLibrary/pcl/issues/5237
Solution: PCL 1.13.1 contains fixes to work around the VTK bug.
Update to PCL 1.13.1 or higher. If required, uninstall the PCL libraries provided by your Linux distribution and build PCL version 1.13.1 or higher from sources (these can be retrieved from https://github.com/PointCloudLibrary/pcl).
範例清單#
- FirstSample:介紹如何操作 Stereo ace 相機並擷取 3D 資料。
- ParametrizeCamera:說明如何存取相機參數。
- DeviceRemovalHandling:說明如何處理裝置移除。
- OpenDeviceByIpAddress: 示範如何透過其中一個 IP 位址開啟 Stereo ace 相機。
- GrabDepthMap:說明如何擷取與解讀深度圖。
- SavePointcloud:說明如何在不使用 OpenCV 的情況下將彩色點雲儲存至 .ply 檔案。
- SavePointcloudCV:說明如何使用 OpenCV 將強度影像、視差影像以及彩色點雲儲存至檔案。
- ShowPointcloud:說明如何視覺化使用 Stereo ace 相機擷取的點雲。
- TriggerLowLatency:示範如何透過將相機上的強度與深度解析度設為 High(2x2 Binning)來降低延遲。
- LeftAndRightIntensity: 示範如何從 Stereo ace 相機擷取左側與右側強度影像。
如需更多詳細資料,請參閱 C++ 範例目錄中的範例程式碼。
如何建置應用程式#
Using Visual Studio Solutions#
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#
適用於 Stereo ace 的 pylon 補充套件包含一個 Findpylon.cmake 模組,用於決定 pylon 以及適用於 Stereo ace 的 pylon 補充套件的安裝位置。尋找模組會匯出 pylon::pylon CMake 目標。請將此目標做為引數傳遞給 target_link_libraries,CMake 將會處理設定包含路徑、函式庫路徑等。
一個基本的 CMakeLists.txt CMake 檔案看起來可能如下:
project (hello)
# Locate the CMake find module for pylon ...
# for Unix systems. All other OS PYLON_ROOT will be empty.
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_ROOT})
# for Windows systems. All other OS PYLON_DEV_DIR will be empty.
list(APPEND CMAKE_PREFIX_PATH $ENV{PYLON_DEV_DIR})
find_package(pylon 12.0 REQUIRED)
add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)
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 12.0 REQUIRED)
add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)
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 12.0 REQUIRED)
add_executable(hello helloworld.cpp)
target_link_libraries(hello pylon::pylon)
適用於 Stereo ace 的 Instant Camera 類別#
pylon 提供不同類型的類別來存取相機裝置。除了低階的 IPylon 裝置外,還有所謂的 Instant Camera 類別,可為相機提供便利的高階 API。
影像 Pylon::CInstantCamera 類別提供對所有 Basler 相機的通用存取。
對於 Stereo ace 相機,適用於 Stereo ace 的 pylon 補充套件包含 Pylon::CStereoAceInstantCamera 類別。Basler 建議針對 Basler Stereo ace 相機使用此類別,因為它提供了便利的參數存取以及 Stereo ace 專屬功能。
如果您使用 CBaslerUniversalInstantCamera 類別而非 CStereoAceInstantCamera 類別,您仍然可以設定與取得由 Stereo ace 相機所提供的所有相機參數。如果沒有提供存取子物件 CBaslerUniversalInstantCamera 類別所提供的存取器物件,請使用所謂的 通用 Property 存取 用於透過名稱存取 Property,詳見 通用 Property 存取 pylon C++ Programmer's Guide 的章節。
範例:
using namespace Pylon;
GenApi::INodeMap& nodemap = camera.GetNodeMap();
CIntegerParameter depthSeg(nodemap, "BslDepthSeg" );
std::cout << "Segmentation: " << depthSeg.GetValue() << std::endl;
開啟與存取 Stereo ace 相機#
建立並開啟 Stereo ace 相機物件需要三個步驟:
- 為您要存取的相機建立相機物件。
通常,您應該建立Pylon::CStereoAceInstantCamera類別的執行個體。 - 如果需要,請註冊 Stereo ace 專屬的組態事件處理常式(詳細資料請參閱 DeviceRemovalHandling.cpp 範例)。
- 在您的應用程式中呼叫
Open()方法來建立與相機裝置的連線。
以下範例說明了這些步驟:
#include <pylon/PylonIncludes.h>
#include <pylon/StereoAceInstantCamera.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 Stereo ace camera.
CUniversalInstantInterface instantInterface(
CInterfaceInfo().SetDeviceClass(Pylon::BaslerGenTlStaDeviceClass));
CStereoAceInstantCamera camera(instantInterface.CreateFirstDevice());
// 2. Register a default configuration if available (see samples).
// camera.RegisterConfiguration(...);
// 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 的例外狀況。
典型錯誤狀況:
- 找不到 Stereo ace 相機:
CreateFirstDevice()函式會擲回例外狀況。 - 無法開啟相機,例如因為它已經被其他應用程式開啟:
Open()方法會擲回例外狀況。
以下小節提供關於如何建立和開啟相機物件的更詳細資訊。
為第一個可用的 Stereo ace 相機建立相機物件#
請使用 Pylon::CTlFactory::CreateFirstDevice() 方法來為第一個可用的 Stereo ace 相機建立相機物件。務必指定 Stereo ace 相機的 pylon 裝置類別識別碼以防止 CreateFirstDevice() 從為不同類型的相機建立相機物件:
CUniversalInstantInterface instantInterface(
CInterfaceInfo().SetDeviceClass(Pylon::BaslerGenTlStaDeviceClass));
CStereoAceInstantCamera camera(instantInterface.CreateFirstDevice());
如果找不到 Stereo ace 相機,請檢查相機和網路介面卡的 IP 組態設定。有關設定網路的詳細資訊,請參閱 Basler 產品說明文件中的 Network Configuration 主題。
為特定的 Stereo ace 相機建立相機物件#
如果您想要開啟特定的 Stereo ace 相機,除了裝置類別之外,您還可以指定其他屬性。
若要透過序號開啟特定的 Stereo ace 相機,請使用下列程式碼行:
CUniversalInstantInterface instantInterface(
CInterfaceInfo().SetDeviceClass(Pylon::BaslerGenTlStaDeviceClass));
CStereoAceInstantCamera camera(instantInterface.CreateFirstDevice(
CDeviceInfo().SetSerialNumber("40410842")));
若要透過使用者自訂名稱開啟 Stereo ace 相機,請使用下列程式碼行:
CUniversalInstantInterface instantInterface(
CInterfaceInfo().SetDeviceClass(Pylon::BaslerGenTlStaDeviceClass));
CStereoAceInstantCamera camera(instantInterface.CreateFirstDevice(
CDeviceInfo().SetUserDefinedName("MyCamera")));
User-Defined Names
您可以使用 DeviceUserID parameter. You can do this in the pylon 3D Viewer or the pylon API:
透過 IP 地址建立裝置
目前,您無法使用 CreateFirstDevice() 函式指定相機 IP 位址。原因在於目前 Pylon::CDeviceInfo() 類別未包含任何關於相機 IP 位址的資訊。
影像 OpenDeviceByIpAddress sample demonstrates how to open a Stereo ace camera by one of its IP addresses.
If the desired Stereo ace camera isn't found, check whether you're using the right values for the properties and check your camera's and your network adapter's IP configuration settings. Refer to the Network Configuration topic in the Basler Product Documentation for more information about setting up your network.
列舉 Stereo ace 相機#
The following code snippet illustrates how to retrieve a list of all connected Stereo ace cameras. For each element of the list, the camera is opened and some camera parameter values are printed.
#include <pylon/PylonIncludes.h>
#include <pylon/StereoAceInstantCamera.h>
#include <ostream>
using namespace Pylon;
// ....
// Before using any pylon methods, the pylon runtime must be initialized.
PylonInitialize();
// ....
// Enumerate all Stereo ace cameras.
CTlFactory& TlFactory = CTlFactory::GetInstance();
DeviceInfoList_t lstDevices;
DeviceInfoList_t filter;
filter.push_back(CDeviceInfo().SetDeviceClass(BaslerGenTlStaDeviceClass));
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.
CStereoAceInstantCamera camera(CTlFactory::GetInstance().CreateDevice(*it));
// Optionally register configuration(s) here.
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 Instant Camera 類別允許您註冊組態事件處理常式物件,可用於在特定事件發生時套用相機設定,例如當 Open() 方法被呼叫時。
以下範例說明如何註冊一個套用額外設定的組態事件處理常式:
class MyConfigurationHandler : public StereoAceConfigurationEventHandler
{
public:
// Sets exposure time to minimum possible value.
void OnOpened(CStereoAceInstantCamera& camera) override
{
camera.ExposureTime.SetToMinimum();
}
};
// ....
// Then, register configuration event handlers.
camera.RegisterConfiguration(
new MyConfigurationHandler,
RegistrationMode_Append, Cleanup_Delete);
// ....
camera.Open(); // Configurations will be applied.
Refer to the Instant Camera Event Handler Basics section of the pylon C++ Programmer's Guide for more information about pylon camera event handler classes.
If you don't want to apply your desired settings by providing a configuration event handler, you can set the parameters you want to change at any time after calling the CStereoAceInstantCamera::Open() 方法來建立與相機的連線。
Refer to the Parametrize Camera section for information about how to set and get camera parameter values.
連接至相機#
建立相機物件並註冊組態事件處理常式後,透過呼叫 CStereoAceInstantCamera::Open() 方法來建立與相機的連線。
連線會保持作用中,直到呼叫 CStereoAceInstantCamera::Close() 方法被呼叫時。以下項目的解構函式 CStereoAceInstantCamera 會自動呼叫 Close() (如果尚未明確呼叫)。
The camera closes the connection if it doesn't periodically receive heartbeat requests from the camera. Missing heartbeat requests occur if the application crashes or is interrupted by a debugger.
設定相機參數#
Refer to the Accessing Parameters section of the pylon C++ Programmer's Guide to get familiar with how to access camera parameters using the pylon API.
The pylon C++ samples Parametrize_NativeParameterAccess and Parametrize_GenericParameterAccess illustrate typical methods for accessing camera parameters using pylon.
The following code sample illustrates how to set and get frequently-used Stereo ace-specific camera parameters using the CStereoAceInstantCamera 類別的執行個體。
// Include files to use the pylon API
#include <pylon/PylonIncludes.h>
#include <pylon/StereoAceInstantCamera.h>
// Namespaces for using the pylon API and the Stereo ace camera parameters
using namespace Pylon;
using namespace StereoAceCameraParams_Params;
// Set the exposure time of the camera.
camera.ExposureTime.SetValue(5000); // us
// Set the gain.
camera.Gain.SetValue(0.0);
// Set the illumination mode (e.g., AlwaysActive, AlternateActive, Off).
camera.BslIlluminationMode.SetValue(BslIlluminationMode_AlwaysActive);
// Set the illumination strength (0.0 ... 1.0).
camera.BslIlluminationStrength.SetValue(1.0);
// Set the minimum and maximum depth for the working area.
camera.BslDepthMinDepth.SetValue(200); // mm
camera.BslDepthMaxDepth.SetValue(2000); // mm
// Set the output resolutions.
CEnumParameter(camera.GetNodeMap(), "BslDepthResolution").SetValue("High");
CEnumParameter(camera.GetNodeMap(), "BslIntensityResolution").SetValue("Full");
// The producer derives the internal binning and scaling settings automatically.
// Print out current parameter values.
std::cout << "Exposure Time : "
<< camera.ExposureTime.GetValue() << std::endl;
std::cout << "Gain : "
<< camera.Gain.GetValue() << std::endl;
std::cout << "Illumination Mode : "
<< camera.BslIlluminationMode.GetValue() << std::endl;
std::cout << "Illumination Strength : "
<< camera.BslIlluminationStrength.GetValue() << std::endl;
std::cout << "Min Depth : "
<< camera.BslDepthMinDepth.GetValue() << std::endl;
std::cout << "Max Depth : "
<< camera.BslDepthMaxDepth.GetValue() << std::endl;
std::cout << "Depth Resolution : "
<< CEnumParameter(camera.GetNodeMap(), "BslDepthResolution").ToString() << std::endl;
std::cout << "Intensity Resolution : "
<< CEnumParameter(camera.GetNodeMap(), "BslIntensityResolution").ToString() << std::endl;
The pylon 3D Viewer provides a Documentation pane. When you select a camera parameter in the Features pane, the Documentation pane displays information about the parameter selected as well as C++ and C# code snippets that illustrate how to get and set the value of that camera parameter.
擷取資料#
請參閱 pylon C++ Programmer's Guide 中的 Grabbing Images 一節,以熟悉如何使用 pylon API 擷取資料。
pylon represents grabbed images as data structures called GrabResults. GrabResults acquired by a Stereo ace camera contain multiple components. By default, each GrabResult stores an intensity image, a disparity map, and additional information.
// Enable disparity maps by enabling the Disparity component and setting the
// appropriate pixel format.
camera.ComponentSelector.SetValue(ComponentSelector_Disparity);
camera.ComponentEnable.SetValue(true);
Refer to the Component Selector and Pixel Format topics of the Basler Product Documentation for more details.
擷取迴圈#
pylon 支援用於設定擷取迴圈的不同方法,並提供用於處理 Memory 緩衝區的不同策略。
如需更多詳細資料,請參閱 pylon C++ Programmer's Guide 中的 Grabbing Images 一節。
以下程式碼片段說明了使用以下項目的典型擷取迴圈: CStereoAceInstantCamera 類別:
#include <pylon/PylonIncludes.h>
#include <pylon/StereoAceInstantCamera.h>
using namespace Pylon;
using namespace StereoAceCameraParams_Params;
PylonInitialize();
CUniversalInstantInterface instantInterface(
CInterfaceInfo().SetDeviceClass(Pylon::BaslerGenTlStaDeviceClass));
CStereoAceInstantCamera camera(instantInterface.CreateFirstDevice());
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.
// ...existing code...
} else {
// Error handling
std::cerr << "Grab error occurred: "
<< ptrGrabResult->GetErrorDescription() << std::endl;
}
}
// Clean-up
camera.StopGrabbing();
camera.Close();
存取元件#
To access an individual image component of a GrabResult, use the Pylon::CGrabResultData::GetFirstImageDataComponent() method and specify the desired component type. The method returns a Pylon::CPylonDataComponent that holds the image data, e.g., the depth values, as well as its metadata.
將 throwIfNotFound argument to false if a missing component returns an invalid component instead of throwing an exception. Always use the CPylonDataComponent::IsValid() method to check whether the requested component was found before accessing its data.
Refer to the Multi-Component Grab Results section in the "Advanced Topics" chapter of the pylon C++ Programmer's Guide for more information about how pylon provides access to GrabResults containing multiple components.
範例:
if (ptrGrabResult->GrabSucceeded()) {
const auto intensityComponent =
ptrGrabResult->GetFirstImageDataComponent(
EComponentType::ComponentType_Intensity, 0, false);
if (!intensityComponent.IsValid()) {
throw std::runtime_error(
"Buffer doesn't contain an intensity component.");
}
const auto disparityComponent =
ptrGrabResult->GetFirstImageDataComponent(
EComponentType::ComponentType_Disparity, 0, false);
if (!disparityComponent.IsValid()) {
throw std::runtime_error(
"Buffer doesn't contain a disparity component.");
}
} else {
std::cerr << "Grab error: " << ptrGrabResult->GetErrorCode() << " "
<< ptrGrabResult->GetErrorDescription() << std::endl;
}