Synchronization of Asynchronous Image Pipelines

연산자 유형 및 동기화에 대한 실용적인 지침은 Operator Types and Synchronization 튜토리얼 항목을 참조하십시오.

카메라 동기화

VisualApplets의 강력한 기능 중 하나는 다양한 카메라 소스의 이미지를 결합하는 것입니다. 다음에서는 다음 방법에 대해 알아보겠습니다.

  1. 카메라 소스 간 전환
  2. 두 카메라의 이미지 오버레이
  3. 카메라 이미지 멀티플렉싱
  4. 두 카메라의 이미지 스티칭

Switch Between two Cameras

두 카메라 간에 전환하려면 두 개의 카메라 모듈이 포함된 간단한 디자인이 필요합니다. VisualApplets에서는 'SourceSelector' 오퍼레이터를 사용하여 두 비동기 소스 간에 전환할 수 있습니다. 이 오퍼레이터를 사용하면 다른 입력의 데이터가 버려지는 동안 입력 중 하나를 선택할 수 있습니다. 입력 중 하나가 선택되면 나머지는 Trash 오퍼레이터에 연결된 것처럼 동작합니다. 획득이 진행되는 동안에도 입력을 전환할 수 있습니다. 오퍼레이터는 새 프레임이 시작될 때 전환됩니다. 두 입력의 프레임 속도와 이미지 크기가 같을 필요는 없습니다.

두 카메라 간 전환을 위한 VisualApplets 디자인

그림 208. 두 카메라 간 전환을 위한 VisualApplets 디자인


두 카메라 소스의 이미지 데이터 결합 - 오버레이 블렌드 빌드

다음으로, 두 카메라의 이미지 데이터를 결합하는 방법에 대해 살펴보겠습니다. 예제에서는 두 이미지를 결합하기 위해 오버레이 블렌드(overlay-blend)를 사용합니다.

예제의 사양은 다음과 같습니다.

  • 카메라: 베이스 구성 모드의 두 대의 CameraLink RGB 영역 스캔 카메라
  • 해상도: 1024 x 1024 픽셀
  • 오버레이 블렌드:

    수식 1. 오버레이 블렌드


  1. 기본 오퍼레이터

    다음 그림과 같이 디자인의 기본 오퍼레이터부터 시작합니다. 모든 기본 파라미터와 링크 속성을 사용할 수 있습니다.

  2. Synchronization

    다음으로 두 카메라의 데이터 스트림을 동기화해야 합니다. 이는 SYNC 오퍼레이터를 사용하여 간단하게 수행할 수 있습니다. SYNC 오퍼레이터는 출력이 완전히 동기화되도록 입력을 제어합니다. 보시다시피 동기화 전에 두 개의 버퍼 모듈을 사용했습니다. 두 카메라인 100% 동기화 상태를 보장할 수 없으므로 이를 사용해야 합니다.

    이미지 데이터를 동기화했더라도 몇 가지 제약 사항에 주의해야 합니다.

    • 두 카메라이 프레임 수, 즉 프레임 속도가 동일해야 합니다. 한 카메라의 프레임 속도가 다른 카메라보다 높으면 ImageBuffer 모듈 중 하나에 일부 이미지를 저장해야 하므로 overflow 상태가 발생할 수 있습니다. 따라서 장시간 획득을 위해서는 두 카메라가 동일한 프레임 속도를 사용하여 프레임을 획득해야 합니다. 트리거 시스템을 통해 이를 보장할 수 있습니다.

    • 두 카메라의 ROI 이미지 크기와 이미지 위치는 다를 수 있습니다. SYNC 오퍼레이터는 파라미터 설정에 따라 자동으로 작은 이미지를 큰 이미지에 맞춰 확장하거나 큰 이미지를 잘라냅니다. 자세한 내용은 SYNC 오퍼레이터 설명을 참조하십시오: ('SYNC')
  3. 오버레이 블렌드

    마지막 단계는 두 이미지를 결합하기 위해 오버레이 블렌드를 구현하는 것입니다. 편의를 위해 오버레이 블렌드 구현에 계층적 상자(hierarchical box)를 사용합니다.

    오버레이 블렌드는 모든 색상 성분에 개별적으로 적용되어야 합니다. 따라서 링크를 세 가지 색상 성분 모두로 분할해야 합니다. 오버레이 블렌드는 계층적 상자 내부에 다시 배치됩니다. 결과적으로 현재 계층적 상자 내부에 세 개의 계층적 상자가 있게 됩니다. 복사 및 붙여넣기를 사용하여 각 색상 성분용 상자를 복제할 수 있습니다.

    VisualApplets 오퍼레이터를 사용하여 위에 제시된 방정식을 실현하는 다양한 방법이 있습니다. 일반적으로 구현하기 전에 FPGA 사용에 맞게 방정식을 조정하고 최적화하려고 시도해야 합니다.

    방정식에는 상숫값과의 곱셈 및 나눗셈이 포함되어 있습니다. 이러한 연산은 VisualApplets에서 사용할 수 있지만 FPGA에서 매우 효율적으로 구현되지는 않습니다. 곱셈이나 나눗셈을 2의 거듭제곱 곱셈으로 작성할 수 있는 경우 구현을 위해 간단한 비트 시프트를 사용할 수 있습니다. 비트 시프트에는 리소스가 전혀 필요하지 않습니다! 다음 사항을 단순화하겠습니다.

    에서

    즉 7비트 오른쪽 시프트로, 하위 7비트를 버리는 것을 의미합니다.

    다음으로, 방정식에는 255에서 ColorA를 빼는 등의 부분이 포함됩니다. 이는 간단한 색상 반전입니다. 흰색은 어둡게, 어두운 색은 흰색으로 바뀝니다. 값의 반전은 각 비트를 간단히 반전시키는 방식으로도 수행할 수 있습니다. 이를 통해 최종적으로 방정식을 다음과 같이 다시 작성할 수 있습니다.

    수식 2. FPGA 구현을 위한 최적화된 오버레이 블렌드


    이제 구현을 시작할 수 있습니다. 방정식의 나머지 연산은 VisualApplets 연산자로 제공됩니다. 다음 항목들이 필요합니다.

    • IF

    • 반전을 위한 NOT

    • 2^7로 나누기 위한 ShiftRight

    • 곱셈을 위한 HWMULT

      VisualApplets에는 HWMULT 외에도 MULT 연산자가 포함되어 있습니다. 두 연산 모두 동일한 역할을 하지만, HWMULT는 FPGA의 전용 승수를 사용하므로 리소스를 훨씬 적게 소모합니다.

    • 비트 심도 제한을 위해 CastBitWidth 연산자가 필요합니다. 이 연산자를 사용하면 MSB를 버려 9비트에서 8비트로 전환할 수 있습니다. 공식에서 알 수 있듯이 255보다 큰 값은 발생하지 않습니다.

  4. 시뮬레이션을 사용한 검증

    1. VisualApplets 시뮬레이션을 사용하여 오버레이 블렌드의 기능을 쉽게 검증할 수 있습니다. 두 개의 시뮬레이션 소스를 사용하여 두 카메라에 모두 이미지를 주입합니다. 원하는 링크에 시뮬레이션 프로브를 배치합니다. 시뮬레이션 결과에 두 이미지의 오버레이가 표시됩니다. 필요한 경우 계층 구조 상자에서 오버레이의 중간 결과도 확인할 수 있습니다.

    2. 시뮬레이션은 애플릿의 기능적 부분만 반영하고 타이밍은 반영하지 않으므로, 시뮬레이션만으로는 동기화를 검증할 수 없습니다. 하드웨어에서 검증해야 합니다.
  5. 트리거 추가

    앞서 언급했듯이, 버퍼 중 하나에서 오버플로가 발생하는 것을 방지하려면 두 카메라가 동일한 프레임 레이트로 실행되어야 합니다. 트리거 시스템을 사용하면 이 문제를 쉽게 해결할 수 있습니다.

Multiplex the Images of Two Cameras

VisualApplets에서는 이미지나 라인의 멀티플렉싱이 매우 쉽습니다. 두 카메라의 이미지를 멀티플렉싱하는 예시부터 시작하겠습니다. 즉, 동일한 DMA 채널을 사용하여 카메라 A와 카메라 B의 이미지를 번갈아가며 출력하려고 합니다.

  1. 기본 오퍼레이터

    두 개의 카메라 모듈, 두 개의 버퍼, 하나의 DMA를 사용하는 두 카메라용 표준 디자인이 필요합니다.

  2. 이미지 멀티플렉싱

    이미지를 멀티플렉싱하기 위해 InsertImage 연산자를 사용합니다. 이 연산자는 입력된 이미지들을 차례대로 전달합니다. 예를 들어 두 개의 입력을 사용하는 경우, 연산자는 입력 0, 1, 0, 1, 0, 1, ... 순서로 이미지를 전달합니다. 따라서 하나의 입력 처리가 완료되면 다음 입력이 사용됩니다. 결과적으로 두 입력의 프레임 수가 동일해야 합니다. 즉, 입력들의 프레임 레이트가 같아야 합니다.

    보시다시피 삽입 작업 전에 이미지 버퍼 모듈을 배치했습니다. 이는 InsertImage 연산자 자체에는 버퍼가 없기 때문입니다. 입력 0의 이미지가 전달되는 동안 입력 1은 차단되므로, 데이터 손실을 방지하기 위해 카메라 이미지를 버퍼링해야 합니다.

    각 입력(I0, I1, …)에 대해 연산자는 Ins0, Ins1, …이라는 두 번째 입력을 제공합니다. 이 입력은 이미지를 사용할지 버릴지를 제어하는 제어 입력입니다. 따라서 Ins 입력에 값 0이 있으면 해당 입력을 건너뛰고, 값 1이 제공되면 사용됩니다. 입력 그룹 I와 Ins는 동기화되어야 합니다. 즉, O형 연산자의 임의 네트워크를 통해 동일한 M형 연산자로부터 소스를 받아야 합니다. 자세한 내용은 'Operator Types'를 참조하세요. 두 입력이 동기화되므로 이미지 크기가 동일해야 합니다. InsertImage는 Ins 입력의 첫 번째 픽셀을 사용하여 이미지 사용 또는 폐기 여부를 결정합니다. 이전 스크린샷에서 볼 수 있듯이, 이미지 사용을 활성화하기 위해 CONST 연산자를 간단히 사용했습니다. CONST 연산자의 출력 링크 비트 심도를 1비트로 설정하고 "Value" 파라미터를 1로 설정하여 삽입을 활성화합니다.

    참고 사항: Ins 입력 중 하나의 값이 0인 경우에도 연산자는 해당 입력의 이미지를 계속 처리해야 합니다. 값이 0이라고 해서 이미지를 제공할 필요가 없다는 뜻은 아닙니다. 입력에 이미지가 제공되지 않으면 연산자는 이미지가 사용 가능해질 때까지 대기합니다.

    앞서 언급했듯이 한 번에 하나의 페이로드 입력만 열리고 나머지는 차단됩니다. 이미지는 서로 다른 버퍼 등에서 비동기적으로 소스를 가져와야 합니다. 다음 그림에서 작동하지 않는 두 가지 구성을 확인할 수 있습니다. 자체 차단으로 인해 애플릿에서 어떠한 결과도 얻을 수 없습니다. 이를 소위 "교착 상태(deadlock)" 조건이라고 합니다.

    InsertImage를 사용한 교착 상태 구성

    그림 209. InsertImage를 사용한 교착 상태 구성


    다른 입력이 활성화되어 있는 동안 중지된 입력 중 하나를 버퍼링할 수 있는지 항상 확인하십시오. 교착 상태 상황은 DRC나 시뮬레이션으로 감지할 수 없음을 유의하십시오. 교착 상태에 대한 자세한 내용은 'Timing Synchronization'에서 확인할 수 있습니다.

두 대의 카메라 스티칭

이전 섹션에서는 두 대의 카메라 이미지를 멀티플렉싱했습니다. Stitching도 거의 동일한 방식으로 수행됩니다. 대신 InsertLine 오퍼레이터를 사용하며, AppendLine 오퍼레이터를 사용하여 연속된 두 라인을 결합해야 합니다.

InsertLine은 먼저 두 입력의 라인을 멀티플렉싱하며, 그 후에 두 라인을 결합해야 합니다.

물론 앞선 두 예제와 동일한 이미지 소스를 사용하는 것도 가능합니다. 여기서 유의할 점은 삽입 작업 전에 충분한 버퍼가 확보되어야 한다는 것입니다. 이미지를 삽입하려면 전체 이미지를 버퍼링해야 합니다. 라인을 복제하는 경우, 한쪽 경로에서 동일한 라인이 처리되는 동안 단일 라인만 버퍼링하면 됩니다. 소수의 라인만 버퍼링하려면 ImageFifo 오퍼레이터를 사용할 수 있습니다. 이 오퍼레이터는 프레임 그래버 DRAM 메모리를 사용하지 않습니다. 대신 FPGA 내부의 BlockRAM 메모리를 사용합니다. 최대 한 줄을 저장하도록 FIFO를 구성합니다. 다음 예제에서는 이미지 라인을 복제했으며, 복제 과정에서 반전이 이루어집니다. 따라서 결과는 왼쪽에 원본 이미지, 오른쪽에 반전된(네거티브) 버전이 됩니다.

Line Duplication

그림 210. Line Duplication