콘텐츠로 바로 가기
STAGING SERVER
DEVELOPMENT SERVER

.NET 프로그래머 가이드#

이 주제는 Basler blaze 카메라에 관한 구체적인 정보를 제공하며, pylon .NET API에 대한 포괄적인 개요를 제시하는 것을 목적으로 하지 않습니다.

pylon을 처음 사용하시는 경우, Basler에서는 먼저 ‘pylon .NET 프로그래머 가이드’를 읽어보며 pylon .NET API에 익숙해지실 것을 권장합니다.

.NET 프로그래밍 예제#

블레이즈 카메라용 프로그래밍 예제가 들어 있는 폴더를 열려면 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. 솔루션 탐색기에서 프로젝트를 마우스 오른쪽 단추로 클릭한 다음 ‘프로젝트 언로드’를 선택합니다.
  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 구성 이벤트 핸들러 클래스에 대한 자세한 내용은 ‘사전 정의된 카메라 매개변수 구성’ 섹션을 참조하십시오.

  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 카메라에 대한 카메라 객체 생성#

The Camera 이 클래스는 카메라 객체가 생성된 카메라 장치의 속성을 지정하는 키-값 쌍 목록을 전달할 수 있는 생성자를 제공합니다.

사용 가능한 첫 번째 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()추가 속성을 지정할 수 있습니다.

다음 코드 예제는 일련번호를 사용하여 블레이즈 카메라를 여는 방법을 보여줍니다.

// 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 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 항목을 참조하십시오.

사전 정의된 카메라 매개변수 구성#

블레이즈 카메라의 경우, 다음과 같은 것이 있습니다. 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

The BlazeConfigurations 다음과 같은 구성 방법을 제공합니다:

  • AcquirePointCloudsContinuously
    데이터를 지속적으로 수집합니다. 깊이 데이터는 포인트 클라우드로 표현됩니다.
  • AcquireDepthMapsContinuously
    데이터를 지속적으로 수집합니다. 수심 데이터는 수심 맵으로 표시됩니다.

pylon의 구성 이벤트 핸들러에 대해 자세히 알아보려면 pylon .NET 프로그래머 가이드의 “사전 정의된 카메라 매개변수 구성” 섹션을 참조하십시오.

깊이 데이터 해석#

'측정 결과 처리' 항목에서는 '범위' 데이터 구성 요소에 저장된 깊이 데이터의 형식에 대한 정보를 제공합니다.

카메라 연결#

카메라 객체를 생성하고 구성 이벤트 핸들러를 등록한 후, 다음 메서드를 호출하여 CBlazeInstantCamera::Open() 메서드를 호출하여 매개변수를 설정할 수 있습니다.

카메라와의 연결이 수립됩니다. 연결은 다음 CBlazeInstantCamera::Close() 메서드가 호출됩니다. 의 소멸자는 Camera 클래스 호출 Close() 명시적으로 호출되지 않은 경우 자동으로 호출됩니다. 카메라 객체의 수명을 명시적으로 제어하려면, Basler는 위 코드 예시에서 볼 수 있듯이 using 문 내에서 카메라 객체를 사용할 것을 권장합니다.

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

파라미터 접근#

pylon .NET 프로그래머 가이드의 ‘매개변수 액세스’ 섹션을 참조하여 pylon .NET API를 사용하여 카메라 매개변수에 액세스하는 방법을 숙지하십시오.

pylon .NET API는 Visual Studio의 IntelliSense 기능을 활용하여 카메라 매개변수에 편리하게 접근할 수 있는 매개변수 목록을 제공합니다.

블레이즈 카메라의 경우, 다음과 같은 것이 있습니다. 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 프로그래머 가이드의 “이미지 캡처” 섹션을 참조하여 pylon .NET API를 사용하여 데이터를 수집하는 방법을 숙지하십시오.

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

blaze 카메라로 캡처한 GrabResults에는 여러 구성 요소가 포함되어 있습니다. 기본적으로 각 GrabResult는 강도 이미지, 신뢰도 맵, 깊이 정보를 저장합니다.

Range 컴포넌트에 설정된 픽셀 형식에 따라, 깊이 데이터는 2D 깊이 맵이나 3D 포인트 클라우드로 표현될 수 있습니다.

정보

카메라가 포인트 클라우드와 깊이 맵 형태의 깊이 정보를 동시에 전송하도록 설정할 수는 없습니다.

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

그랩 루프#

pylon은 이미지 취득 루프를 설정하는 다양한 접근 방식을 지원하며, 메모리 버퍼를 처리하기 위한 여러 가지 전략을 제공합니다.

자세한 내용은 pylon .NET 프로그래머 가이드의 “이미지 가져오기” 섹션을 참조하십시오.

다음 코드 예제는 일반적인 그랩 루프를 보여줍니다:

// 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 프로그래머 가이드의 “다중 구성 요소 Grab 결과” 섹션을 참조하십시오.

예:

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

깊이 데이터 해석#

'측정 결과 처리' 항목에서는 '범위' 데이터 구성 요소에 저장된 깊이 데이터의 형식에 대한 정보를 제공합니다.

애플리케이션 디버깅 및 GigE Vision 하트비트 제어#

pylon 7.0 이하 버전을 사용할 때의 재연결 문제

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

이러한 현상은 주로 디버거를 사용하여 애플리케이션을 중지하거나 애플리케이션이 예기치 않게 종료될 때 발생합니다. 카메라를 다시 열려면 타임아웃이 만료될 때까지 기다리거나 네트워크에서 카메라를 일시적으로 분리해야 합니다.

이를 해결하려면, 디버거 제어 하에 애플리케이션이 실행되는 동안 다음 환경 변수를 설정하여 하트비트 타임아웃의 자동 조정을 재정의할 수 있습니다. GEV_HEARTBEAT_TIMEOUT 원하는 타임아웃 값을 밀리초 단위로 설정합니다. 또는 샘플 프로그램에 표시된 것처럼 pylon API를 사용하여 애플리케이션에서 하트비트 타임아웃을 설정할 수 있습니다. DeviceRemovalCSharp 및 DeviceRemovalVB 예제 프로그램.