콘텐츠로 바로 가기
STAGING SERVER
DEVELOPMENT SERVER

멀티 카메라 시스템#

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

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

일반적인 사용 사례:

  • 객체의 다양한 시점 캡처
  • 시야(Field of View) 확대
  • 처리량(Throughput) 증가
  • 여러 객체의 병렬 검사

근본적인 과제#

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

  • 동기화(타이밍)
  • 대역폭 제한(특히 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)

이렇게 하면 장치당 하나의 카메라 인스턴스가 생성되고 열립니다.

획득 방식#

여러 카메라는 사용할 때는 순차(sequential) 또는 병렬(parallel) 중 하나의 획득 방식을 결정해야 합니다.

순차적 획득#

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

Cam1 → Capture → Process
Cam2 → Capture → Process

이 방식의 주요 특징:

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

병렬 취득#

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

Cam1 → Capture →
                → Process
Cam2 → Capture →

이 방식의 주요 특징:

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

동기화 방법#

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

소프트웨어 동기화#

이 방식의 주요 특징:

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

예:

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

이 방식의 주요 특징:

  • 정밀한 타이밍
  • 결정론적(deterministic) 동작
  • 스테레오 또는 측정 시스템에 필수적

대역폭 고려 사항(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, 네트워크)를 모니터링하십시오.

일반적인 문제점#

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

멘탈 모델#

Multiple Cameras → Acquisition → Buffers → Processing → Results

주요 핵심 사항#

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