표지된 초파리(Drosophila)를 위한 마커리스 다중 시점 모션 캡처
요약
DeepFly3D는 표지된 초파리(tethered Drosophila)의 2D 및 3D 자세 추정을 위한 PyTorch 기반 구현체입니다. 이 도구는 별도의 보정 패턴 없이 그림 구조를 활용하여 기하학적 제약 조건을 강제함으로써 높은 정확도를 제공합니다. 또한, GUI 환경을 통해 수동 오류 수정 기능도 지원합니다.
핵심 포인트
- 표지된 초파리 자세 추정을 위한 PyTorch 기반 솔루션입니다.
- 그림 구조(pictorial structures)를 이용해 기하학적 제약 조건을 강제합니다.
- 2D 자세 추정치를 3D로 변환하고 오류를 보정하는 기능을 제공합니다.
- eLife 저널에 발표된 연구 결과를 바탕으로 개발되었습니다.
표지된 초파리를 위한 마커리스 다중 시점 모션 캡처
<a href="https://github.com/psf/black"><img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg"></a>

DeepFly3D는 2D-3D 표지된 초파리(tethered Drosophila) 자세 추정의 PyTorch 및 PyQT5 구현체입니다. 이는 자세 추정을 위한 인터페이스를 제공하고, 자동으로 3D 자세로 변환되는 2D 자세 추정치를 추가적으로 보정할 수 있도록 하는 것을 목표로 합니다.
DeepFly3D는 별도의 보정 패턴을 요구하지 않으며, 그림 구조(pictorial structures)를 사용하여 기하학적 제약 조건(geometric constraints)을 강제함으로써 대부분의 오류를 수정합니다. 그리고 남아있는 오류는 자동으로 감지되어 GUI에서 수동으로 처리할 수 있습니다.
저희는 이전에 eLife 저널에 DeepFly3D 작업을 발표한 바 있습니다. 출판물은 여기에서 읽을 수 있습니다.
목차 (Table of Contents)
- 표지된 초파리를 위한 마커리스 다중 시점 모션 캡처
- 목차
- 설치 (Installing)
- 데이터 구조 (Data Structure)
- 기본 사용법 (Basic Usage)
- 고급 사용법 (Advanced Usage)
- Python 인터페이스 (Python Interface)
- 비디오 (Videos)
- 출력 (Output)
- GUI 실행하기 (Running GUI)
- 개발 (Development)
- 새 버전 출시하기 (Releasing a new version)
- 참고 문헌 (References)
- 버전 기록 (Version History)
⚠️ [IMG:N] 형식 토큰은 이미지 placeholder 입니다. 번역하지 말고 원래 위치에 그대로 유지하세요.
설치 (Installing)
pip을 이용한 설치 (Installing with pip)
새로운 anaconda 환경을 만들고, pip install nely-df3d 패키지를 설치하세요.
conda create -n df3d python=3.12
conda activate df3d
pip install nely-df3d
CUDA 드라이버 문제 (Odd CUDA Drivers)
CUDA 드라이버가 최신 버전이 아니거나, 또는 주류 pytorch에서 지원하지 않는 경우, nely-df3d를 pip으로 설치하기 전에 명시적으로 cudatoolkit을 설치해야 할 수 있습니다:
conda install pytorch torchvision torchaudio cudatoolkit="YOUR_CUDA_VERSION" -c pytorch
예를 들어, RTX 3080 Ti GPU의 경우 다음과 같이 해야 합니다:
conda create -n df3d python=3.12
conda activate df3d
conda install pytorch torchvision cudatoolkit=11 -c pytorch-nightly
...
소스 코드로부터 설치 (Installing from the source)
DeepFly3D는 설치를 위해 Python3, Anaconda 환경, 그리고 CUDA 드라이버가 필요합니다. 이 방법은 Ubuntu와 MacOS에서만 테스트되었습니다. 먼저 저장소를 클론하세요:
git clone https://github.com/NeLy-EPFL/DeepFly3D
cd DeepFly3D
그런 다음, 새로운 python 환경을 생성하는 다음 명령어로 conda 환경을 만드세요:
conda create -n df3d python=3.12
그 후, 환경을 활성화하세요.
conda activate df3d
이 과정을 완료하면 다음 명령어를 사용하여 df3d 패키지를 설치할 수 있습니다.
pip install -e .
이는 setup.py 함수를 사용하여 패키지를 생성합니다.
GPU와 호환되는 CUDA 드라이버도 반드시 설치해야 합니다. 그렇지 않으면 2D 예측을 수행하는 것이 불가능합니다. CUDA 드라이버 설치 방법은 여기에서 확인할 수 있습니다: https://developer.nvidia.com/cuda-downloads
개발용 소스 코드로부터 설치 (Installing from the source for development)
DeepFly3D를 실행하려면 nely-df2d와 nely-pyba라는 다른 두 개의 패키지도 필요합니다. 개발을 하고자 한다면, 세 가지 모두를 소스에서 설치하는 것이 가장 좋으며, 이렇게 하면 코드의 여러 부분에 쉽게 변경 사항을 적용할 수 있습니다. 다음 방법으로 할 수 있습니다.
데이터 구조 (Data Structure)
DeepFly3D를 사용하는 목적은 명령줄 인터페이스(CLI)를 통해서입니다.
df3d-cli는 폴더 내에 비디오 또는 이미지가 이 형식으로 존재한다고 가정합니다. 만약 경로 /your/image/path에 이미지나 비디오가 있다면, df3d-cli는 2D 포즈 추정(pose estimation), 보정(calibration) 및 삼각 측량(triangulation)을 실행하고 그 결과를 폴더 /your/image/path/df3d 아래에 2D 포즈, 3D 포즈, 그리고 보정 파라미터로 저장합니다.
이상적으로는 images/ 폴더 안에 이미지나 비디오가 있어야 하며, 이때 특정 명명 규칙을 따라야 합니다:
.
+-- images/
| +-- camera_0_img_0.jpg
...
또는
.
+-- images
| +-- camera_0.mp4
...
만약 mp4 파일인 경우, df3d는 ffmpeg를 사용하여 먼저 이들을 이미지로 확장합니다. 실제 예시는 다음 링크에서 확인해 주세요: https://github.com/NeLy-EPFL/DeepFly3D/tree/master/sample/test
기본 사용법 (Basic Usage)
기본 사용법은 다음과 같습니다.
df3d-cli /your/image/path
이 명령어는 카메라가 기본 순서대로 번호가 매겨져 있다고 가정합니다:
<p align="center"> <img src="https://raw.githubusercontent.com/NeLy-EPFL/DeepFly3D/HEAD/images/camera_order.png"> </p>이 경우, 카메라 0, 1, 2가 상단 행에 왼쪽부터 오른쪽으로 표시되고 카메라 4, 5, 6이 하단 행에 왼쪽부터 오른쪽으로 표시된다면 데이터는 다음과 같은 형태를 가집니다:

만약 대신 카메라 순서가 역순이라면 예를 들어:

그렇다면 순서는 6 5 4 3 2 1 0이므로, DeepFly3D가 제대로 작동하려면 df3d-cli /your/image/path --order 6 5 4 3 2 1 0을 실행해야 합니다.
고급 사용법 (Advanced Usage)
usage: df3d-cli [-h] [-v] [-vv] [-d] [--output-folder OUTPUT_FOLDER] [-r] [-f]
[-o] [-n NUM_IMAGES_MAX]
[--order [CAMERA_IDS [CAMERA_IDS ...]]] [--skip-pose-estimation]
...
따라서, df3d-cli에서 다음과 같이 고급 쿼리를 생성할 수 있습니다:
df3d-cli -f /path/to/text.txt \ # 텍스트 파일의 각 줄을 처리합니다
-r \ # 텍스트 줄 아래에 있는 이미지 폴더를 재귀적으로 검색합니다
--order 0 1 2 3 4 5 6 \ # 카메라 순서를 설정합니다
...
df3d-cli을 테스트하려면, 100개의 이미지 폴더에 대해 실행하고 비디오를 생성하며 디버깅을 위해 공격적으로 출력(print)해야 합니다:
df3d-cli /path/to/images/ -n 100 -vv
Python 인터페이스
선택적으로, df3d를 파이썬에서 직접 사용할 수도 있습니다.
from df3d.core import Core
from df3d import video
...
일반적으로 Core 모듈에서는 다음 함수들을 사용할 수 있습니다:
class Core:
def __init__(self, input_folder, num_images_max): # 9줄
def setup_cameras(self): # 38줄
...
비디오
df3d-cli에서 --video-2d 플래그를 사용하면 다음 비디오가 생성됩니다:

df3d-cli에서 --video-3d 플래그를 사용하면 다음 비디오가 생성됩니다:

--video-2d 또는 --video-3d로 비디오를 생성할 때, --output-fps 플래그를 사용하여 출력 비디오 프레임 속도를 제어할 수 있습니다. 지정하지 않으면, 출력 비디오 프레임 속도는 입력 비디오의 프레임 속도와 동일하게 설정됩니다.
출력
df3d-cli는 결과를 df3d_result.pk 파일에 저장합니다. 다음 코드를 사용하여 읽을 수 있습니다:
result_path = '../sample/test/df3d/df3d_result*.pkl'
d = pickle.load(open(glob.glob(pr_path)[0], 'rb'))
이것은 다음과 같은 키를 가진 딕셔너리를 읽습니다:
d.keys()
>>> dict_keys([0, 1, 2, 3, 4, 5, 6, 'points3d', 'points2d', 'points3d_wo_procrustes', 'camera_ordering', 'heatmap_confidence'])
Points2D
감지된 2D 키포인트는 d['points2d']에 저장되어 있으며, 이는 4차원 텐서입니다.
d['points2d'].shape
>>> (7, 15, 38, 2) # [CAMERAS, TIMES, JOINTS, 2D]
특정 시간의 특정 카메라에서 해당 2D 포인트를 읽으려면 다음을 사용할 수 있습니다:
row, column = d['points2d'][CAMERA, TIME, JOINT]
포인트는 (row, column) 형식입니다.
결과에서 어떤 키포인트가 동물에 있는 어떤 키포인트에 속하는지 시각화할 수도 있습니다:
import matplotlib.pyplot as plt
image_path = '../sample/test/camera_{cam_id}_img_{img_id}.jpg'
...
Points3D
주어진 2D 포인트와 보정(calibration) 매개변수를 사용하여 3D 포인트를 재계산할 수 있습니다:
from pyba.CameraNetwork import CameraNetwork
import pickle
import glob
...
카메라 0은 원점(origin)에 해당합니다. 카메라 중심(translation vector가 아님)이 0 포인트에 해당합니다.

카메라 순서 지정 (Camera Ordering)
CLI에서 --order 플래그를 사용하여 주어진 입력과 동일한 카메라 순서를 사용합니다.
d["camera_ordering"]
>>> array([0, 1, 2, 3, 4, 5, 6])
히트맵 신뢰도 (Heatmap Confidence)
예측된 각 관절에 대한 누적된 Hourglass 신뢰도 값입니다. 픽셀 $H$에 대한 정규화되지 않은 사후 분포(unnormalized posterior distribution) 히트맵이 주어지면, 최종 예측을 위해 $ ext{argmax}_{h, w} H$를 사용하고, 신뢰도 수준은 $H[h, w]$를 사용합니다.

보정 (Calibration)
df3d_result 파일에는 각 카메라에 대한 계산된 보정 매개변수도 포함되어 있습니다. 각 보정 섹션에는 다음이 포함됩니다:
- 회전 행렬 $R$ (rotation matrix R)
- 변환 벡터 $tvec$ (translation vector tvec)
- 내부 행렬 $intr$ (intrinsic matrix intr)
- 왜곡 매개변수 $distort$ (distortion parameters distort)
calib = {0: {'R': array([[ 0.90885957, 0.006461 , -0.41705219],
[ 0.01010426, 0.99924554, 0.03750006],
[ 0.41697983, -0.0382963 , 0.90810859]]),
...
좌표계는 OpenCV와 호환되며, 여기서 z축은 카메라에서 나가는 방향(axis going out of camera)에 해당합니다.
GUI 실행 (Running GUI)
GUI는 주로 'Correction' 모드에서 잘못된 2D 자세 추정 결과를 수정하는 데 사용됩니다. 변경 사항은 df3d 폴더 아래에 저장되며 최종 df3d_result 파일에 사용됩니다.
현재는 df3d를 CLI에서 동일 폴더에 실행한 후에만 GUI를 사용할 수 있습니다.
의존성(dependencies)을 설치한 후, 다음 명령줄 진입점(command line entry point)을 사용하여 GUI를 초기화할 수 있습니다:

df3d ./data/test/ 15
두 번째 인수는 이미지 폴더를 설정하며, 세 번째 인수는 이미지를 처리하고 싶은 하한선(upper bound)을 설정합니다. 이 경우 전체 이미지 중 일부만 처리할 수 있습니다.
이것은 GUI를 시작해야 합니다:

/FULL/PATH_FOLDER와 NUM_IMAGES는 선택적으로 제거할 수 있으며, 이 경우 폴더를 선택하는 팝업창(pop-up)이 나타납니다.
CLI에서 자세 추정(pose estimation)을 완료한 후, 포즈 모드(pose mode)를 열 수 있습니다:

개발 (Development)
DeepFly3D는 3개의 pip 패키지로 구성됩니다:
- DeepFly3D: https://pypi.org/project/df3d/
- PyBundleAdjustment: https://pypi.org/project/pyba/
- DeepFly2D: https://pypi.org/project/df2d/
DeepFly3D 패키지의 master 브랜치는 pip 패키지의 최신 버전과 함께 업데이트됩니다. 개발은 dev 브랜치에서 진행됩니다. master 브랜치에 변경 사항을 푸시하기 전에 모든 테스트 케이스가 통과하는지 확인하십시오. python -m unittest discover를 사용하여 테스트를 실행할 수 있습니다. 단위 테스트(Unittests)는 CLI를 통해 여러 시나리오가 실패 없이 처리될 수 있는지 확인합니다.
새 버전 릴리스 (Releasing a new version)
AI 자동 생성 콘텐츠
본 콘텐츠는 개발 자료 GitHub · 77c279a5의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기