멀티 카메라 시스템#
다중 카메라 구성은 검사, 3D 재구성, 동기화된 데이터 수집과 같은 산업용 응용 분야에서 흔히 사용됩니다. 이는 단일 카메라로는 필요한 모든 정보를 포착하기에 충분하지 않을 때 활용됩니다.
일반적인 사용 사례:
- 사물의 다양한 관점을 담아내기
- 시야각 확대
- 처리량 증대
- 여러 개체의 병렬 검사
근본적인 과제#
여러 대의 카메라를 사용하면 다음과 같은 몇 가지 어려움이 발생합니다:
- 동기화 (타이밍)
- 대역폭 제한 (특히 GigE 카메라를 사용할 때)
- CPU 부하 (여러 스트림 처리 시)
- 장치 식별 및 매핑
기기 식별#
각 카메라에는 고유 식별자(일반적으로 일련번호)가 있어야 합니다.
매핑 예시:
다음과 같은 인덱스는 사용하지 마십시오. devices[0] 카메라가 열거되는 순서가 바뀔 수 있기 때문입니다. 자세한 내용은 다음을 참조하십시오. 카메라 열거하기.
여러 카메라 인스턴스 생성하기#
from pypylon import pylon
factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()
cameras = []
for device_info in device_info_list:
camera = pylon.InstantCamera(factory.CreateDevice(device_info))
camera.Open()
cameras.append(camera)
이렇게 하면 기기당 하나의 카메라 인스턴스를 생성하고 엽니다.
취득 방법#
여러 대의 카메라를 사용할 때는 획득 방식을 순차 방식과 병렬 방식 중 하나로 결정해야 합니다.
순차적 인수#
즉, 이미지 처리가 카메라별로 차례대로 이루어진다는 뜻입니다.
이 방법의 주요 특징:
- 구현하기 간편하다
- 시간 동기화가 되어 있지 않음
- 전반적으로 더 느림
병렬 취득#
이는 여러 대의 카메라에서 촬영된 영상이 함께 처리된다는 것을 의미합니다.
이 방법의 주요 특징:
- 카메라들이 동시에 영상을 촬영합니다
- 동기화를 위해 필수
- 더 높은 CPU 및 대역폭 요구 사항
동기화 방법#
카메라를 동기화할 때는 소프트웨어 동기화와 하드웨어 동기화 중에서 선택할 수 있습니다. 각각의 장단점은 소프트웨어 트리거링과 하드웨어 트리거링의 장단점과 유사합니다.
소프트웨어 동기화#
이 방법의 주요 특징:
- 소프트웨어를 통해 카메라 작동하기
- 정밀도 제한
- 운영 체제의 스케줄링에 영향을 받음
예:
하드웨어 동기화 (권장)#
이 방법의 주요 특징:
- 정확한 타이밍
- 결정론적 동작
- 스테레오 또는 측정 시스템에 필수적입니다.
대역폭 고려 사항 (GigE)#
여러 대의 GigE 카메라가 동일한 네트워크 대역폭을 공유합니다.
발생할 수 있는 문제:
- 패킷 손실
- 프레임 누락
- 지연 시간 증가
잠재적인 문제를 완화하기 위해 다음 전략 중 하나를 사용할 수 있습니다:
- 전용 네트워크 인터페이스 카드(NIC)를 사용하십시오
- 점보 프레임 활성화 (MTU 9000)
- ROI 또는 프레임 속도를 낮추세요
- 패킷 지연 시간 설정
처리 아키텍처#
단일 스레드#
- 간단한
- 제한된 확장성
다중 스레드 (권장)#
- 확장 가능
- CPU 활용도 향상
- 구현하기가 더 복잡하다
예시 패턴#
기본 멀티 카메라 루프 (순차적 폴링)#
from pypylon import pylon
def process(image):
print(image.shape)
factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()
cameras = [pylon.InstantCamera(factory.CreateDevice(device_info)) for device_info in device_info_list]
for camera in cameras:
camera.Open()
camera.StartGrabbing()
while any(camera.IsGrabbing() for camera in cameras):
for camera in cameras:
if camera.IsGrabbing():
with camera.RetrieveResult(1000) as grab_result:
if grab_result.GrabSucceeded():
image = grab_result.Array
# Do processing on image here, e.g. call a function.
process(image)
고급 방법: InstantCameraArray (권장)#
pypylon은 다중 카메라 구성을 위한 전용 추상화 계층을 제공합니다: InstantCameraArray.
이 클래스는 여러 대의 카메라를 관리하며, 단일 통합 RetrieveResult() 전화, 어떤 카메라로 촬영된 이미지인지에 대한 정보도 포함됩니다.
from pypylon import pylon
def process(image):
print(image.shape)
COUNT_OF_IMAGES_TO_GRAB = 100
RETRIEVE_TIMEOUT_MS = 5000
factory = pylon.TlFactory.GetInstance()
device_info_list = factory.EnumerateDevices()
with pylon.InstantCameraArray(len(device_info_list)) as cameras:
for i, camera in enumerate(cameras):
camera.Attach(factory.CreateDevice(device_info_list[i]))
print("Using device:", camera.DeviceInfo.ModelName)
cameras.StartGrabbing()
for i in range(COUNT_OF_IMAGES_TO_GRAB):
if not cameras.IsGrabbing():
break
with cameras.RetrieveResult(
RETRIEVE_TIMEOUT_MS,
pylon.TimeoutHandling_ThrowException
) as grab_result:
if grab_result.GrabSucceeded():
cam_idx = grab_result.CameraContext
print(f"Camera {cam_idx}: {cameras[cam_idx].DeviceInfo.ModelName}")
image = grab_result.Array
# Do processing on image here, e.g. call a function.
process(image)
else:
print("Error:", grab_result.ErrorDescription)
왜 InstantCameraArray 중요합니다
수동 루핑과 비교했을 때, 이 방식은 다음과 같은 이점을 제공합니다:
- 모든 카메라를 위한 단일 획득 루프
- 자동 카메라 컨텍스트 추적 (
camera.CameraContext) - 더 간편한 동기화 처리
- 더 효율적인 스레드 사용
개념적으로:
실용적인 디자인 지침#
- 카메라는 항상 일련번호로 식별하십시오.
- 하드웨어 동기화를 선호합니다.
- 가능한 경우 대역폭을 줄이십시오(예: ROI를 지정하거나 프레임 속도를 낮추는 방법 등).
- 확장성을 위해 별도의 처리 스레드를 사용하십시오.
- 시스템 부하(CPU, 네트워크)를 모니터링합니다.
흔히 범하는 실수#
- 장치 인덱스를 기반으로 합니다.
- 네트워크 대역폭을 초과했습니다.
- 동기화 요구 사항을 무시함.
- 획득 루프에서 처리 차단 중입니다.
멘탈 모델#
주요 핵심 사항#
- 다중 카메라 시스템은 신중한 설계가 필요합니다.
- 동기화는 많은 애플리케이션에서 매우 중요합니다.
- 대역폭과 CPU는 초기 단계부터 고려해야 합니다.
- 확장 가능한 아키텍처는 병렬 처리를 활용합니다.