이미지 작업#
이미지 표현#
pypylon에서 이미지는 예를 들어 NumPy arrays로 노출되므로, 과학 및 머신비전 워크플로에서 직접 사용할 수 있습니다.
다음은 일반적인 워크플로입니다.
이미지 데이터 액세스#
그랩 결과에서 데이터를 복사해야 하는 시기와 복사하지 않아야 하는 시기를 아는 것이 중요합니다. 불필요하게 너무 많이 복사하면 시간이 낭비되고, 너무 적게 복사하면 충돌이나 잘못된 픽셀 데이터가 발생할 수 있습니다.
| 코드 | 설명 | 복사 필요 여부 |
|---|---|---|
.Array | NumPy 복사본 반환 | 아니요(이미 복사본임) |
.GetMemoryView() | 버퍼 뷰 반환 | Yes |
.GetArrayZeroCopy() | 제로 카피 배열 반환 | Yes |
grab_result.Array내부 버퍼의 복사본입니다.grab_result.GetMemoryView()다음입니다: 내부 버퍼에 대한 뷰 (픽셀 형식 제외:pylon.IsPacked(grab_result.PixelType)가 True인 경우).grab_result.GetArrayZeroCopy()다음입니다: 내부 버퍼에 대한 뷰 복사 없이 NumPy 배열 제공 (단, 픽셀 형식의 경우는 예외:pylon.IsPacked(grab_result.PixelType)가 True인 경우).- 그랩 결과 버퍼는 다음을 벗어날 때 해제됩니다.
with블록 또는grab_result.Release()이(가) 호출될 때까지 취득 모드 상태를 유지합니다. - 버퍼가 해제된 후 Memory 뷰나 제로 코피(zero-copy) 배열에 액세스하면 잘못된 Memory 액세스가 발생할 수 있습니다.
올바른 사용법:
with camera.RetrieveResult(5000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
Image Shape 및 Format#
배열의 Shape은 Pixel Format에 따라 다릅니다:
| Pixel Format | Shape 예시 |
|---|---|
| Mono8 | (높이, 너비) |
| RGB8/BGR8 | (높이, 너비, 3) |
Shape을 직접 확인할 수 있습니다:
Pixel Format Conversion#
카메라 구성에 따라 원본 이미지 형식이 적합하지 않을 수 있으며 변환이 필요할 수 있습니다.
예시: BGR로 변환 (OpenCV 호환)
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
image = converter.Convert(grab_result).GetArray()
정보
In ImageFormatConverter, OutputPixelFormat 은(는) parameter 노드가 아니라 픽셀 타입 값을 보유하는 일반 속성입니다. 직접 할당하세요(converter.OutputPixelFormat = pylon.PixelType_BGR8packed). 이것은 다음과 같은 기능이 없습니다. .Value accessor.
NumPy 배열로 직접 변환(ConvertToArray)#
converter.Convert(src) 반환 값은 PylonImage. 픽셀을 읽을 때 .Array (또는 .GetArray()), 추가 복사본 생성 변환된 버퍼의 결과가 NumPy 배열로만 필요한 경우 사용하세요. converter.ConvertToArray(src) 대신, 올바른 Shape과 데이터 유형을 가진 NumPy 배열을 미리 할당하고 변환기가 변환된 픽셀을 작성할 수 있도록 합니다. 해당 배열에 직접, 추가 복사를 방지합니다.
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
# Equivalent result to converter.Convert(grab_result).Array, but without the extra copy.
image = converter.ConvertToArray(grab_result)
ConvertToArray 은(는) 다음의 소스 유형을 허용합니다. Convert (그랩 결과, PylonImage, 데이터 컴포넌트 또는 기타 IImage)이며, 생성된 배열의 형태(shape)와 데이터 유형은 다음을 반영합니다. OutputPixelFormat:
PixelType_Mono8→(height, width),uint8PixelType_Mono16→(height, width),uint16PixelType_RGB8packed/PixelType_BGR8packed→(height, width, 3),uint8
비트 팩 형식(다음의 경우 pylon.IsPacked(pixel_type) 이(가) True인 형식)은 모호하지 않은 NumPy 형태/데이터 유형을 가지지 않으므로, ConvertToArray 은(는) 기본적으로 이에 대해 ValueError 을(를) 발생시킵니다. 대신 변환된 바이트를 1차원 raw=True 배열로 얻으려면 uint8 을(를) 전달하세요.
# raw=True returns a flat uint8 array of the converted bytes,
# which is also how to handle bit-packed output formats.
raw_bytes = converter.ConvertToArray(grab_result, raw=True)
| 접근 방식 | 결과 | 추가 복사 여부 |
|---|---|---|
converter.Convert(src).Array | 중간 단계를 거치는 NumPy 배열 PylonImage | Yes |
converter.ConvertToArray(src) | 제자리(in-place)에 작성되는 NumPy 배열 | No |
converter.ConvertToArray(src, raw=True) | 1차원 uint8 배열(팩 형식의 경우에도 해당) | No |
변환이 필요한 이유#
- 카메라는 종종 RAW 또는 Bayer 형식을 출력합니다.
- 응용 프로그램은 일반적으로 다음을 예상합니다.
- BGR (OpenCV)
- RGB (시각화)
일반적인 문제점#
버퍼 해제 후 데이터 사용#
with camera.RetrieveResult(...) as grab_result:
image = grab_result.Array # NumPy array
memory_view = grab_result.GetMemoryView()
with grab_result.GetArrayZeroCopy() as zero_copy_array:
... process zero_copy_array (NumPy array) ...
이것은 안전하지 않습니다. memory_view 이(가) 이제 유효하지 않은 memory를 참조할 수 있기 때문입니다. 항상 다음을 사용하세요. result.Array 블록 외부에 필요하거나 유지 grab_result 활성화 상태 유지.
Pixel Format 무시#
Pixel Format을 항상 확인하거나 명시적으로 설정하십시오. 이를 무시할 경우 다음과 같은 결과가 발생할 수 있습니다.
- 잘못된 색상 해석
- 잘못된 처리 결과
성능 오버헤드#
다음 작업으로 인해 성능이 저하될 수 있습니다.
- 대용량 이미지 복사에 시간 소요
- 변환으로 인한 CPU 부하 증가
이를 방지하기 위한 전략:
- ROI(Region of Interest) 축소 (카메라 파라미터 설정 참조)
- 불필요한 변환 방지
처리 파이프라인에서 이미지 사용#
이미지는 NumPy 배열이므로 OpenCV, NumPy 연산 및 AI/ML 프레임워크에서 직접 사용할 수 있습니다.
이것은 이미지 파이프라인의 일반화된 도해입니다.
이는 대부분의 컴퓨터 비전 시스템의 중심적인 데이터 흐름을 나타냅니다.
OpenCV#
NumPy 연산#
AI/ML 프레임워크#
- PyTorch
- TensorFlow
NumPy를 사용하는 샘플 이미지 처리 파이프라인#
NumPy를 사용하면 획득한 이미지에 대해 빠르고 벡터화된 이미지 처리를 직접 수행할 수 있습니다.
다음 샘플은 NumPy를 사용하는 작지만 현실적인 이미지 처리 파이프라인입니다.
샘플 코드#
import numpy as np
from pypylon import pylon
with pylon.InstantCamera(pylon.FirstFound) as camera:
camera.StartGrabbingMax(100)
while camera.IsGrabbing():
with camera.RetrieveResult(5000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
# Do something with the image data.
if image.ndim == 3:
gray = image.mean(axis=2)
else:
gray = image
norm = gray / 255.0
binary = norm > 0.5
mean_intensity = norm.mean()
bright_pixel_ratio = binary.mean()
print(f"Mean intensity: {mean_intensity:.3f}")
print(f"Bright pixels: {bright_pixel_ratio*100:.1f}%")
개별 단계에 대한 설명은 다음과 같습니다.
-
그레이스케일 변환:
-
정규화:
-
임계값 처리:
-
통계적 평가:
일반적인 NumPy 이미지 파이프라인은 다음과 같습니다.
주요 내용 요약#
- 이미지는 NumPy 배열로 제공됩니다.
- 필요한 경우 항상 버퍼 데이터를 복사하십시오.
- 올바른 Pixel Format을 사용하고 있는지 확인하십시오.
- 후속 처리를 위해 변환이 필요할 수 있습니다.