이미지 처리#
이미지 표현#
pypylon에서는 이미지가 NumPy 배열 등의 형태로 노출되므로, 과학 및 머신 비전 워크플로우에서 직접 사용할 수 있습니다.
다음은 일반적인 작업 흐름입니다:
이미지 데이터에 접근하기#
그랩 결과에서 데이터를 언제 복사해야 하고 언제 복사하지 말아야 하는지 파악하는 것이 중요합니다. 너무 많이 복사하면 시간이 낭비되고, 너무 적게 복사하면 프로그램이 중단되거나 픽셀 데이터가 잘못될 수 있습니다.
| 코드 | 설명 | 복사해야 하나요? |
|---|---|---|
.Array | NumPy 복사본을 반환합니다. | 아니요 (이미 사본이 있음) |
.GetMemoryView() | 버퍼 뷰를 반환합니다. | 예 |
.GetArrayZeroCopy() | 제로 카피 배열을 반환합니다. | 예 |
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
이미지 모양 및 형식#
배열의 형태는 픽셀 형식에 따라 달라집니다:
| Pixel Format | 모양 예시 |
|---|---|
| Mono8 | (높이, 너비) |
| RGB8/BGR8 | (높이, 너비, 3) |
모양을 직접 확인할 수 있습니다:
Pixel Format 변환#
카메라 설정에 따라 RAW 이미지 형식이 적합하지 않을 수 있으며, 변환이 필요할 수 있습니다.
예시: BGR 형식으로 변환하기 (OpenCV 호환)
converter = pylon.ImageFormatConverter()
converter.OutputPixelFormat = pylon.PixelType_BGR8packed
image = converter.Convert(grab_result).GetArray()
정보
에서 ImageFormatConverter, OutputPixelFormat 매개변수 노드가 아닌, 픽셀 유형의 값을 저장하는 일반 속성입니다. 이 속성에 직접 값을 할당하십시오 (converter.OutputPixelFormat = pylon.PixelType_BGR8packed). 여기에는 .Value 액세서리.
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 (검색 결과, a PylonImage, 데이터 구성 요소, 또는 그 밖의 어떤 IImage), 그리고 그 결과로 생성된 배열의 차원과 데이터 유형은 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 기본적으로 이를 위해. Pass 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 | 예 |
converter.ConvertToArray(src) | NumPy 배열을 제자리에서 쓰기 | 아니요 |
converter.ConvertToArray(src, raw=True) | 평면 uint8 배열 (압축 형식에도 적용됨) | 아니요 |
전환이 필요한 이유#
- 카메라는 대개 RAW 또는 베이어 형식으로 이미지를 출력합니다.
- 일반적으로 애플리케이션에서는 다음을 기대합니다:
- 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#
항상 픽셀 형식을 확인하거나 명시적으로 설정해야 합니다. 이를 무시할 경우 다음과 같은 결과가 발생할 수 있습니다:
- 색상 해석 오류
- 잘못된 처리 결과
성능 오버헤드#
다음과 같은 조치는 성능을 저하시킬 수 있습니다:
- 대용량 이미지를 복사하는 데는 시간이 걸립니다
- 변환 작업은 CPU 부하를 증가시킵니다
이를 방지하기 위한 전략:
- 관심 영역(ROI) 축소 (「 카메라 매개변수 구성」 참조)
- 불필요한 변환 피하기
처리 파이프라인에서 이미지 사용하기#
이미지는 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 배열 형태로 제공됩니다.
- 필요할 때는 항상 버퍼 데이터를 복사하십시오.
- 올바른 픽셀 형식을 사용하고 있는지 확인하십시오.
- 후속 처리를 위해 변환이 필요할 수 있습니다.