跳转到主要内容

用于固定果蝇的GUI和3D姿态估计流程。

项目描述

DeepFly3D

Code style: black License: GPL v3 PyPI version

Alt text

DeepFly3D是PyTorch和PyQT5实现的2D-3D固定果蝇姿态估计。它旨在提供一个姿态估计的接口,并允许对自动转换为3D姿态的2D姿态估计进行进一步修正。

DeepFly3D不需要校准图案,它使用图样结构强制执行几何约束,这纠正了大多数错误,剩余的错误可以手动通过GUI处理。

目录

附加信息

安装

使用pip安装

创建一个新的Anaconda环境,并使用pip安装df3d包。

conda create -n df3d python=3.6
conda activate df3d
pip install df3d

旧CUDA驱动程序

仅在您的cuda驱动程序不是最新版本的情况下,在pip安装df3d之前,您可能还需要显式安装cudatoolkit

conda install pytorch torchvision torchaudio cudatoolkit="YOUR_CUDA_VERSION" -c pytorch

从源代码安装

DeepFly3D需要Python3、Anaconda环境和CUDA驱动程序进行安装。它仅在Ubuntu和MacOS上进行了测试。首先,克隆存储库

git clone https://github.com/NeLy-EPFL/DeepFly3D
cd DeepFly3D

然后,使用以下命令创建conda环境

conda create -n df3d python=3.6

这将创建一个新的python环境。然后,激活该环境。

conda activate df3d

完成此操作后,您可以使用以下命令安装df3d包

pip install -e .

它使用setup.py函数创建包。

确保您还安装了与您的GPU兼容的CUDA驱动程序,否则无法进行2D预测。您可以在以下位置检查如何安装CUDA驱动程序: https://developer.nvidia.com/cuda-downloads

数据结构

DeepFly3D的预期使用方式是通过命令行界面(CLI)。df3d-cli假定在文件夹中有此类格式的视频或图像。如果你的路径/your/image/path有图像或视频,df3d-cli将运行2D姿态估计、校准和三角测量,并将2D姿态、3D姿态和校准参数保存到/your/image/path/df3d文件夹下。

理想情况下,你将在images/文件夹下有图像或视频,并遵循特定的命名约定。

.
+-- images/
|   +-- camera_0_img_0.jpg
|   +-- camera_1_img_0.jpg
|   +-- camera_2_img_0.jpg
|   +-- camera_3_img_0.jpg
|   +-- camera_4_img_0.jpg
|   +-- camera_5_img_0.jpg
|   +-- camera_6_img_0.jpg
...

或者

.
+-- images
|   +-- camera_0.mp4
|   +-- camera_1.mp4
|   +-- camera_2.mp4
|   +-- camera_3.mp4
|   +-- camera_4.mp4
|   +-- camera_5.mp4
|   +-- camera_6.mp4

对于mp4文件,df3d将首先使用ffmpeg将其扩展为图像。请查看示例数据以获取真实示例:[链接](https://github.com/NeLy-EPFL/DeepFly3D/tree/master/sample/test)

基本用法

基本用法如下。

df3d-cli /your/image/path \
         --order 0 1 2 3 4 5 6 

相机顺序表示相机选择。默认相机顺序(0 1 2 3 4 5 6)表示此顺序。如果你有其他顺序,则需要说明顺序。

最初。

然后,如果你有以下顺序,你的顺序应该是6 5 4 3 2 1 0。 ![图片](https://pypi-camo.freetls.fastly.net/...)

例如,如果你的数据看起来像这样,那么你的顺序应该是6 5 4 3 2 1 0。 ![图片](https://pypi-camo.freetls.fastly.net/...)

高级用法

usage: df3d-cli [-h] [-v] [-vv] [-d] [--output-folder OUTPUT_FOLDER] [-r] [-f]
                [-o] [-n NUM_IMAGES_MAX]
                [-order [CAMERA_IDS [CAMERA_IDS ...]]] [--video-2d]
                [--video-3d] [--skip-pose-estimation]
                INPUT

DeepFly3D pose estimation

positional arguments:
  INPUT                 Without additional arguments, a folder containing
                        unlabeled images.

optional arguments:
  -h, --help            show this help message and exit
  -v, --verbose         Enable info output (such as progress bars)
  -vv, --verbose2       Enable debug output
  -d, --debug           Displays the argument list for debugging purposes
  --output-folder OUTPUT_FOLDER
                        The name of subfolder where to write results
  -r, --recursive       INPUT is a folder. Successively use its subfolders
                        named 'images/'
  -f, --from-file       INPUT is a text-file, where each line names a folder.
                        Successively use the listed folders.
  -o, --overwrite       Rerun pose estimation and overwrite existing pose
                        results
  -n NUM_IMAGES_MAX, --num-images-max NUM_IMAGES_MAX
                        Maximal number of images to process.
  -order [CAMERA_IDS [CAMERA_IDS ...]], --camera-ids [CAMERA_IDS [CAMERA_IDS ...]]
                        Ordering of the cameras provided as an ordered list of
                        ids. Example: 0 1 4 3 2 5 6.
  --video-2d            Generate pose2d videos
  --video-3d            Generate pose3d videos
  --skip-pose-estimation
                        Skip 2D and 3D pose estimation

因此,你可以在df3d-cli中创建高级查询,例如

df3d-cli -f /path/to/text.txt    \  # process each line from the text file 
         -r                      \  # recursively search for images folder under each line of the text line
         --order 0 1 2 3 4 5 6   \  # set the camera order
         -n 100                  \  # process only the first 100 images 
         --output-folder results \  # write results under  /your/image/path/results instead of  /your/image/path/df3d
         --vv                    \  # will print agressivelly, for debugging purposes
         --skip-pose-estimation  \  # will not run 2d pose estimation, instead will do calibration, triangulation and will save results
         --video-2d              \  # will make 2d video for each folder 
         --video-3d              \  # will make 3d video for each folder

要测试df3d-cli,你可以在只有100个图像的文件夹上运行它,制作视频,并积极打印以进行调试

df3d-cli /path/to/images/ -n 100 -vv -order 0 1 2 3 4 5 6

Python接口

可选地,你还可以直接在Python中使用df3d。

from df3d.core import Core
from df3d import video

core = Core(input_folder='../sample/test/', num_images_max=100, output_subfolder='df3d_py', camera_ordering=[0,1,2,3,4,5,6])
core.pose2d_estimation()
core.calibrate_calc(min_img_id=0, max_img_id=100)

# save df3d_resultt  file under '../sample/test/df3d_py' 
core.save()

# make videos
video.make_pose2d_video(
    core.plot_2d, core.num_images, core.input_folder, core.output_folder
)
video.make_pose3d_video(
    core.get_points3d(),
    core.plot_2d,
    core.num_images,
    core.input_folder,
    core.output_folder,
)

通常,以下功能可用于核心模块

class Core:
    def __init__(self, input_folder, num_images_max):  # 9 lines
	def setup_cameras(self):  # 38 lines
    
    # attribute access
    @property def input_folder(self):  # 2 lines
    @property def output_folder(self):  # 2 lines
    @property def image_shape(self):  # 2 lines
    @property def number_of_joints(self):  # 3 lines
    def has_pose(self):  # 1 lines
    def has_heatmap(self):  # 1 lines
    def has_calibration(self):  # 4 lines
    
    # interactions with pose-estimation
    def update_camera_ordering(self, cidread2cid):  # 12 lines
    def pose2d_estimation(self):  # 14 lines
    def next_error(self, img_id):  # 1 lines
    def prev_error(self, img_id):  # 1 lines
    def calibrate_calc(self, min_img_id, max_img_id):  # 35 lines
    def nearest_joint(self, cam_id, img_id, x, y):  # 10 lines
    def move_joint(self, cam_id, img_id, joint_id, x, y):  # 10 lines

    def save_calibration(self):  # 3 lines
    def save_pose(self):  # 63 lines
    def save_corrections(self):  # 1 line
    
    # visualizations
    def plot_2d(self, cam_id, img_id, with_corrections=False, joints=[]):  # 33 lines
    def plot_heatmap(self, cam_id, img_id, joints=[]):  # 5 lines
    def get_image(self, cam_id, img_id):  # 4 lines
    
    # private helper methods
    def next_error_in_range(self, range_of_ids):  # 6 lines
    def get_joint_reprojection_error(self, img_id, joint_id, camNet):  # 11 lines
    def joint_has_error(self, img_id, joint_id):  # 4 lines
    def solve_bp_for_camnet(self, img_id, camNet):  # 29 lines

视频

使用df3d-cli的--video-2d标志将创建以下视频:![图片](https://pypi-camo.freetls.fastly.net/...)

使用df3d-cli的--video-3d标志将创建以下视频:![图片](https://pypi-camo.freetls.fastly.net/...)

输出

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

你也可以可视化结果中的哪些关键点属于动物上的哪些关键点

import matplotlib.pyplot as plt

image_path = '../sample/test/camera_{cam_id}_img_{img_id}.jpg'
pr_path = '../sample/test/df3d/df3d_result*.pkl'

plt.imshow(plt.imread(image_path.format(cam_id=0,img_id=0)))
plt.axis('off')
for i in range(19):
    x, y = d['points2d'][0, 0][i, 1] * 960, d['points2d'][0, 0][i, 0] * 480
    plt.scatter(x, y, c='blue', s=5)
    plt.text(x, y, f'{i}', c='red')

相机排序

与CLI中使用的--order标志给出的输入相同的相机顺序。

d["camera_ordering"]
>>> array([0, 1, 2, 3, 4, 5, 6])

热图置信度

对于预测的每个关节,Stacked Hourglass置信值。给定一个未归一化的后验分布热图H在像素上,我们取argmax_{h, w} H作为最终预测和H[h, w]作为置信度级别。

校准

df3d_result文件还包括每个相机的计算校准参数。每个校准部分包括

  1. 旋转矩阵R
  2. 平移向量tvec,
  3. 内在矩阵intr,
  4. 畸变参数distort。
calib = {0: {'R': array([[ 0.90885957,  0.006461  , -0.41705219],
         [ 0.01010426,  0.99924554,  0.03750006],
         [ 0.41697983, -0.0382963 ,  0.90810859]]),
  'tvec': array([1.65191596e+00, 2.22582670e-02, 1.18353733e+02]),
  'intr': array([[1.60410e+04, 0.00000e+00, 2.40000e+02],
         [0.00000e+00, 1.59717e+04, 4.80000e+02],
         [0.00000e+00, 0.00000e+00, 1.00000e+00]]),
  'distort': array([0., 0., 0., 0., 0.])},
 1: {'R': array([[ 0.59137248,  0.02689833, -0.80594979],
         [-0.00894927,  0.9996009 ,  0.02679478],
         [ 0.80634887, -0.00863303,  0.59137718]]),
  'tvec': array([ 1.02706542e+00, -9.25820468e-02,  1.18251732e+02]),
  'intr': array([[1.60410e+04, 0.00000e+00, 2.40000e+02],
         [0.00000e+00, 1.59717e+04, 4.80000e+02],
         [0.00000e+00, 0.00000e+00, 1.00000e+00]]),
  'distort': array([0., 0., 0., 0., 0.])},
}

运行GUI

GUI主要用于在“校正”模式下纠正错误的2D姿态估计结果。你的更改将保存到df3d文件夹中,并将用于最终的df3d_result文件。

目前,你只能在同一文件夹上通过CLI运行df3d后使用GUI。

安装依赖项后,我们可以使用命令行入口点初始化GUI

Alt text

df3d ./data/test/ 15

第二个参数设置图像文件夹,第三个参数设置图像的上限,以防你只想处理图像的子集。

这将启动GUI

Alt text

你可以选择性地删除/FULL/PATH_FOLDERNUM_IMAGES,在这种情况下,将弹出窗口以选择文件夹。

在CLI中完成姿态估计后,你可以打开姿态模式

Alt text

开发

DeepFly3D由3个pip包组成

  • DeepFly3D: [链接](https://pypi.ac.cn/project/df3d/0.56/)
  • PyBundleAdjustment: [链接](https://pypi.ac.cn/project/pyba/)
  • Drosophila2D Pose: [链接](https://pypi.ac.cn/project/df2d/)

DeepFly3D软件包的主分支与pip包的最新版本保持同步。开发工作在dev分支上进行。在将更改推送到主分支之前,请确保所有测试用例都通过。您可以使用python test.py运行测试。单元测试确保可以通过cli处理多个场景而不会失败。

参考文献

@inproceedings{Gunel19DeepFly3D,
  author    = {Semih G{\"u}nel and
               Helge Rhodin and
               Daniel Morales and
               João Compagnolo and
               Pavan Ramdya and
               Pascal Fua},
  title     = {DeepFly3D, a deep learning-based approach for 3D limb and appendage tracking in tethered, adult Drosophila},
  bookTitle = {eLife},
  doi       = {10.7554/eLife.48571},
  year      = {2019}
}

版本历史

0.5版本中的更改

  • 主要内部重写。

0.4版本中的更改

  • 使用CLI,可以使用--output-folder标志更改输出文件夹。
  • CLI和GUI现在使用相同的姿态估计代码,因此更改将自动传播到两者。
  • GUI布局进行了一些小的调整,功能保持不变。

0.3版本中的更改

  • 结果保存到df3d文件夹而不是图像文件夹。
  • 启动时间大大加快。
  • 使用正则表达式自动对相机进行排序。
  • CLI改进。现在它包括3D姿态。

0.2版本中的更改

  • 将名称从deepfly3d更改为df3d。
  • 添加了df3d-cli的CLI界面。
  • 删除了numpy和scipy的特定依赖。
  • 删除了L/R按钮,因此您可以一次性查看所有数据。
  • 删除了前置摄像头。
  • 启动时间更快,花费在搜索图像文件夹上的时间更少。
  • 为绘图添加了更好的笔记本。
  • 添加了普鲁斯特支持。现在所有输出都注册到模板骨骼。
  • 在CameraNetwork中修复了错误。现在可以使用任意相机序列进行校准。

项目详情


下载文件

下载适用于您平台的应用程序。如果您不确定选择哪个,请了解更多关于安装包的信息。

源分布

df3d-0.57.tar.gz (51.6 kB 查看哈希)

上传时间:

构建分布

df3d-0.57-py3-none-any.whl (54.6 kB 查看哈希)

上传时间: Python 3

支持者: