콘텐츠로 건너뛰기
STAGING SERVER
DEVELOPMENT SERVER

멀티 카메라 시스템#

이 주제에서는 여러 카메라를 동시에 사용하는 시스템을 설계, 구성 및 운영하는 방법에 대해 설명합니다.

멀티 카메라 설정은 검사, 3D 재구성, 동기화된 데이터 취득과 같은 산업용 응용 분야에서 흔히 사용됩니다. 단일 카메라만으로는 필요한 모든 정보를 캡처하기에 충분하지 않을 때 사용됩니다.

일반적인 사용 사례:

  • 객체의 다양한 시점 캡처
  • 시야각 확장
  • 처리량 증가
  • 여러 객체의 병렬 검사

근본적인 과제#

여러 카메라를 사용하면 다음과 같은 여러 가지 과제가 발생합니다:

  • 동기화 (타이밍)
  • 대역폭 제한 (특히 GigE 카메라를 사용할 때)
  • CPU 부하 (다중 스트림 처리)
  • 장치 식별 및 매핑

장치 식별#

각 카메라는 고유 식별자(일반적으로 일련번호)를 가져야 합니다.

for device_info in device_info_list:
    print(device_info.GetSerialNumber())

매핑 예시:

Camera 40123456 → Left view
Camera 40123478 → Right view

다음과 같은 인덱스 사용을 피하십시오: 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)

이 작업은 디바이스당 하나의 카메라 인스턴스를 생성하고 엽니다.

취득 방식#

여러 카메라를 사용할 때는 순차적 방식과 병렬 방식 중 하나의 취득 방식을 결정해야 합니다.

순차적 취득#

즉, 이미지 처리가 한 카메라씩 차례대로 수행됩니다.

Cam1 → Capture → Process
Cam2 → Capture → Process

이 방식의 주요 특징:

  • 구현이 간단함
  • 시간 동기화되지 않음
  • 전체적인 속도가 느림

병렬 취득#

즉, 여러 카메라의 이미지가 함께 처리됩니다.

Cam1 → Capture →
                → Process
Cam2 → Capture →

이 방식의 주요 특징:

  • 카메라가 동시에 취득함
  • 동기화에 필요함
  • 더 높은 CPU 및 대역폭 요구 사항

동기화 방법#

카메라를 동기화하려면 소프트웨어 동기화와 하드웨어 동기화 중 하나를 선택할 수 있습니다. 장단점은 소프트웨어 대 하드웨어 트리거와 유사합니다.

소프트웨어 동기화#

이 방식의 주요 특징:

  • 소프트웨어를 통한 카메라 트리거
  • 제한된 정밀도
  • 운영 체제 스케줄링의 영향 받음

예:

camera.ExecuteSoftwareTrigger()
Master camera → trigger signal → Slave cameras

이 방식의 주요 특징:

  • 정밀한 타이밍
  • 결정론적 동작
  • 스테레오 또는 측정 시스템에 필요함

대역폭 고려사항 (GigE)#

여러 GigE 카메라는 동일한 네트워크 대역폭을 공유합니다.

잠재적 문제:

  • 패킷 손실
  • 프레임 드롭
  • 지연 시간 증가

잠재적 문제를 완화하기 위해 다음 전략 중 하나를 사용할 수 있습니다.

  • 전용 네트워크 인터페이스 카드(NIC) 사용
  • 점보 프레임 활성화(MTU 9000)
  • ROI 또는 프레임 레이트 줄이기
  • 패킷 딜레이 설정

프로세싱 아키텍처#

싱글 스레드#

Acquire all → process all
  • 간단함
  • 제한된 확장성
Camera threads → queue → processing threads
  • 확장 가능
  • 더 나은 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)

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)
  • 더 간단한 동기화 처리
  • 더 효율적인 스레드 사용

개념적으로:

Multiple Cameras → InstantCameraArray → Unified RetrieveResult() → Processing

실무 설계 지침#

  • 카메라는 항상 시리얼 번호로 식별해야 합니다.
  • 하드웨어 동기화를 우선적으로 사용하십시오.
  • 가능하면 (예: ROI를 지정하거나 프레임 레이트를 낮추어) 대역폭을 줄이십시오.
  • 확장성을 위해 별도의 처리 스레드를 사용하십시오.
  • 시스템 부하(CPU, 네트워크)를 모니터링하십시오.

일반적인 문제점#

  • 디바이스 인덱스에 의존하는 방식입니다.
  • 네트워크 대역폭을 초과하는 경우입니다.
  • 동기화 요구 사항을 무시하는 경우입니다.
  • 획득 루프에서 처리를 차단하는 경우입니다.

Mental Model#

Multiple Cameras → Acquisition → Buffers → Processing → Results

주요 내용 요약#

  • 멀티 카메라 시스템은 신중한 설계가 필요합니다.
  • 동기화는 많은 어플리케이션에서 매우 중요합니다.
  • 대역폭과 CPU는 초기 단계부터 고려해야 합니다.
  • 확장 가능한 아키텍처는 병렬 처리를 사용합니다.