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

.NET程式設計人員指南#

本主題提供Basler blaze相機的專屬資訊,目的並非全面介紹pylon .NET API。

如果您是pylon的新手,Basler建議您先閱讀 pylon .NET程式設計人員指南,以熟悉pylon .NET API。

.NET程式設計範例#

若要開啟包含blaze相機程式設計範例的資料夾,請按下 Win 鍵,前往 Basler 資料夾,然後選擇 blaze Samples。隨即會開啟「檔案總管」視窗。.NET程式設計範例位於 DotNet 資料夾中。

如何建置範例#

資訊

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

範例提供Visual Studio解決方案與專案檔案。您可以使用Visual Studio 2017或更新版本開啟解決方案並建置範例。

如何建置.NET應用程式#

若要使用C#或Visual Basic .NET操作Basler blaze相機,您必須將 Basler.Pylon 和 Basler.Pylon.Blaze 組件新增至專案的組件參考清單中。

若要新增組件:

  1. 在Visual Studio「方案總管」中以滑鼠右鍵按一下您的專案,然後選取 Add > Project Reference。
    隨即會開啟 Reference Manager 視窗。
  2. 按一下 Browse 按鈕。
  3. 瀏覽至 %Program Files%\Basler\pylon 8\Development\Assemblies\Basler.Pylon\x64 資料夾。
  4. 選取 Basler.Pylon.dll,然後按一下 Add 按鈕。
  5. 按一下 Browse 按鈕。
  6. 瀏覽至 %Program Files%\Basler\pylon 8\Development\Assemblies\Basler.Pylon.Blaze\AnyCpu 資料夾。
  7. 選擇 Basler.Pylon.Blaze.dll,然後按一下 Add 按鈕。

Basler.Pylon 組件的處理器架構

選擇針對 32 位元還是 64 位元平台的組件並不重要。由於組件已安裝在全域組件快取 (GAC) 中,.NET 組件載入器將自動選擇與您的應用程式建置架構相符的組件。

為了在建置應用程式時避免關於潛在架構不相容的警告,Basler 建議手動編輯 Visual Studio 專案檔案以隱藏這些警告。請遵循以下步驟:

  1. 在「方案總管」中,以滑鼠右鍵按一下您的專案,然後選擇 Unload project。
  2. 再次以滑鼠右鍵按一下專案,然後選擇 Edit project。
    專案的 XML 檔案隨即會在編輯器視窗中開啟。
  3. 在 XML 檔案中,導覽至參考 Basler.Pylon 組件的位置,亦即搜尋類似下列的片段:

    <ItemGroup>
    ....
    <Reference Include="Basler.Pylon, Version=1.2.0.0, Culture=neutral,
        PublicKeyToken=e389355f398382ab, processorArchitecture=AMD64" />/
    
  4. 在 ItemGroup 元素上方,新增下列 XML 片段:

    <PropertyGroup>
    <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    

    新增元素之後,您的專案檔案應包含類似這樣的片段:

    <PropertyGroup>
        <ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
    </PropertyGroup>
    <ItemGroup>
    ....
    <Reference Include="Basler.Pylon">
        <HintPath>..\..\..\..\..\..\Program Files\Basler\pylon\Development\Assemblies\Basler.Pylon\x64\Basler.Pylon.dll</HintPath>
    </Reference>
    <Reference Include="Basler.Pylon.Blaze">
        <HintPath>..\..\..\..\..\..\Program Files\Basler\pylon\Development\Assemblies\Basler.Pylon.Blaze\AnyCpu\Basler.Pylon.Blaze.dll</HintPath>
    </Reference>
    ....
    </ItemGroup>
    
  5. 完成編輯後,以滑鼠右鍵按一下專案並選擇 Reload project 以重新載入專案。
    當系統詢問時,確認關閉專案檔案並儲存未完成的變更。

開啟並存取blaze相機#

pylon .NET API 針對所有相機類型提供單一 Camera 類別。您可以使用多載建構函式來選取特定的相機裝置。

建立並開啟 blaze 相機物件需要三個步驟:

  1. 為您要存取的相機建立相機物件。

  2. 註冊套用預設組態的 blaze 專屬參數組態。如需 blaze 組態事件處理常式類別的詳細資訊,請參閱 Predefined Camera Parameter Configurations 一節。

  3. 在您的應用程式中呼叫 Open() 方法來建立與相機裝置的連線。

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

using Basler.Pylon;
using Basler.Pylon.Blaze;

// ...

var filter = new Dictionary<string, string> {
    { CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass }
};
using (var camera = new Camera(filter, CameraSelectionStrategy.FirstFound))
{
    // Set up the camera for continuously grabbing point clouds.
    camera.CameraOpened += BlazeConfigurations.AcquirePointCloudsContinuously;

    // Open the connection to the camera device.
    camera.Open();

    // Use the camera.

    // Close the connection.
    camera.Close();
}
Imports Basler.Pylon
Imports Basler.Pylon.Blaze

' ...

Dim filter = New Dictionary(Of String, String) From {
    {CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass}
}
Using camera = New Camera(filter, CameraSelectionStrategy.FirstFound)
    ' Set up the camera for continuously grabbing point clouds.
    AddHandler camera.CameraOpened,
        AddressOf BlazeConfigurations.AcquirePointCloudsContinuously

    ' Open the connection to the camera device.
    camera.Open()

    ' Use the camera.

    ' Close the connection.
    camera.Close()
End Using

為第一個可用的blaze相機建立相機物件#

影像 Camera 類別提供建構函式,允許您傳入鍵值對清單,以指定為其建立相機物件之相機裝置的 Property。

若要開啟第一個可用的 blaze 相機,只需指定裝置類型等於 blaze 裝置類別即可。

var filter = new Dictionary<string, string> {
    { CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass }
};
using (var camera = new Camera(filter, CameraSelectionStrategy.FirstFound))
{
}
Dim filter = New Dictionary(Of String, String) From {
    {CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass}
}
Using camera = New Camera(filter, CameraSelectionStrategy.FirstFound)

End Using

為特定的blaze相機建立相機物件#

如果您想要開啟特定的 blaze 相機(例如透過指定其序號),除了將 blaze 相機的 pylon 裝置類別識別碼傳遞至 CreateFirstDevice()之外,您還可以指定其他 Property。

以下程式碼片段說明如何透過序號開啟 blaze 相機。

// Specify device class and serial number.
var filter = new Dictionary<string, string>
{
    { CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass },
    { CameraInfoKey.SerialNumber, "20399956" }
};
using (var camera = new Camera(filter, CameraSelectionStrategy.Unambiguous))
{
}
Dim filter = New Dictionary(Of String, String) From {
    {CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass},
    { CameraInfoKey.SerialNumber, "20399956" }
}
Using camera = New Camera(filter, CameraSelectionStrategy.FirstFoundUnambiguous)

End Using

若要透過使用者定義名稱開啟 blaze 相機,請使用下列程式碼行:

// Specify device class and serial number.
var filter = new Dictionary<string, string>
{
    { CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass },
    { CameraInfoKey.UserDefinedName, "Top" }
};
using (var camera = new Camera(filter, CameraSelectionStrategy.Unambiguous))
{
}
Dim filter = New Dictionary(Of String, String) From {
    {CameraInfoKey.DeviceType, DeviceType.BaslerGenTlBlazeDeviceClass},
    { CameraInfoKey.UserDefinedName, "Top" }
}
Using camera = New Camera(filter, CameraSelectionStrategy.FirstFoundUnambiguous)

End Using

User-Defined Names

您可以使用 DeviceUserID 參數將使用者定義名稱指派給相機。您可以在 blaze Viewer、pylon IP Configurator 或 pylon API 中執行此操作:

camera.Parameters[PLBlaze.DeviceUserID].SetValue("MyCamera");
camera.Parameters(PLBlaze.DeviceUserID).SetValue("MyCamera")

透過 IP 地址建立裝置

目前,您無法透過指定裝置的 IP 地址來建立裝置。

如果您想要建立並開啟具有特定 IP 地址的相機,必須先列舉所有相機、走訪傳回的清單,並在查詢 IP 地址及其他網路相關資訊之前開啟每台相機。

如果找不到所需的 blaze 相機,請檢查您是否使用了正確的 Property 值,並檢查相機與網路介面卡的 IP 設定。如需有關設定網路的詳細資訊,請參閱網路組態主題。

預先定義的相機Property設定#

對於 blaze 相機,有 BlazeConfigurations 類別。此類別的方法可以新增至 CameraOpened 事件。這必須在呼叫 Open() 方法來開啟相機之前完成。當相機開啟時,會自動呼叫組態方法並相應地變更相機組態。

範例:

// Set up the camera for continuously grabbing point clouds.
camera.CameraOpened += BlazeConfigurations.AcquirePointCloudsContinuously;
' Set up the camera for continuously grabbing point clouds.
AddHandler camera.CameraOpened,
AddressOf BlazeConfigurations.AcquirePointCloudsContinuously

影像 BlazeConfigurations 提供以下組態方法:

  • AcquirePointCloudsContinuously
    持續擷取資料。深度資料以點雲形式表示。
  • AcquireDepthMapsContinuously
    持續擷取資料. 深度資料以深度圖形式表示。

請參閱 pylon .NET Programmer's Guide 中的Predefined Camera Parameter Configurations章節,以深入了解 pylon 的組態事件處理常式。

解讀深度資料#

Processing Measurement Results主題提供了關於儲存在 Range 資料元件中的深度資料格式的資訊。

連接至相機#

建立相機物件並註冊組態事件處理常式後,透過呼叫 CBlazeInstantCamera::Open() 方法來建立與相機的連線。

連線會保持作用中,直到呼叫 CBlazeInstantCamera::Close() 方法的 Camera 類別會自動呼叫 Close() (如果尚未明確呼叫)。為了明確控制相機物件的生命週期,Basler 建議如上方程式碼片段所示,在 using 陳述式內使用相機物件。

如果相機未定期收到來自相機的心跳要求,相機將會關閉連線。如果應用程式當機或遭到偵錯工具中斷,就會發生遺漏心跳要求的情況。如需更多詳細資訊,請參閱Debugging Applications and Controlling the GigE Vision Heartbeat章節。

存取Property#

請參閱 pylon .NET Programmer's Guide 中的Parameter Access章節,以熟悉如何使用 pylon .NET API 存取相機參數。

pylon .NET API 提供參數清單作為存取相機參數的便利方法,並在 Visual Studio 的 IntelliSense 輔助下進行。

對於 blaze 相機,有 PLBlaze 參數清單。

以下程式碼片段示範如何使用 PLBlaze 參數清單。

// 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.
var oldOperatingMode = camera.Parameters[PLBlaze.OperatingMode].GetValue();
camera.Parameters[PLBlaze.OperatingMode].SetValue(PLBlaze.OperatingMode.LongRange);

// Exposure time of the camera. If the operating mode is changed, the
// exposure time is set to the recommended default value.
camera.Parameters[PLBlaze.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.Parameters[PLBlaze.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.Parameters[PLBlaze.TemporalFilter].SetValue(true);
camera.Parameters[PLBlaze.TemporalFilterStrength].SetValue(220);

// The outlier removal removes pixels that differ significantly from
// their local environment.
camera.Parameters[PLBlaze.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.Parameters[PLBlaze.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.Parameters[PLBlaze.MultiCameraChannel].TrySetValue(1);

Console.WriteLine("Operating Mode           : {0}",
    camera.Parameters[PLBlaze.OperatingMode].GetValue());
Console.WriteLine("Exposure Time            : {0}",
    camera.Parameters[PLBlaze.ExposureTime].GetValue());
Console.WriteLine("Spatial Filter           : {0}",
    camera.Parameters[PLBlaze.SpatialFilter].GetValue());
Console.WriteLine("Temporal Filter          : {0}",
    camera.Parameters[PLBlaze.TemporalFilter].GetValue());
Console.WriteLine("Temporal Filter Strength : {0}",
    camera.Parameters[PLBlaze.TemporalFilterStrength].GetValue());
Console.WriteLine("Outlier Removal          : {0}",
    camera.Parameters[PLBlaze.OutlierRemoval].GetValue());
Console.WriteLine("Confidence Threshold     : {0}",
    camera.Parameters[PLBlaze.ConfidenceThreshold].GetValue());
if (camera.Parameters[PLBlaze.MultiCameraChannel].IsReadable)
{
    Console.WriteLine("Multi-Camera Channel     : {0}",
        camera.Parameters[PLBlaze.MultiCameraChannel].GetValue());
}

// Restore the old operating mode.
camera.Parameters[PLBlaze.OperatingMode].SetValue(oldOperatingMode);
' 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.
Dim oldOperatingMode = camera.Parameters(PLBlaze.OperatingMode).GetValue()
camera.Parameters(PLBlaze.OperatingMode).SetValue(PLBlaze.OperatingMode.LongRange)

' Exposure time of the camera. If the operating mode is changed, the
' exposure time is set to the recommended default value
camera.Parameters(PLBlaze.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.Parameters(PLBlaze.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.Parameters(PLBlaze.TemporalFilter).SetValue(True)
camera.Parameters(PLBlaze.TemporalFilterStrength).SetValue(220)

' The outlier removal removes pixels that differ significantly from
' their local environment
camera.Parameters(PLBlaze.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.Parameters(PLBlaze.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.Parameters(PLBlaze.MultiCameraChannel).TrySetValue(1)

Console.WriteLine("Operating Mode           : {0}",
    camera.Parameters(PLBlaze.OperatingMode).GetValue())
Console.WriteLine("Exposure Time            : {0}",
    camera.Parameters(PLBlaze.ExposureTime).GetValue())
Console.WriteLine("Spatial Filter           : {0}",
    camera.Parameters(PLBlaze.SpatialFilter).GetValue())
Console.WriteLine("Temporal Filter          : {0}",
    camera.Parameters(PLBlaze.TemporalFilter).GetValue())
Console.WriteLine("Temporal Filter Strength : {0}",
    camera.Parameters(PLBlaze.TemporalFilterStrength).GetValue())
Console.WriteLine("Outlier Removal          : {0}",
    camera.Parameters(PLBlaze.OutlierRemoval).GetValue())
Console.WriteLine("Confidence Threshold     : {0}",
    camera.Parameters(PLBlaze.ConfidenceThreshold).GetValue())

If camera.Parameters(PLBlaze.MultiCameraChannel).IsReadable Then
    Console.WriteLine("Multi-Camera Channel     : {0}",
        camera.Parameters(PLBlaze.MultiCameraChannel).GetValue())
End If

' Restore the old operating mode.
camera.Parameters(PLBlaze.OperatingMode).SetValue(oldOperatingMode)

擷取資料#

請參閱 pylon .NET Programmer's Guide 中的Grabbing Images章節,以熟悉如何使用 pylon .NET API 擷取資料。

pylon 會將擷取的影像表示為稱為 GrabResults 的資料結構。由 2D 相機擷取的 GrabResults 包含單一灰階或彩色影像。

由 blaze 相機擷取的 GrabResults 包含多個元件。預設情況下,每個 GrabResult 都會儲存強度影像、信心圖和深度資訊。

根據為 Range 元件設定的 Pixel Format,深度資料可以表示為 2D 深度圖或 3D 點雲。

資訊

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

Processing Measurement Results 主題說明了如何從深度圖計算點雲。

擷取迴圈#

pylon 支援用於設定擷取迴圈的不同方法,並提供用於處理 Memory 緩衝區的不同策略。

如需更多詳細資料,請參閱 pylon .NET Programmer's Guide 的 Grabbing Images 節。

下列程式碼範例說明了典型的擷取迴圈:

// Open the connection to the camera device.
camera.Open();

// The MaxNumBuffer parameter can be used to control the amount of buffers
// allocated for grabbing. The default value of this parameter is 10.
camera.Parameters[PLCameraInstance.MaxNumBuffer].SetValue(3);

// Start grabbing.
camera.StreamGrabber.Start();

// Grab a number of images.
for (int i = 0; i < 10; ++i)
{
  // Wait for an image and then retrieve it. A timeout of 1000 ms is used.
  IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(
      1000,
      TimeoutHandling.ThrowException
  );
  using (grabResult) // Make sure that the grab buffers are reused for
                     // grabbing as soon we run out of scope.
  {
    // Image grabbed successfully?
    if (grabResult.GrabSucceeded)
    {
      // Access the data.
      // ....
    }
    else
    {
      Console.WriteLine("Error: {0} {1}",
      grabResult.ErrorCode, grabResult.ErrorDescription);
    }
  }
}
// Stop grabbing.
camera.StreamGrabber.Stop();
' Open the connection to the camera device.
camera.Open()

' The MaxNumBuffer parameter can be used to control the amount of buffers
' allocated for grabbing. The default value of this parameter is 10.
camera.Parameters(PLCameraInstance.MaxNumBuffer).SetValue(3)

' Start grabbing.
camera.StreamGrabber.Start()

' Grab a number of images.
For i As Integer = 0 To 10 - 1
  ' Wait for an image and then retrieve it. A timeout of 1000 ms is used.
  Dim grabResult As IGrabResult = camera.StreamGrabber.RetrieveResult(
    1000,
    TimeoutHandling.ThrowException
  )

  Using grabResult
    ' Image grabbed successfully?
    If grabResult.GrabSucceeded Then
      ' Access the data.
      ' ....
    Else
      Console.WriteLine("Error: {0} {1}",
        grabResult.ErrorCode,
        grabResult.ErrorDescription)
    End If
  End Using
Next

' Stop grabbing.
camera.StreamGrabber.Stop()

存取元件#

若要存取 GrabResult 的個別元件,您可以使用 IDataContainer 和 IDataComponent 類別。容器可以容納一個或多個元件。您可以使用容器來查詢元件數量並擷取特定元件。容器中的每個元件都包含實際資料(例如深度值)以及其中繼資料。

請使用 IGrabResult::GetDataContainer() 方法以存取 GrabResult 的 IDataContainer.

如需關於 pylon 如何提供對包含多個元件之 GrabResults 的存取的更多資訊,請參閱 pylon .NET Programmer's Guide 的 Multi-Component Grab Results 節。

範例:

IGrabResult grabResult = camera.StreamGrabber.RetrieveResult(
  1000,
  TimeoutHandling.ThrowException
);
using (grabResult)
{
  // Image grabbed successfully?
  if (grabResult.GrabSucceeded)
  {
    // Access the components.
    // The container and the components should always be used in combination
    // with using statements. This ensures that the underlying grab buffers
    // are reused for grabbing new data as soon as the variables go out
    // of scope. Omitting the using statements and relying on the garbage
    // collector instead will cause buffer underruns resulting in missed data.
    using (var container = grabResult.Container)
    using (var rangeComponent = container[0])
    using (var intensityComponent = container[1])
    using (var confidenceComponent = container[2])
    {
      var pointCloudData = rangeComponent.PixelData as float[];
      var intensityData = intensityComponent.PixelData as UInt16[];
      var confidenceData = confidenceComponent.PixelData as UInt16[];

      // Access the center pixel.
      var u = (uint)(rangeComponent.Width / 2);
      var v = (uint)(rangeComponent.Height / 2);
      var idx = v * rangeComponent.Width + u;
      var intensity = intensityData[idx];
      var confidence = confidenceData[idx];
      // There is a triple (x,y,z) of floats per pixel.
      var x = pointCloudData[3 * idx];
      var y = pointCloudData[3 * idx + 1];
      var z = pointCloudData[3 * idx + 2];

      if (confidence != 0) // Alternatively: if (z != 0)
      {
        // Valid depth data
        Console.WriteLine("x={0}, y={1}, z={2}, intensity={3}, confidence = {4}",
            x, y, z, intensity, confidence);
      }
      else
      {
        Console.WriteLine("No depth data available for pixel ({0},{1}), intensity={2}",
        u, v, intensity);
      }
  }
  else
  {
      Console.WriteLine("Error: {0} {1}",
        grabResult.ErrorCode, grabResult.ErrorDescription);
  }
}
Dim grabResult As IGrabResult =
  camera.StreamGrabber.RetrieveResult(5000, TimeoutHandling.ThrowException)

Using grabResult
  ' Image grabbed successfully?
  If grabResult.GrabSucceeded Then
    ' Access the components.
    ' The container and the components should always be used in combination with
    ' using statements. This ensures that the underlying grab buffers are reused
    ' for grabbing new data as soon as the variables go out of scope.
    ' Omitting the using statements and relying on the garbage collector instead
    ' will cause buffer underruns resulting in missed data.
    Using container = grabResult.Container,
      rangeComponent = container(0),
      intensityComponent = container(1),
      confidenceComponent = container(2)

      Dim pointCloudData = TryCast(rangeComponent.PixelData, Single())
      Dim intensityData = TryCast(intensityComponent.PixelData, UInt16())
      Dim confidenceData = TryCast(confidenceComponent.PixelData, UInt16())

      ' Access the center pixel.
      Dim u = CUInt((rangeComponent.Width / 2))
      Dim v = CUInt((rangeComponent.Height / 2))
      Dim idx = v * rangeComponent.Width + u
      Dim intensity = intensityData(idx)
      Dim confidence = confidenceData(idx)
      Dim x = pointCloudData(3 * idx)
      Dim y = pointCloudData(3 * idx + 1)
      Dim z = pointCloudData(3 * idx + 2)

      If confidence <> 0 Then ' Alternatively: if (z != 0)
        ' Valid depth data
        Console.WriteLine("x={0}, y={1}, z={2}, intensity={3}, confidence = {4}",
          x, y, z, intensity, confidence)
      Else
        Console.WriteLine("No depth data available for pixel ({0},{1}), intensity={2}",
          u, v, intensity)
      End If
    End Using
  Else
    Console.WriteLine("Error: {0} {1}", grabResult.ErrorCode,
      grabResult.ErrorDescription)
  End If
End Using

解讀深度資料#

Processing Measurement Results主題提供了關於儲存在 Range 資料元件中的深度資料格式的資訊。

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

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

如果應用程式在正常關閉與相機的連線之前終止或當機,相機會保持連線開啟,直到心跳逾時(heartbeat timeout)到期為止。在心跳逾時到期之前,相機會拒絕任何進一步的連線嘗試。當重新啟動您的應用程式或啟動另一個要求存取相機的應用程式時,您將收到一則指出裝置目前正在使用的錯誤。

如果您使用偵錯工具停止應用程式,或者如果您的應用程式非預期地終止,通常會發生這種情況。若要再次開啟相機,您必須等待逾時經過,或者暫時將相機從網路中斷連線。

為了因應這種情況,當應用程式在偵錯工具的控制下執行時,您可以透過將名為 GEV_HEARTBEAT_TIMEOUT 的環境變數設定為所需的毫秒逾時時間,來覆寫心跳逾時的自動調整。或者,您可以使用 pylon API 在應用程式中設定心跳逾時,如 DeviceRemovalCSharp 和 DeviceRemovalVB 範例程式所示。