이미지 처리#
Image Representation#
pypylon에서 이미지는 예컨대 NumPy array로 노출되므로, 과학 및 머신비전 워크플로에서 직접 사용할 수 있습니다.
다음은 일반적인 워크플로입니다.
Accessing Image Data#
그랩 결과에서 데이터를 복사해야 하는 시기와 복사하지 않아야 하는 시기를 아는 것이 중요합니다. 불필요하게 복사하면 시간이 낭비되고, 너무 적게 복사하면 충돌이나 잘못된 Pixel Format 데이터가 발생할 수 있습니다.
| 코드 | 설명 | 복사가 필요합니까? |
|---|---|---|
.Array | NumPy 복사본을 반환합니다. | 아니요(이미 복사본임) |
.GetMemoryView() | 버퍼 뷰를 반환합니다. | 예 |
.GetArrayZeroCopy() | 제로 복사(zero-copy) array를 반환합니다. | 예 |
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()이(가) 호출될 때까지. - 버퍼가 해제된 후 메모리 뷰나 제로 코피 배열에 접근하면 유효하지 않은 메모리 접근이 발생할 수 있습니다.
올바른 사용법:
with camera.RetrieveResult(5000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
Image Shape and Format#
배열의 형태(shape)는 Pixel Format에 따라 다릅니다.
| Pixel Format | 형태 예시 |
|---|---|
| Mono8 | (높이, 너비) |
| RGB8/BGR8 | (높이, 너비, 3) |
형태를 직접 확인할 수 있습니다:
Pixel Format 변환#
카메라 구성에 따라 로우 이미지 포맷이 적합하지 않을 수 있으며 변환이 필요할 수 있습니다.
예시: BGR로 변환 (OpenCV 호환)
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
image = converter.Convert(grab_result).GetArray()
정보
에서 ImageFormatConverter, OutputPixelFormat 은(는) 파라미터 노드가 아니라 픽셀 타입 값을 보유하는 일반 속성입니다. 직접 할당하세요(converter.OutputPixelFormat = pylon.PixelType_BGR8packed). 이 속성에는 .Value accessor이(가) 없습니다.
NumPy 배열로 직접 변환(ConvertToArray)#
converter.Convert(src) )은(는) 다음을 반환합니다 PylonImage. 픽셀을 읽는 작업( .Array (또는 .GetArray())은(는) 변환된 버퍼의 추가 복사본 을(를) 생성합니다. 결과가 NumPy 배열로만 필요한 경우 대신 converter.ConvertToArray(src) 을(를) 사용하세요. 이렇게 하면 올바른 형태와 데이터 타입을 가진 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 (grab 결과, a PylonImage, data component 또는 기타 IImage)이며, 생성된 배열의 shape 및 data type은 다음을 반영합니다. OutputPixelFormat:
PixelType_Mono8→(height, width),uint8PixelType_Mono16→(height, width),uint16PixelType_RGB8packed/PixelType_BGR8packed→(height, width, 3),uint8
비트 팩킹된 출력 형식(다음 항목이 pylon.IsPacked(pixel_type) 인 경우)은 명확한 NumPy shape/data type이 없으므로, ConvertToArray 은(는) ValueError 을(를) 기본적으로 발생시킵니다. 대신 raw=True 을(를) 전달하여 변환된 바이트를 1차원 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 | 예 |
converter.ConvertToArray(src) | 제자리(in-place)에 작성된 NumPy 배열 | 아니요 |
converter.ConvertToArray(src, raw=True) | 1차원 uint8 배열 (팩킹된 형식에도 적용) | 아니요 |
변환이 필요한 이유#
- 카메라는 종종 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 이(가) 유효하지 않은 메모리를 참조할 수 있기 때문입니다. 블록 외부에서 사용해야 하는 경우 항상 result.Array 을(를) 사용하거나 grab_result 을(를) 유지하십시오.
Pixel Format 무시하기#
Pixel Format을 항상 확인하거나 명시적으로 설정하십시오. 이를 무시하면 다음과 같은 문제가 발생할 수 있습니다.
- 잘못된 색상 해석
- 잘못된 처리 결과
성능 오버헤드#
다음 작업으로 인해 성능이 저하될 수 있습니다:
- 큰 이미지 복사에는 시간이 소요됩니다.
- 변환 작업은 CPU 부하를 증가시킵니다.
이를 방지하기 위한 전략:
- 관심 영역(ROI) 축소 (카메라 파라미터 구성 참조)
- 불필요한 변환 방지
처리 파이프라인에서의 이미지 사용#
이미지가 NumPy 배열 형식이므로 OpenCV, NumPy Operations 및 AI/ML Frameworks에서 직접 사용할 수 있습니다.
이는 이미지 파이프라인의 일반화된 예시입니다.
이는 대부분의 머신 비전 시스템에서 핵심적인 데이터 흐름을 나타냅니다.
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을 사용하고 있는지 확인하십시오.
- 후속 처리를 위해 변환이 필요할 수 있습니다.