콘텐츠로 건너뛰기
STAGING SERVER
DEVELOPMENT SERVER

.NET 프로그래머 가이드#

이 항목은 Basler blaze 카메라 전용 정보를 제공하며 pylon .NET API에 대한 포괄적인 개요를 제공하기 위한 것은 아닙니다.

pylon을 처음 사용하는 경우, Basler에서는 pylon .NET Programmer's Guide를 먼저 읽고 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 솔루션 탐색기에서 프로젝트를 마우스 우클릭하고 추가 > 프로젝트 참조를 선택합니다.
    참조 관리자 창이 열립니다.
  2. 찾아보기 버튼을 클릭합니다.
  3. %Program Files%\Basler\pylon 8\Development\Assemblies\Basler.Pylon\x64 폴더로 이동합니다.
  4. Basler.Pylon.dll을 선택하고 추가 버튼을 클릭합니다.
  5. 찾아보기 버튼을 클릭합니다.
  6. %Program Files%\Basler\pylon 8\Development\Assemblies\Basler.Pylon.Blaze\AnyCpu 폴더로 이동합니다.
  7. Basler.Pylon.Blaze.dll을 선택하고 추가 버튼을 클릭합니다.

Basler.Pylon 어셈블리의 프로세서 아키텍처

32비트 플랫폼용 어셈블리를 선택하든 64비트 플랫폼용 어셈블리를 선택하든 상관없습니다. 어셈블리가 GAC(Global Assembly Cache)에 설치되어 있으므로, .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

사용자 지정 이름

다음을 사용하여 카메라에 사용자 지정 이름을 할당할 수 있습니다. DeviceUserID parameter. blaze Viewer, pylon IP Configurator 또는 pylon API에서 이 작업을 수행할 수 있습니다:

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

IP 주소로 디바이스 생성

현재는 IP 주소를 지정하여 디바이스를 생성할 수 없습니다.

특정 IP 주소를 가진 카메라를 생성하고 열려면, 먼저 모든 카메라를 열거하고 반환된 목록을 반복한 후, 각 카메라를 열어 IP 주소 및 기타 네트워크 관련 정보를 조회해야 합니다.

원하는 blaze 카메라를 찾지 못한 경우, 속성에 올바른 값을 사용하고 있는지 확인하고 카메라 및 네트워크 어댑터의 IP 구성 설정을 점검하십시오. 네트워크 설정에 대한 자세한 내용은 Network Configuration 항목을 참조하십시오.

사전 정의된 카메라 파라미터 구성#

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의 구성 이벤트 핸들러에 대해 자세히 알아보려면 pylon .NET Programmer's Guide의 Predefined Camera Parameter Configurations 섹션을 참조하십시오.

깊이 데이터 해석#

Processing Measurement Results 항목에서는 Range 데이터 컴포넌트에 저장된 깊이 데이터의 형식에 대한 정보를 제공합니다.

카메라에 연결#

카메라 객체를 생성하고 구성 이벤트 핸들러를 등록한 후, CBlazeInstantCamera::Open() 메서드를 호출하여 카메라와의 연결이 설정됩니다.

연결은 CBlazeInstantCamera::Close() 메서드가 호출될 때까지 유지됩니다. Camera 클래스의 소멸자는 명시적으로 호출되지 않은 경우 Close() 을(를) 자동으로 호출합니다. 카메라 객체의 수명을 명시적으로 제어하기 위해 Basler는 위의 코드 스니펫에 표시된 것처럼 using 문 내에서 카메라 객체를 사용할 것을 권장합니다.

카메라가 주기적으로 하트비트 요청을 수신하지 못하면 카메라는 연결을 닫습니다. 하트비트 요청 누락은 애플리케이션이 충돌하거나 디버거에 의해 중단될 때 발생합니다. 자세한 내용은 Debugging Applications and Controlling the GigE Vision Heartbeat 섹션을 참조하십시오.

파라미터 액세스#

pylon .NET API를 사용하여 카메라 파라미터에 액세스하는 방법을 익히려면 pylon .NET Programmer's Guide의 Parameter Access 섹션을 참조하십시오.

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 API를 사용하여 데이터를 획득하는 방법을 익히려면 Grabbing Images의 pylon .NET Programmer's Guide 섹션을 참조하십시오.

pylon은 캡처한 이미지를 GrabResults라는 데이터 구조로 표현합니다. 2D 카메라로 획득한 GrabResults에는 단일 그레이 밸류 또는 컬러 이미지가 포함됩니다.

blaze 카메라로 캡처한 GrabResults에는 여러 컴포넌트가 포함됩니다. 기본적으로 각 GrabResult에는 강도 이미지, 신뢰도 맵, 깊이 정보가 저장됩니다.

Range 컴포넌트에 설정된 Pixel Format에 따라 깊이 데이터는 2D 깊이 맵 또는 3D 포인트 클라우드로 표현될 수 있습니다.

정보

카메라가 포인트 클라우드와 깊이 정보를 동시에 전송하도록 설정하는 것은 불가능합니다.

Processing Measurement Results 항목에서는 깊이 맵에서 포인트 클라우드를 계산하는 방법을 설명합니다.

그랩 루프#

pylon은 그랩 루프 설정을 위한 다양한 접근 방식을 지원하며 메모리 버퍼를 처리하기 위한 다양한 전략을 제공합니다.

자세한 내용은 Grabbing Images의 pylon .NET Programmer's Guide 섹션을 참조하십시오.

다음 코드 샘플은 일반적인 그랩 루프를 보여줍니다.

// 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() method to get access to a GrabResult's IDataContainer.

pylon이 여러 컴포넌트를 포함하는 GrabResults에 대한 액세스를 제공하는 방법에 대한 자세한 내용은 Multi-Component Grab Results의 pylon .NET Programmer's Guide 섹션을 참조하십시오.

예:

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 이하 버전 사용 시 재연결 문제

카메라와의 연결을 정상적으로 닫기 전에 애플리케이션이 종료되거나 중단되면, 하트비트 타임아웃이 만료될 때까지 카메라는 연결된 상태를 유지합니다. 하트비트 타임아웃이 만료될 때까지 카메라는 추가적인 연결 시도를 거부합니다. 애플리케이션을 다시 시작하거나 카메라에 액세스하는 다른 애플리케이션을 시작할 때 장치가 현재 사용 중이라는 오류가 발생합니다.

이 문제는 보통 디버거를 사용하여 애플리케이션을 중지하거나 애플리케이션이 예기치 않게 종료될 때 발생합니다. 카메라를 다시 열려면 타임아웃이 경과할 때까지 기다리거나 네트워크에서 카메라를 일시적으로 연결 해제해야 합니다.

이 문제를 해결하려면 디버거 제어하에 애플리케이션이 실행 중일 때 하트비트 타임아웃의 자동 조정을 재정의할 수 있으며, 환경 변수 이름을 GEV_HEARTBEAT_TIMEOUT (으)로 설정하여 원하는 타임아웃(밀리초 단위)을 지정할 수 있습니다. 또는 샘플 프로그램에 표시된 대로 pylon API를 사용하여 애플리케이션에서 하트비트 타임아웃을 설정할 수 있습니다. DeviceRemovalCSharp 및 DeviceRemovalVB 예제 프로그램.