ImageFrames 및 GpuBuffers를 변환하는 방법
계산기 ImageFrameToGpuBufferCalculator
와 GpuBufferToImageFrameCalculator
는 ImageFrame
및 GpuBuffer
유형의 패킷 간에 변환합니다. ImageFrame
는 CPU 메모리에 있는 여러 비트맵 이미지 형식의 이미지 데이터를 나타냅니다. GpuBuffer
는 GPU 메모리의 이미지 데이터를 나타냅니다. 자세한 내용은 프레임워크 개념 섹션 GpuBuffer to ImageFrame Converters를 참고하세요. 다음에서 예를 확인할 수 있습니다.
인식 결과를 시각화하는 방법
AnnotationOverlayCalculator
를 사용하면 경계 상자, 화살표, 타원 같은 인식 결과를 인식된 객체에 맞게 정렬된 동영상 프레임에 겹칠 수 있습니다. 워크스테이션에서 실행할 때는 진단 창에, 기기에서 실행할 때는 텍스처 프레임에 결과를 표시할 수 있습니다. AnnotationOverlayCalculator
사용 예는 다음에서 확인할 수 있습니다.
계산기를 동시에 실행하는 방법
계산기 그래프 내에서 MediaPipe는 일상적으로 별도의 계산기 노드를 병렬로 실행합니다. MediaPipe는 스레드 풀을 유지하며 스레드를 사용할 수 있고 스레드의 모든 입력이 준비되는 즉시 각 계산기를 실행합니다. 각 계산기 인스턴스는 한 번에 하나의 입력 세트에 대해서만 실행되므로 대부분의 계산기는 스레드와 호환되어야 하며 스레드로부터 안전하지 않아야 합니다.
하나의 계산기에서 여러 입력을 병렬로 처리할 수 있도록 하려면 다음 두 가지 방법을 사용할 수 있습니다.
- 여러 계산기 노드를 정의하고 입력 패킷을 모든 노드에 전달합니다.
- 계산기를 스레드로부터 안전하게 설정하고
max_in_flight
설정을 구성합니다.
첫 번째 접근 방식은 RoundRobinDemuxCalculator
와 같은 다른 계산기에 패킷을 배포하도록 설계된 계산기를 사용하여 따를 수 있습니다. 단일 RoundRobinDemuxCalculator
는 동일하게 구성된 여러 ScaleImageCalculator
노드에 연속적인 패킷을 배포할 수 있습니다.
두 번째 방법을 사용하면 동일한 계산기 노드에서 CalculatorBase::Process
메서드를 최대 max_in_flight
회 호출할 수 있습니다. CalculatorBase::Process
의 출력 패킷은 다운스트림 계산기로 전달되기 전에 자동으로 타임스탬프에 따라 정렬됩니다.
어느 방법을 사용하든 병렬로 실행되는 계산기는 일반적인 순차 계산기와 동일한 방식으로 내부 상태를 유지할 수 없다는 점에 유의해야 합니다.
ImmediateInputStreamHandler 사용 시 출력 타임스탬프
ImmediateInputStreamHandler
는 각 패킷이 입력 스트림에 도착하는 즉시 전달합니다. 따라서 다른 입력 스트림에서 타임스탬프가 더 낮은 패킷을 전송하기 전에 한 입력 스트림에서 타임스탬프가 더 높은 패킷을 전달할 수 있습니다. 이러한 입력 타임스탬프가 한 출력 스트림으로 전송된 패킷에 모두 사용되면 해당 출력 스트림에서는 타임스탬프가 단조 증가하지 않는다고 불만을 표시합니다. 이 문제를 해결하기 위해 계산기는 타임스탬프에 대한 처리가 완료된 후에만 패킷을 출력하도록 주의를 기울여야 합니다.
이는 해당 타임스탬프의 모든 입력 스트림에서 입력 패킷이 수신될 때까지 기다리거나 이미 처리된 타임스탬프로 도착한 패킷을 무시하여 수행할 수 있습니다.
런타임 시 설정을 변경하는 방법
애플리케이션이 실행되는 동안 계산기 그래프의 설정을 변경하는 방법에는 두 가지가 있습니다.
- 수정된
CalculatorGraphConfig
을 사용하여 계산기 그래프를 다시 시작합니다. - 그래프 입력 스트림의 패킷을 통해 새로운 계산기 옵션을 전송합니다.
첫 번째 접근 방식은 '하위 그래프'와 같은 CalculatorGraphConfig
처리 도구를 활용하는 이점이 있습니다. 두 번째 접근 방식은 설정이 변경되는 동안 활성 계산기와 패킷이 이동되도록 하는 이점이 있습니다. Mediapipe 기여자는 현재 이 두 가지 이점을 모두 달성하기 위한 대체 접근 방식을 연구하고 있습니다.
실시간 입력 스트림을 처리하는 방법
mediapipe 프레임워크는 온라인 또는 오프라인에서 데이터 스트림을 처리하는 데 사용할 수 있습니다. 오프라인 처리의 경우, 계산기가 패킷을 처리할 준비가 되는 즉시 패킷이 그래프로 푸시됩니다. 온라인 처리의 경우 각 프레임에 대한 하나의 패킷이 해당 프레임이 기록될 때 그래프로 푸시됩니다.
MediaPipe 프레임워크는 연속적인 패킷에 단조 증가하는 타임스탬프만 할당하면 됩니다. 규칙에 따라 실시간 계산기와 그래프는 기록 시간 또는 프레젠테이션 시간을 각 패킷의 타임스탬프로 사용하며 각 타임스탬프는 Jan/1/1970:00:00:00
이후의 마이크로초를 나타냅니다. 이를 통해 다양한 소스의 패킷을 전역적으로 일관된 순서로 처리할 수 있습니다.
일반적으로 오프라인 처리의 경우 모든 입력 패킷이 처리되고 필요한 만큼 처리가 지속됩니다. 온라인 처리의 경우 입력 데이터 프레임의 도착 속도를 따라잡기 위해 입력 패킷을 삭제해야 하는 경우가 많습니다.
입력이 너무 자주 도착하는 경우 패킷 삭제에 권장되는 방법은 FlowLimiterCalculator
및 PacketClonerCalculator
와 같이 이 용도로 설계된 MediaPipe 계산기를 사용하는 것입니다.
온라인 처리의 경우 처리를 진행할 수 있는 시점을 즉시 결정해야 합니다. MediaPipe는 계산기 간에 타임스탬프 경계를 전파하여 이를 지원합니다. 타임스탬프 경계는 입력 패킷이 포함되지 않은 타임스탬프 간격을 나타내며 계산기가 이러한 타임스탬프에 대한 처리를 즉시 시작할 수 있게 해줍니다. 실시간 처리용으로 설계된 계산기는 최대한 빨리 처리를 시작하기 위해 타임스탬프 경계를 신중하게 계산해야 합니다. 예를 들어 MakePairCalculator
는 SetOffset
API를 사용하여 타임스탬프 경계를 입력 스트림에서 출력 스트림으로 전파합니다.
MS Windows에서 MediaPipe를 실행할 수 있나요?
현재 MediaPipe 이동성은 Debian Linux, Ubuntu Linux, MacOS, Android, iOS를 지원합니다. MediaPipe 프레임워크의 핵심은 C++11 표준을 준수하는 C++ 라이브러리이므로 추가 플랫폼에 비교적 쉽게 포팅할 수 있습니다.