├── .gitignore ├── CMakeLists.txt ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── DensePoseData ├── demo_data │ ├── demo_dp_single_ann.pkl │ ├── demo_im.jpg │ ├── synth_UV_example.png │ ├── texture_atlas_200.png │ └── texture_from_SURREAL.png ├── get_DensePose_COCO.sh ├── get_densepose_uv.sh ├── get_eval_data.sh └── infer_out │ ├── demo_im.jpg.pdf │ ├── demo_im_INDS.png │ └── demo_im_IUV.png ├── GETTING_STARTED.md ├── INSTALL.md ├── LICENSE ├── MODEL_ZOO.md ├── Makefile ├── NOTICE ├── PoseTrack ├── DensePose-PoseTrack-Visualize.ipynb ├── README.md ├── configs │ └── DensePose_ResNet50_FPN_s1x-e2e.yaml └── get_DensePose_PoseTrack.sh ├── README.md ├── challenge ├── 2018_COCO_DensePose │ ├── data_format.md │ ├── evaluation.md │ ├── example_results.json │ ├── readme.md │ ├── results_format.md │ └── upload.md ├── 2018_PoseTrack_DensePose │ ├── data_format.md │ ├── evaluation.md │ ├── readme.md │ ├── results_format.md │ └── upload.md ├── 2019_COCO_DensePose │ ├── data_format.md │ ├── densepose_cocoeval.py │ ├── evaluation.md │ ├── readme.md │ ├── results_format.md │ └── upload.md └── encode_results_for_competition.py ├── cmake ├── Summary.cmake └── legacy │ ├── Cuda.cmake │ ├── Dependencies.cmake │ ├── Modules │ └── FindCuDNN.cmake │ ├── Summary.cmake │ ├── Utils.cmake │ └── legacymake.cmake ├── configs ├── DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml ├── DensePose_ResNet101_FPN.yaml ├── DensePose_ResNet101_FPN_32x8d_s1x-e2e.yaml ├── DensePose_ResNet101_FPN_32x8d_s1x.yaml ├── DensePose_ResNet101_FPN_s1x-e2e.yaml ├── DensePose_ResNet101_FPN_s1x.yaml ├── DensePose_ResNet50_FPN.yaml ├── DensePose_ResNet50_FPN_s1x-e2e.yaml ├── DensePose_ResNet50_FPN_s1x.yaml ├── DensePose_ResNet50_FPN_single_GPU.yaml ├── rpn_densepose_only_R-50-FPN_1x.yaml └── rpn_densepose_only_X-101-32x8d-FPN_1x.yaml ├── detectron ├── __init__.py ├── core │ ├── __init__.py │ ├── config.py │ ├── rpn_generator.py │ ├── test.py │ ├── test_engine.py │ └── test_retinanet.py ├── datasets │ ├── VOCdevkit-matlab-wrapper │ │ ├── get_voc_opts.m │ │ ├── voc_eval.m │ │ └── xVOCap.m │ ├── __init__.py │ ├── cityscapes_json_dataset_evaluator.py │ ├── coco_to_cityscapes_id.py │ ├── data │ │ └── README.md │ ├── dataset_catalog.py │ ├── densepose_cocoeval.py │ ├── dummy_datasets.py │ ├── json_dataset.py │ ├── json_dataset_evaluator.py │ ├── roidb.py │ ├── task_evaluation.py │ ├── voc_dataset_evaluator.py │ └── voc_eval.py ├── modeling │ ├── FPN.py │ ├── ResNet.py │ ├── VGG16.py │ ├── VGG_CNN_M_1024.py │ ├── __init__.py │ ├── body_uv_rcnn_heads.py │ ├── detector.py │ ├── fast_rcnn_heads.py │ ├── generate_anchors.py │ ├── keypoint_rcnn_heads.py │ ├── mask_rcnn_heads.py │ ├── model_builder.py │ ├── name_compat.py │ ├── optimizer.py │ ├── retinanet_heads.py │ ├── rfcn_heads.py │ └── rpn_heads.py ├── ops │ ├── __init__.py │ ├── collect_and_distribute_fpn_rpn_proposals.py │ ├── generate_proposal_labels.py │ ├── generate_proposals.py │ ├── pool_points_interp.cc │ ├── pool_points_interp.cu │ ├── pool_points_interp.h │ ├── zero_even_op.cc │ ├── zero_even_op.cu │ └── zero_even_op.h ├── roi_data │ ├── __init__.py │ ├── body_uv_rcnn.py │ ├── data_utils.py │ ├── fast_rcnn.py │ ├── keypoint_rcnn.py │ ├── loader.py │ ├── mask_rcnn.py │ ├── minibatch.py │ ├── retinanet.py │ └── rpn.py ├── tests │ ├── data_loader_benchmark.py │ ├── test_batch_permutation_op.py │ ├── test_bbox_transform.py │ ├── test_cfg.py │ ├── test_loader.py │ ├── test_restore_checkpoint.py │ ├── test_smooth_l1_loss_op.py │ ├── test_spatial_narrow_as_op.py │ └── test_zero_even_op.py └── utils │ ├── __init__.py │ ├── blob.py │ ├── boxes.py │ ├── c2.py │ ├── collections.py │ ├── colormap.py │ ├── coordinator.py │ ├── cython_bbox.pyx │ ├── cython_nms.pyx │ ├── densepose_methods.py │ ├── env.py │ ├── image.py │ ├── io.py │ ├── keypoints.py │ ├── logging.py │ ├── lr_policy.py │ ├── model_convert_utils.py │ ├── net.py │ ├── segms.py │ ├── subprocess.py │ ├── timer.py │ ├── train.py │ ├── training_stats.py │ └── vis.py ├── docker └── Dockerfile ├── notebooks ├── .ipynb_checkpoints │ ├── DensePose-COCO-Visualize-checkpoint.ipynb │ ├── DensePose-COCO-on-SMPL-checkpoint.ipynb │ └── DensePose-RCNN-Texture-Transfer-checkpoint.ipynb ├── DensePose-COCO-Visualize.ipynb ├── DensePose-COCO-on-SMPL.ipynb ├── DensePose-RCNN-Texture-Transfer.ipynb └── DensePose-RCNN-Visualize-Results.ipynb ├── requirements.txt ├── setup.py └── tools ├── infer.py ├── infer_simple.py ├── test_net.py ├── train_net.py └── visualize_results.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # Shared objects 7 | *.so 8 | 9 | # Distribution / packaging 10 | build/ 11 | *.egg-info/ 12 | *.egg 13 | 14 | # Temporary files 15 | *.swn 16 | *.swo 17 | *.swp 18 | 19 | *.mat 20 | *.pkl 21 | !DensePoseData/demo_data/demo_dp_single_ann.pkl 22 | *.tar.gz 23 | *.json 24 | !challenge/2018_COCO_DensePose/example_results.json 25 | 26 | *.DS_Store 27 | # Dataset symlinks 28 | detectron/datasets/data/* 29 | !detectron/datasets/data/README.md 30 | 31 | # Generated C files 32 | detectron/utils/cython_*.c 33 | 34 | notebooks_old/* 35 | configs_old/* 36 | 37 | 38 | .nfs* 39 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8.12 FATAL_ERROR) 2 | 3 | # Find the Caffe2 package. 4 | # Caffe2 exports the required targets, so find_package should work for 5 | # the standard Caffe2 installation. If you encounter problems with finding 6 | # the Caffe2 package, make sure you have run `make install` when installing 7 | # Caffe2 (`make install` populates your share/cmake/Caffe2). 8 | find_package(Caffe2 REQUIRED) 9 | 10 | if (${CAFFE2_VERSION} VERSION_LESS 0.8.2) 11 | # Pre-0.8.2 caffe2 does not have proper interface libraries set up, so we 12 | # will rely on the old path. 13 | message(WARNING 14 | "You are using an older version of Caffe2 (version " ${CAFFE2_VERSION} 15 | "). Please consider moving to a newer version.") 16 | include(cmake/legacy/legacymake.cmake) 17 | return() 18 | endif() 19 | 20 | # Add compiler flags. 21 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 22 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -fPIC -Wno-narrowing") 23 | 24 | # Print configuration summary. 25 | include(cmake/Summary.cmake) 26 | detectron_print_config_summary() 27 | 28 | # Collect custom ops sources. 29 | file(GLOB CUSTOM_OPS_CPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cc) 30 | file(GLOB CUSTOM_OPS_GPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cu) 31 | 32 | # Install custom CPU ops lib. 33 | add_library( 34 | caffe2_detectron_custom_ops SHARED 35 | ${CUSTOM_OPS_CPU_SRCS}) 36 | 37 | target_link_libraries(caffe2_detectron_custom_ops caffe2_library) 38 | install(TARGETS caffe2_detectron_custom_ops DESTINATION lib) 39 | 40 | # Install custom GPU ops lib, if gpu is present. 41 | if (CAFFE2_USE_CUDA OR CAFFE2_FOUND_CUDA) 42 | # Additional -I prefix is required for CMake versions before commit (< 3.7): 43 | # https://github.com/Kitware/CMake/commit/7ded655f7ba82ea72a82d0555449f2df5ef38594 44 | list(APPEND CUDA_INCLUDE_DIRS -I${CAFFE2_INCLUDE_DIRS}) 45 | CUDA_ADD_LIBRARY( 46 | caffe2_detectron_custom_ops_gpu SHARED 47 | ${CUSTOM_OPS_CPU_SRCS} 48 | ${CUSTOM_OPS_GPU_SRCS}) 49 | 50 | target_link_libraries(caffe2_detectron_custom_ops_gpu caffe2_gpu_library) 51 | install(TARGETS caffe2_detectron_custom_ops_gpu DESTINATION lib) 52 | endif() 53 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | Facebook has adopted a Code of Conduct that we expect project participants to adhere to. 4 | Please read the [full text](https://code.facebook.com/pages/876921332402685/open-source-code-of-conduct) 5 | so that you can understand what actions will and will not be tolerated. 6 | 7 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to DensePose 2 | We want to make contributing to this project as easy and transparent as 3 | possible. 4 | 5 | ## Our Development Process 6 | Minor changes and improvements will be released on an ongoing basis. 7 | 8 | ## Pull Requests 9 | We actively welcome your pull requests. 10 | 11 | 1. Fork the repo and create your branch from `master`. 12 | 2. If you've added code that should be tested, add tests. 13 | 3. If you've changed APIs, update the documentation. 14 | 4. Ensure the test suite passes. 15 | 5. Make sure your code lints. 16 | 6. If you haven't already, complete the Contributor License Agreement ("CLA"). 17 | 18 | ## Contributor License Agreement ("CLA") 19 | In order to accept your pull request, we need you to submit a CLA. You only need 20 | to do this once to work on any of Facebook's open source projects. 21 | 22 | Complete your CLA here: 23 | 24 | ## Issues 25 | We use GitHub issues to track public bugs. Please ensure your description is 26 | clear and has sufficient instructions to be able to reproduce the issue. 27 | 28 | ## Coding Style 29 | * 4 spaces for indentation rather than tabs 30 | * 80 character line length 31 | * PEP8 formatting 32 | 33 | ## License 34 | By contributing to DensePose, you agree that your contributions will be licensed 35 | under the LICENSE file in the root directory of this source tree. 36 | 37 | -------------------------------------------------------------------------------- /DensePoseData/demo_data/demo_im.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/demo_data/demo_im.jpg -------------------------------------------------------------------------------- /DensePoseData/demo_data/synth_UV_example.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/demo_data/synth_UV_example.png -------------------------------------------------------------------------------- /DensePoseData/demo_data/texture_atlas_200.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/demo_data/texture_atlas_200.png -------------------------------------------------------------------------------- /DensePoseData/demo_data/texture_from_SURREAL.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/demo_data/texture_from_SURREAL.png -------------------------------------------------------------------------------- /DensePoseData/get_DensePose_COCO.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir DensePose_COCO 3 | cd DensePose_COCO 4 | wget https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_train.json 5 | wget https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_valminusminival.json 6 | wget https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_minival.json 7 | wget https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_test.json 8 | -------------------------------------------------------------------------------- /DensePoseData/get_densepose_uv.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir UV_data 3 | cd UV_data 4 | wget https://dl.fbaipublicfiles.com/densepose/densepose_uv_data.tar.gz 5 | tar xvf densepose_uv_data.tar.gz 6 | rm densepose_uv_data.tar.gz 7 | -------------------------------------------------------------------------------- /DensePoseData/get_eval_data.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir eval_data 3 | cd eval_data 4 | wget https://dl.fbaipublicfiles.com/densepose/densepose_eval_data.tar.gz 5 | tar xvf densepose_eval_data.tar.gz 6 | rm densepose_eval_data.tar.gz 7 | -------------------------------------------------------------------------------- /DensePoseData/infer_out/demo_im.jpg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/infer_out/demo_im.jpg.pdf -------------------------------------------------------------------------------- /DensePoseData/infer_out/demo_im_INDS.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/infer_out/demo_im_INDS.png -------------------------------------------------------------------------------- /DensePoseData/infer_out/demo_im_IUV.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/DensePoseData/infer_out/demo_im_IUV.png -------------------------------------------------------------------------------- /GETTING_STARTED.md: -------------------------------------------------------------------------------- 1 | # Using Detectron 2 | 3 | This document provides brief tutorials covering DensePose for inference and training on the DensePose-COCO dataset. 4 | This document is a modified version of the [`detectron/GETTING_STARTED.md`](https://github.com/facebookresearch/Detectron/blob/master/GETTING_STARTED.md). 5 | 6 | - For general information about DensePose, please see [`README.md`](README.md). 7 | - For installation instructions, please see [`INSTALL.md`](INSTALL.md). 8 | 9 | ## Inference with Pretrained Models 10 | 11 | #### 1. Directory of Image Files 12 | To run inference on a an image (or a directory of image files), you can use the `infer_simple.py` tool. In this example, we're using an end-to-end trained DensePose-RCNN model with a ResNet-101-FPN backbone from the model zoo: 13 | ``` 14 | python2 tools/infer_simple.py \ 15 | --cfg configs/DensePose_ResNet101_FPN_s1x-e2e.yaml \ 16 | --output-dir DensePoseData/infer_out/ \ 17 | --image-ext jpg \ 18 | --wts https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl \ 19 | DensePoseData/demo_data/demo_im.jpg 20 | ``` 21 | 22 | DensePose should automatically download the model from the URL specified by the `--wts` argument. This tool will output visualizations of the detections in PDF format in the directory specified by `--output-dir`. Also, it will output two images `*_IUV.png` and `*_INDS.png` which consists of I,U, V channels and segmented instance indices respectively. Please see [`notebooks/DensePose-RCNN-Visualize-Results.ipynb`](notebooks/DensePose-RCNN-Visualize-Results.ipynb) for the visualizations of these outputs. 23 | 24 | 25 | ## Testing with Pretrained Models 26 | 27 | Make sure that you have downloaded the DensePose evaluation files as instructed in [`INSTALL.md`](INSTALL.md). 28 | This example shows how to run an end-to-end trained DensePose-RCNN model from the model zoo using a single GPU for inference. As configured, this will run inference on all images in `coco_2014_minival` (which must be properly installed). 29 | 30 | ``` 31 | python2 tools/test_net.py \ 32 | --cfg configs/DensePose_ResNet101_FPN_s1x-e2e.yaml \ 33 | TEST.WEIGHTS https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl \ 34 | NUM_GPUS 1 35 | ``` 36 | 37 | ## Training a Model 38 | 39 | This example shows how to train a model using the DensePose-COCO dataset. The model will be an end-to-end trained DensePose-RCNN using a ResNet-50-FPN backbone. 40 | 41 | ``` 42 | python2 tools/train_net.py \ 43 | --cfg configs/DensePose_ResNet50_FPN_single_GPU.yaml \ 44 | OUTPUT_DIR /tmp/detectron-output 45 | ``` 46 | The models we have provided in the model zoo are trained using 8 gpus. As in any Detectron configs, we use linear scaling rule to adjust learning schedules. Please refer to the following paper: [Accurate, Large Minibatch SGD: Training ImageNet in 1 Hour](https://arxiv.org/abs/1706.02677). We also provide learning rate and number of iterations for varying number of GPUs. 47 | 48 | -------------------------------------------------------------------------------- /MODEL_ZOO.md: -------------------------------------------------------------------------------- 1 | # DensePose Model Zoo 2 | 3 | ## RPN Files 4 | Herein, we provide RPN files for DensePose-COCO dataset `train`, `minival` and `valminusminival` partitions. 5 | 6 | The RPN results are obtained using the models provided in the Detectron model-zoo. For performance measures please refer to [`this file`](https://github.com/facebookresearch/Detectron/blob/master/MODEL_ZOO.md#person-specific-rpn-baselines). 7 | 8 | **X-101-32x8d-FPN:** [`[train]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_X-101-32x8d-FPN.pkl) [`[minival]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_X-101-32x8d-FPN.pkl) [`[valminusminival]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_X-101-32x8d-FPN.pkl) 9 | 10 | **R-50-FPN:** [`[train]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl) [`[minival]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl) [`[valminusminival]`](https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl) 11 | 12 | ## DensePose-RCNN Models 13 | 14 | | Model | AP | AP50 | AP75 | APm |APl | 15 | |-----|-----|--- |--- |--- |--- | 16 | | [`ResNet50_FPN_s1x`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet50_FPN_s1x.pkl)| 0.4748 |0.8368|0.4820 |0.4262|0.4948| 17 | | [`ResNet50_FPN_s1x-e2e`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet50_FPN_s1x-e2e.pkl)|0.4892 |0.8490|0.5078| 0.4384|0.5059| 18 | | [`ResNet101_FPN_s1x`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x.pkl)|0.4978| 0.8521|0.5276 |0.4373|0.5164| 19 | | [`ResNet101_FPN_s1x-e2e`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_s1x-e2e.pkl)|0.5147 |0.8660|0.5601 |0.4716|0.5291| 20 | | [`ResNet101_FPN_32x8d_s1x`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_32x8d_s1x.pkl)|0.5095 | 0.8590|0.5381 |0.4605|0.5272| 21 | | [`ResNet101_FPN_32x8d_s1x-e2e`](https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet101_FPN_32x8d_s1x-e2e.pkl)|0.5554 | 0.8908|0.6080 |0.5067|0.5676| 22 | 23 | Please note that due to the new per-part normalization the AP numbers do not match those reported in the paper, which are obtained with global normalization factor `K = 0.255`. 24 | 25 | ## Models with Multiple Heads 26 | 27 | We provide an example of a 28 | [configuration file](configs/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml) 29 | that performs multiple tasks 30 | using the same backbone architecture (ResNet-50) and containing several 31 | heads for dense pose, mask and keypoints estimation. We note that this 32 | example is provided purely for illustrative purposes and the performance 33 | of the model is not tuned. As an alternative, one can always use 34 | independent models for individual tasks. 35 | 36 | | Task | AP | AP50 | AP75 | APm |APl | 37 | |-----|-----|--- |--- |--- |--- | 38 | | mask | 0.4903 | 0.8160 | 0.5300 | 0.4379 | 0.6417 | 39 | | keypoint | 0.6159 | 0.8614 | 0.6665 | 0.4847 | 0.7233 | 40 | | densepose | 0.5075 | 0.8606 | 0.5373 | 0.4356 | 0.5265 | 41 | 42 | ([config](configs/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml), 43 | [model](https://dl.fbaipublicfiles.com/densepose/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.pkl), 44 | [md5](https://dl.fbaipublicfiles.com/densepose/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.pkl.md5sum)) 45 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # Don't use the --user flag for setup.py develop mode with virtualenv. 2 | DEV_USER_FLAG=$(shell python2 -c "import sys; print('' if hasattr(sys, 'real_prefix') else '--user')") 3 | 4 | .PHONY: default 5 | default: dev 6 | 7 | .PHONY: install 8 | install: 9 | python2 setup.py install 10 | 11 | .PHONY: ops 12 | ops: 13 | mkdir -p build && cd build && cmake .. && make -j$(shell nproc) 14 | 15 | .PHONY: dev 16 | dev: 17 | python2 setup.py develop $(DEV_USER_FLAG) 18 | 19 | .PHONY: clean 20 | clean: 21 | python2 setup.py develop --uninstall $(DEV_USER_FLAG) 22 | rm -rf build 23 | -------------------------------------------------------------------------------- /NOTICE: -------------------------------------------------------------------------------- 1 | Portions of this software are derived from py-faster-rcnn. 2 | 3 | ============================================================================== 4 | py-faster-rcnn licence 5 | ============================================================================== 6 | 7 | Faster R-CNN 8 | 9 | The MIT License (MIT) 10 | 11 | Copyright (c) 2015 Microsoft Corporation 12 | 13 | Permission is hereby granted, free of charge, to any person obtaining a copy 14 | of this software and associated documentation files (the "Software"), to deal 15 | in the Software without restriction, including without limitation the rights 16 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 | copies of the Software, and to permit persons to whom the Software is 18 | furnished to do so, subject to the following conditions: 19 | 20 | The above copyright notice and this permission notice shall be included in 21 | all copies or substantial portions of the Software. 22 | 23 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 | THE SOFTWARE. 30 | -------------------------------------------------------------------------------- /PoseTrack/README.md: -------------------------------------------------------------------------------- 1 | # DensePose-PoseTrack 2 | We introduce the DensePose-Posetrack dataset, which consists of videos of multiple persons containing rapid motions, occlusions and scale variations which leads to a very challenging correspondence task. DensePose-PoseTrack will be a part of the [ECCV 2018 - POSETRACK CHALLENGE](https://posetrack.net/workshops/eccv2018/). 3 | 4 |
5 | 6 |
7 | 8 | Please first follow the [INSTALL.md](https://github.com/facebookresearch/DensePose/blob/master/INSTALL.md) and [GETTING_STARTED.md](https://github.com/facebookresearch/DensePose/blob/master/GETTING_STARTED.md), to install and run the DensePose inference and training. Herein, we provide instructions to download and evaluate on the DensePose-PoseTrack dataset. 9 | 10 | ### Fetch DensePose-PoseTrack dataset 11 | 12 | To download the images of the original PoseTrack dataset, please refer to the posetrack webpage: https://posetrack.net. Note that we have used the keypoints provided in the PoseTrack dataset to form the DensePose-PoseTrack dataset. Our dense correspondence annotations are distributed under [NonCommercial Creative Commons](https://creativecommons.org/licenses/by-nc/2.0/) license. 13 | 14 | To downoad, run: 15 | ``` 16 | cd $DENSEPOSE/PoseTrack 17 | bash get_DensePose_PoseTrack.sh 18 | ``` 19 | This script downloads *.json files that contains all annotations along with files that only contains annotations for images with densepose annotations. The latter is used during evaluation. 20 | 21 | Visualization of the DensePose-PoseTrack annotations are demonstrated in the [DensePose-PoseTrack-Visualize.ipynb](https://github.com/facebookresearch/DensePose/blob/master/PoseTrack/DensePose-PoseTrack-Visualize.ipynb): 22 | 23 |
24 | 25 |
26 | 27 | 28 | ## Setting-up the PoseTrack dataset. 29 | 30 | Create a symlink for the PoseTrack dataset in your `datasets/data` folder. 31 | ``` 32 | ln -s /path/to/posetrack $DENSEPOSE/detectron/datasets/data/posetrack 33 | ``` 34 | Create symlinks for the DensePose-PoseTrack annotations 35 | 36 | ``` 37 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_only_posetrack_train2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 38 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_only_posetrack_val2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 39 | ln -s $DENSEPOSE/PoseTrack/DensePose_PoseTrack/densepose_posetrack_test2017.json $DENSEPOSE/detectron/datasets/data/posetrack/ 40 | ``` 41 | Your local PoseTrack dataset copy at `/path/to/posetrack` should have the following directory structure: 42 | 43 | ``` 44 | posetrack 45 | |_ images 46 | | |_ 47 | | |_ ... 48 | | |_ . 49 | |_ densepose_only_posetrack_train2017.json 50 | |_ densepose_only_posetrack_val2017.json 51 | |_ densepose_posetrack_test2017.json 52 | ``` 53 | 54 | ### Evaluation on DensePose-PoseTrack dataset 55 | 56 | To demonstrate the evaluation, we use a DensePose-RCNN with a ResNet-50 trunk that is trained on the DensePose-COCO dataset. 57 | ``` 58 | cd $DENSEPOSE 59 | python2 tools/test_net.py \ 60 | --cfg PoseTrack/configs/DensePose_ResNet50_FPN_s1x-e2e.yaml \ 61 | TEST.WEIGHTS https://dl.fbaipublicfiles.com/densepose/DensePose_ResNet50_FPN_s1x-e2e.pkl \ 62 | NUM_GPUS 1 63 | ``` 64 | The evaluation of this baseline network should yield `Bounding Box AP: 0.4438` and `DensePose AP: 0.2698`. 65 | -------------------------------------------------------------------------------- /PoseTrack/configs/DensePose_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 70 | TEST: 71 | DATASETS: ('dense_posetrack_2017_val',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /PoseTrack/get_DensePose_PoseTrack.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | mkdir DensePose_PoseTrack 3 | cd DensePose_PoseTrack 4 | wget -O densepose_only_posetrack_train2017.json https://www.dropbox.com/s/tpbaemzvlojo2iz/densepose_only_posetrack_train2017.json?dl=1 5 | wget -O densepose_only_posetrack_val2017.json https://www.dropbox.com/s/43h43s0t3hkuogr/densepose_only_posetrack_val2017.json?dl=1 6 | wget -O densepose_posetrack_test2017.json https://www.dropbox.com/s/48tkd4pr8aa3rex/densepose_posetrack_test2017.json?dl=1 7 | wget -O densepose_posetrack_train2017.json https://www.dropbox.com/s/awbdp3v0dz4jcau/densepose_posetrack_train2017.json?dl=1 8 | wget -O densepose_posetrack_val2017.json https://www.dropbox.com/s/6tdmqx0h6a04vzz/densepose_posetrack_val2017.json?dl=1 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # DensePose: 2 | **Dense Human Pose Estimation In The Wild** 3 | 4 | _Rıza Alp Güler, Natalia Neverova, Iasonas Kokkinos_ 5 | 6 | [[`densepose.org`](https://densepose.org)] [[`arXiv`](https://arxiv.org/abs/1802.00434)] [[`BibTeX`](#CitingDensePose)] 7 | 8 | Dense human pose estimation aims at mapping all human pixels of an RGB image to the 3D surface of the human body. 9 | DensePose-RCNN is implemented in the [Detectron](https://github.com/facebookresearch/Detectron) framework and is powered by [Caffe2](https://github.com/caffe2/caffe2). 10 | 11 |
12 | 13 |
14 | 15 | 16 | In this repository, we provide the code to train and evaluate DensePose-RCNN. We also provide notebooks to visualize the collected DensePose-COCO dataset and show the correspondences to the SMPL model. 17 | 18 | ## Important Note 19 | 20 | **!!! This project is no longer supported !!!** 21 | 22 | DensePose is now part of Detectron2 (https://github.com/facebookresearch/detectron2/tree/master/projects/DensePose). There you can find the most up to date architectures / models. If you think some feature is missing from there, please post an issue in [Detectron2 DensePose](https://github.com/facebookresearch/detectron2/tree/master/projects/DensePose). 23 | 24 | ## Installation 25 | 26 | Please find installation instructions for Caffe2 and DensePose in [`INSTALL.md`](INSTALL.md), a document based on the [Detectron](https://github.com/facebookresearch/Detectron) installation instructions. 27 | 28 | ## Inference-Training-Testing 29 | 30 | After installation, please see [`GETTING_STARTED.md`](GETTING_STARTED.md) for examples of inference and training and testing. 31 | 32 | ## Notebooks 33 | 34 | ### Visualization of DensePose-COCO annotations: 35 | 36 | See [`notebooks/DensePose-COCO-Visualize.ipynb`](notebooks/DensePose-COCO-Visualize.ipynb) to visualize the DensePose-COCO annotations on the images: 37 | 38 |
39 | 40 |
41 | 42 | --- 43 | 44 | ### DensePose-COCO in 3D: 45 | 46 | See [`notebooks/DensePose-COCO-on-SMPL.ipynb`](notebooks/DensePose-COCO-on-SMPL.ipynb) to localize the DensePose-COCO annotations on the 3D template ([`SMPL`](http://smpl.is.tue.mpg.de)) model: 47 | 48 |
49 | 50 |
51 | 52 | --- 53 | ### Visualize DensePose-RCNN Results: 54 | 55 | See [`notebooks/DensePose-RCNN-Visualize-Results.ipynb`](notebooks/DensePose-RCNN-Visualize-Results.ipynb) to visualize the inferred DensePose-RCNN Results. 56 | 57 |
58 | 59 |
60 | 61 | --- 62 | ### DensePose-RCNN Texture Transfer: 63 | 64 | See [`notebooks/DensePose-RCNN-Texture-Transfer.ipynb`](notebooks/DensePose-RCNN-Texture-Transfer.ipynb) to localize the DensePose-COCO annotations on the 3D template ([`SMPL`](http://smpl.is.tue.mpg.de)) model: 65 | 66 |
67 | 68 |
69 | 70 | ## License 71 | 72 | This source code is licensed under the license found in the [`LICENSE`](LICENSE) file in the root directory of this source tree. 73 | 74 | ## Citing DensePose 75 | 76 | If you use Densepose, please use the following BibTeX entry. 77 | 78 | ``` 79 | @InProceedings{Guler2018DensePose, 80 | title={DensePose: Dense Human Pose Estimation In The Wild}, 81 | author={R\{i}za Alp G\"uler, Natalia Neverova, Iasonas Kokkinos}, 82 | journal={The IEEE Conference on Computer Vision and Pattern Recognition (CVPR)}, 83 | year={2018} 84 | } 85 | ``` 86 | 87 | 88 | -------------------------------------------------------------------------------- /challenge/2018_COCO_DensePose/data_format.md: -------------------------------------------------------------------------------- 1 | # Data Format 2 | 3 | The annotations are stored in [JSON](http://json.org/). Please note that 4 | [COCO API](https://github.com/cocodataset/cocoapi) described on the 5 | [download](http://cocodataset.org/#download) page can be used to access 6 | and manipulate all annotations. 7 | 8 | The annotations file structure is outlined below: 9 | ``` 10 | { 11 | "images" : [image], 12 | "annotations" : [annotation], 13 | "categories" : [category] 14 | } 15 | 16 | image { 17 | "coco_url" : str, 18 | "date_captured" : datetime, 19 | "file_name" : str, 20 | "flickr_url" : str, 21 | "id" : int, 22 | "width" : int, 23 | "height" : int, 24 | "license" : int 25 | } 26 | 27 | annotation { 28 | "area": float, 29 | "bbox": [x, y, width, height], 30 | "category_id": int, 31 | "dp_I": [float], 32 | "dp_U": [float], 33 | "dp_V": [float], 34 | "dp_masks": [dp_mask], 35 | "dp_x": [float], 36 | "dp_y": [float], 37 | "id": int, 38 | "image_id": int, 39 | "iscrowd": 0 or 1, 40 | "keypoints": [float], 41 | "segmentation": RLE or [polygon] 42 | } 43 | 44 | category { 45 | "id" : int, 46 | "name" : str, 47 | "supercategory" : str, 48 | "keypoints": [str], 49 | "skeleton": [edge] 50 | } 51 | 52 | dp_mask { 53 | "counts": str, 54 | "size": [int, int] 55 | } 56 | ``` 57 | 58 | Each dense pose annotation contains a series of fields, including the category 59 | id and segmentation mask of the person. The segmentation format depends on 60 | whether the instance represents a single object (`iscrowd=0` in which case 61 | polygons are used) or a collection of objects (`iscrowd=1` in which case RLE 62 | is used). Note that a single object (`iscrowd=0`) may require multiple polygons, 63 | for example if occluded. Crowd annotations (`iscrowd=1`) are used to label large 64 | groups of objects (e.g. a crowd of people). In addition, an enclosing bounding 65 | box is provided for each person (box coordinates are measured from the top left 66 | image corner and are 0-indexed). 67 | 68 | The categories field of the annotation structure stores the mapping of category 69 | id to category and supercategory names. It also has two fields: "keypoints", 70 | which is a length `k` array of keypoint names, and "skeleton", which defines 71 | connectivity via a list of keypoint edge pairs and is used for visualization. 72 | 73 | DensePose annotations are stored in `dp_*` fields: 74 | 75 | *Annotated masks*: 76 | 77 | * `dp_masks`: RLE encoded dense masks. All part masks are of size 256x256. 78 | They correspond to 14 semantically meaningful parts of the body: `Torso`, 79 | `Right Hand`, `Left Hand`, `Left Foot`, `Right Foot`, `Upper Leg Right`, 80 | `Upper Leg Left`, `Lower Leg Right`, `Lower Leg Left`, `Upper Arm Left`, 81 | `Upper Arm Right`, `Lower Arm Left`, `Lower Arm Right`, `Head`; 82 | 83 | *Annotated points*: 84 | 85 | * `dp_x`, `dp_y`: spatial coordinates of collected points on the image. 86 | The coordinates are scaled such that the bounding box size is 256x256; 87 | * `dp_I`: The patch index that indicates which of the 24 surface patches the 88 | point is on. Patches correspond to the body parts described above. Some 89 | body parts are split into 2 patches: `1, 2 = Torso`, `3 = Right Hand`, 90 | `4 = Left Hand`, `5 = Left Foot`, `6 = Right Foot`, `7, 9 = Upper Leg Right`, 91 | `8, 10 = Upper Leg Left`, `11, 13 = Lower Leg Right`, `12, 14 = Lower Leg Left`, 92 | `15, 17 = Upper Arm Left`, `16, 18 = Upper Arm Right`, `19, 21 = Lower Arm Left`, 93 | `20, 22 = Lower Arm Right`, `23, 24 = Head`; 94 | * `dp_U`, `dp_V`: Coordinates in the UV space. Each surface patch has a 95 | separate 2D parameterization. 96 | 97 | -------------------------------------------------------------------------------- /challenge/2018_COCO_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # COCO 2018 DensePose Task 2 | 3 | ![DensePose Splash Image](http://cocodataset.org/images/densepose-splash.png) 4 | 5 | ## Overview 6 | 7 | The COCO DensePose Task requires dense estimation of human pose in challenging, 8 | uncontrolled conditions. The DensePose task involves simultaneously detecting 9 | people, segmenting their bodies and mapping all image pixels that belong to a 10 | human body to the 3D surface of the body. For full details of this task please 11 | see the [DensePose evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [Joint COCO and Mapillary Recognition Challenge Workshop](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html) 15 | at ECCV 2018. For further details about the joint workshop please 16 | visit the workshop page. Please also see the related COCO 17 | [detection](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-detection), 18 | [panoptic](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-panoptic), 19 | [keypoints](http://cocodataset.org/workshop/coco-mapillary-eccv-2018.html#coco-keypoints) 20 | and [stuff](http://cocodataset.org/#stuff-2018) tasks. 21 | 22 | The COCO train, validation, and test sets, containing more than 39,000 images 23 | and 56,000 person instances labeled with DensePose annotations are available 24 | for [download](http://cocodataset.org/#download). 25 | Annotations on train ( 26 | [train 1](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_train.json), 27 | [train 2](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_valminusminival.json) 28 | ) and [val](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_minival.json) 29 | with over 48,000 people are publicly available. 30 | [Test set](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_test.json) 31 | with the list of images is also available for download. 32 | 33 | Evaluation server for the 2018 task is 34 | [open](https://competitions.codalab.org/competitions/19636). 35 | 36 | ## Dates 37 | 38 | []() | []() 39 | ---- | ----- 40 | **August 17, 2018** | Submission deadline (23:59 PST) 41 | August 26, 2018 | Challenge winners notified 42 | September 9, 2018 | Winners present at ECCV 2018 Workshop 43 | 44 | ## Organizers 45 | 46 | Riza Alp Güler (INRIA, CentraleSupélec) 47 | 48 | Natalia Neverova (Facebook AI Research) 49 | 50 | Iasonas Kokkinos (Facebook AI Research) 51 | 52 | ## Task Guidelines 53 | 54 | Participants are recommended but not restricted to train 55 | their algorithms on COCO DensePose train and val sets. 56 | The [download](http://cocodataset.org/#download) page has 57 | links to all COCO data. When participating in this task, 58 | please specify any and all external data used for training 59 | in the "method description" when uploading results to the 60 | evaluation server. A more thorough explanation of all these 61 | details is available on the 62 | [guidelines](http://cocodataset.org/#guidelines) page, 63 | please be sure to review it carefully prior to participating. 64 | Results in the [correct format](results_format.md) must be 65 | [uploaded](upload.md) to the 66 | [evaluation server](https://competitions.codalab.org/competitions/19636). 67 | The [evaluation](evaluation.md) page lists detailed information 68 | regarding how results will be evaluated. Challenge participants 69 | with the most successful and innovative methods will be invited 70 | to present at the workshop. 71 | 72 | ## Tools and Instructions 73 | 74 | We provide extensive API support for the COCO images, 75 | annotations, and evaluation code. To download the COCO DensePose API, 76 | please visit our 77 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 78 | Due to the large size of COCO and the complexity of this task, 79 | the process of participating may not seem simple. To help, we provide 80 | explanations and instructions for each step of the process: 81 | [download](http://cocodataset.org/#download), 82 | [data format](data_format.md), 83 | [results format](results_format.md), 84 | [upload](upload.md) and [evaluation](evaluation.md) pages. 85 | For additional questions, please contact info@cocodataset.org. 86 | 87 | 88 | 89 | -------------------------------------------------------------------------------- /challenge/2018_COCO_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by COCO DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | dense pose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /challenge/2018_COCO_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the COCO DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in all COCO challenges. 17 | 18 | 2. Carefully review the [guidelines](http://cocodataset.org/#guidelines) for 19 | entering the COCO challenges and using the test sets. 20 | 21 | 3. Prepare a JSON file containing your results in the correct 22 | [results format](results_format.md) for the challenge you wish to enter. 23 | 24 | 4. File naming: the JSON file should be named `densepose_[subset]_[alg]_results.json`. 25 | Replace `[subset]` with the subset you are using (`val` or `test`), 26 | and `[alg]` with your algorithm name. Finally, place the JSON 27 | file into a zip file named `densepose_[subset]_[alg]_results.zip`. 28 | 29 | 5. To submit your zipped result file to the COCO DensePose Challenge, click on 30 | the “Participate” tab on the 31 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/19636) page. 32 | When you select “Submit / View Results” on the left panel, you will be able to choose 33 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 34 | prompt you to select the results zip file for upload. After the file is uploaded 35 | the evaluation server will begin processing. To view the status of your submission 36 | please select “Refresh Status”. Please be patient, the evaluation may take quite 37 | some time to complete (from ~20m to a few hours). If the status of your submission 38 | is “Failed” please check your file is named correctly and has the right format. 39 | 40 | 6. Please enter submission information into Codalab. The most important fields 41 | are "Team name", "Method description", and "Publication URL", which are used 42 | to populate the COCO leaderboard. Additionally, under "user setting" in the 43 | upper right, please add "Team members". There have been issues with the 44 | "Method Description", we may collect these via email if necessary. These 45 | settings are not intuitive, but we have no control of the Codalab website. 46 | For the "Method description", especially for COCO DensePose challenge entries, 47 | we encourage participants to give detailed method information that will help 48 | the award committee invite participants with the most innovative methods. 49 | Listing external data used is mandatory. You may also consider giving some 50 | basic performance breakdowns on test subset (e.g., single model versus 51 | ensemble results), runtime, or any other information you think may be pertinent 52 | to highlight the novelty or efficacy of your method. 53 | 54 | 7. After you submit your results to the test-dev eval server, you can control 55 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 56 | the public visibility of your results please select either “post to leaderboard” 57 | or “remove from leaderboard”. Only one result can be published to the leaderboard 58 | at any time. 59 | 60 | 8. After evaluation is complete and the server shows a status of “Finished”, 61 | you will have the option to download your evaluation results by selecting 62 | “Download evaluation output from scoring step.” The zip file will contain the 63 | score file `scores.txt`. 64 | 65 | -------------------------------------------------------------------------------- /challenge/2018_PoseTrack_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # ECCV 2018 PoseTrack DensePose Task 2 | 3 | ![PoseTrack DensePose Splash Image](https://posetrack.net/workshops/eccv2018/assets/images/densepose-posetrack_examples.jpg) 4 | 5 | ## Overview 6 | 7 | The PoseTrack DensePose Task requires dense estimation of human pose through time 8 | in challenging, uncontrolled conditions. The task involves processing video frames 9 | to simultaneously detect people, segment their bodies and map all image pixels 10 | that belong to a human body to the 3D surface of the body. For full details on 11 | this task please see the [evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [PoseTrack Challenge Workshop](https://posetrack.net/workshops/eccv2018/) 15 | at ECCV 2018. For further details about the workshop please 16 | visit the workshop page. Please also see the related PoseTrack 17 | [Articulated Human Pose Estimation and Tracking](https://posetrack.net/workshops/eccv2018/#challenges) 18 | and 19 | [3D Human Pose Estimation](https://posetrack.net/workshops/eccv2018/#challenges) 20 | tasks. 21 | 22 | The PoseTrack DensePose train, validation, and test sets, containing more 23 | than 5,000 images 24 | and 27,000 person instances labeled with DensePose annotations are available 25 | for [download](https://posetrack.net/users/download.php). 26 | Annotations on 27 | [train](https://www.dropbox.com/s/tpbaemzvlojo2iz/densepose_only_posetrack_train2017.json?dl=1) 28 | and 29 | [val](https://www.dropbox.com/s/43h43s0t3hkuogr/densepose_only_posetrack_val2017.json?dl=1) 30 | with over 13,000 people are publicly available. 31 | 32 | Evaluation server for the 2018 task is 33 | [open](https://competitions.codalab.org/competitions/19650). 34 | 35 | ## Dates 36 | 37 | []() | []() 38 | ---- | ----- 39 | **August 18, 2018** | Submission deadline (23:59 PST) 40 | September 2, 2018 | Challenge winners notified 41 | September 8, 2018 | Winners present at ECCV 2018 Workshop 42 | 43 | ## Organizers 44 | 45 | Riza Alp Güler (INRIA, CentraleSupélec) 46 | 47 | Natalia Neverova (Facebook AI Research) 48 | 49 | Iasonas Kokkinos (Facebook AI Research) 50 | 51 | ## Task Guidelines 52 | 53 | Participants are recommended but not restricted to train 54 | their algorithms on PoseTrack DensePose train and val sets. 55 | The [download](https://posetrack.net/users/download.php) page has 56 | links to the image data. When participating in this task, 57 | please specify any and all external data used for training 58 | in the "method description" when uploading results to the 59 | evaluation server. **Listing external data used is mandatory.** 60 | We emphasize that any form of **annotation or use of the test sets 61 | for supervised or unsupervised training is strictly forbidden**. 62 | A more thorough explanation of all these 63 | details is available on the 64 | [upload](upload.md) page, 65 | please be sure to review it carefully prior to participating. 66 | Results in the [correct format](results_format.md) must be 67 | [uploaded](upload.md) to the 68 | [evaluation server](https://competitions.codalab.org/competitions/19650). 69 | The [evaluation](evaluation.md) page lists detailed information 70 | regarding how results will be evaluated. Challenge participants 71 | with the most successful and innovative methods will be invited 72 | to present at the workshop. 73 | 74 | ## Tools and Instructions 75 | 76 | We provide extensive API support for the images, annotations, 77 | and evaluation code. To download the COCO DensePose API, 78 | please visit our 79 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 80 | Due to the complexity of this task, the process of participating 81 | may not seem simple. To help, we provide explanations and 82 | instructions for each step of the process: 83 | [download](https://posetrack.net/users/download.php), 84 | [data format](data_format.md), 85 | [results format](results_format.md), 86 | [upload](upload.md) and [evaluation](evaluation.md) pages. 87 | 88 | -------------------------------------------------------------------------------- /challenge/2018_PoseTrack_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by PoseTrack DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | DensePose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /challenge/2018_PoseTrack_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the PoseTrack DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in 17 | PoseTrack DensePose challenge. 18 | 19 | 2. Carefully review the [guidelines](readme.md) for 20 | entering the PoseTrack DensePose challenge and using the test sets. 21 | We emphasize that any form of **annotation or use of the test sets 22 | for supervised or unsupervised training is strictly forbidden**. 23 | 24 | 3. Prepare a JSON file containing your results in the correct 25 | [results format](results_format.md). 26 | 27 | 4. File naming: the JSON file should be named `posetrack_[subset]_[alg]_results.json`. 28 | Replace `[subset]` with the subset you are using (`val` or `test`), 29 | and `[alg]` with your algorithm name. Finally, place the JSON 30 | file into a zip file named `posetrack_[subset]_[alg]_results.zip`. 31 | 32 | 5. To submit your zipped result file to the PoseTrack DensePose Challenge, click on 33 | the “Participate” tab on the 34 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/19650) page. 35 | When you select “Submit / View Results” on the left panel, you will be able to choose 36 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 37 | prompt you to select the results zip file for upload. After the file is uploaded 38 | the evaluation server will begin processing. To view the status of your submission 39 | please select “Refresh Status”. Please be patient, the evaluation may take quite 40 | some time to complete (from ~20m to a few hours). If the status of your submission 41 | is “Failed” please check your file is named correctly and has the right format. 42 | 43 | 6. Please enter submission information into Codalab. The most important fields 44 | are "Team name", "Method description", and "Publication URL", which are used 45 | to populate the leaderboard. Additionally, under "user setting" in the 46 | upper right, please add "Team members". There have been issues with the 47 | "Method Description", we may collect these via email if necessary. These 48 | settings are not intuitive, but we have no control of the Codalab website. 49 | For the "Method description" we encourage participants to give detailed 50 | method information that will help 51 | the award committee invite participants with the most innovative methods. 52 | **Listing external data used is mandatory.** You may also consider giving some 53 | basic performance breakdowns on test subset (e.g., single model versus 54 | ensemble results), runtime, or any other information you think may be pertinent 55 | to highlight the novelty or efficacy of your method. 56 | 57 | 7. After you submit your results to the test eval server, you can control 58 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 59 | the public visibility of your results please select either “post to leaderboard” 60 | or “remove from leaderboard”. Only one result can be published to the leaderboard 61 | at any time. 62 | 63 | 8. After evaluation is complete and the server shows a status of “Finished”, 64 | you will have the option to download your evaluation results by selecting 65 | “Download evaluation output from scoring step.” The zip file will contain the 66 | score file `scores.txt`. 67 | 68 | -------------------------------------------------------------------------------- /challenge/2019_COCO_DensePose/data_format.md: -------------------------------------------------------------------------------- 1 | # Data Format 2 | 3 | The annotations are stored in [JSON](http://json.org/). Please note that 4 | [COCO API](https://github.com/cocodataset/cocoapi) described on the 5 | [download](http://cocodataset.org/#download) page can be used to access 6 | and manipulate all annotations. 7 | 8 | The annotations file structure is outlined below: 9 | ``` 10 | { 11 | "images" : [image], 12 | "annotations" : [annotation], 13 | "categories" : [category] 14 | } 15 | 16 | image { 17 | "coco_url" : str, 18 | "date_captured" : datetime, 19 | "file_name" : str, 20 | "flickr_url" : str, 21 | "id" : int, 22 | "width" : int, 23 | "height" : int, 24 | "license" : int 25 | } 26 | 27 | annotation { 28 | "area": float, 29 | "bbox": [x, y, width, height], 30 | "category_id": int, 31 | "dp_I": [float], 32 | "dp_U": [float], 33 | "dp_V": [float], 34 | "dp_masks": [dp_mask], 35 | "dp_x": [float], 36 | "dp_y": [float], 37 | "id": int, 38 | "image_id": int, 39 | "iscrowd": 0 or 1, 40 | "keypoints": [float], 41 | "segmentation": RLE or [polygon] 42 | } 43 | 44 | category { 45 | "id" : int, 46 | "name" : str, 47 | "supercategory" : str, 48 | "keypoints": [str], 49 | "skeleton": [edge] 50 | } 51 | 52 | dp_mask { 53 | "counts": str, 54 | "size": [int, int] 55 | } 56 | ``` 57 | 58 | Each dense pose annotation contains a series of fields, including the category 59 | id and segmentation mask of the person. The segmentation format depends on 60 | whether the instance represents a single object (`iscrowd=0` in which case 61 | polygons are used) or a collection of objects (`iscrowd=1` in which case RLE 62 | is used). Note that a single object (`iscrowd=0`) may require multiple polygons, 63 | for example if occluded. Crowd annotations (`iscrowd=1`) are used to label large 64 | groups of objects (e.g. a crowd of people). In addition, an enclosing bounding 65 | box is provided for each person (box coordinates are measured from the top left 66 | image corner and are 0-indexed). 67 | 68 | The categories field of the annotation structure stores the mapping of category 69 | id to category and supercategory names. It also has two fields: "keypoints", 70 | which is a length `k` array of keypoint names, and "skeleton", which defines 71 | connectivity via a list of keypoint edge pairs and is used for visualization. 72 | 73 | DensePose annotations are stored in `dp_*` fields: 74 | 75 | *Annotated masks*: 76 | 77 | * `dp_masks`: RLE encoded dense masks. All part masks are of size 256x256. 78 | They correspond to 14 semantically meaningful parts of the body: `Torso`, 79 | `Right Hand`, `Left Hand`, `Left Foot`, `Right Foot`, `Upper Leg Right`, 80 | `Upper Leg Left`, `Lower Leg Right`, `Lower Leg Left`, `Upper Arm Left`, 81 | `Upper Arm Right`, `Lower Arm Left`, `Lower Arm Right`, `Head`; 82 | 83 | *Annotated points*: 84 | 85 | * `dp_x`, `dp_y`: spatial coordinates of collected points on the image. 86 | The coordinates are scaled such that the bounding box size is 256x256; 87 | * `dp_I`: The patch index that indicates which of the 24 surface patches the 88 | point is on. Patches correspond to the body parts described above. Some 89 | body parts are split into 2 patches: `1, 2 = Torso`, `3 = Right Hand`, 90 | `4 = Left Hand`, `5 = Left Foot`, `6 = Right Foot`, `7, 9 = Upper Leg Right`, 91 | `8, 10 = Upper Leg Left`, `11, 13 = Lower Leg Right`, `12, 14 = Lower Leg Left`, 92 | `15, 17 = Upper Arm Left`, `16, 18 = Upper Arm Right`, `19, 21 = Lower Arm Left`, 93 | `20, 22 = Lower Arm Right`, `23, 24 = Head`; 94 | * `dp_U`, `dp_V`: Coordinates in the UV space. Each surface patch has a 95 | separate 2D parameterization. 96 | 97 | -------------------------------------------------------------------------------- /challenge/2019_COCO_DensePose/readme.md: -------------------------------------------------------------------------------- 1 | # COCO 2019 DensePose Task 2 | 3 | ![DensePose Splash Image](http://cocodataset.org/images/densepose-splash.png) 4 | 5 | ## Overview 6 | 7 | The COCO DensePose Task requires dense estimation of human pose in challenging, 8 | uncontrolled conditions. The DensePose task involves simultaneously detecting 9 | people, segmenting their bodies and mapping all image pixels that belong to a 10 | human body to the 3D surface of the body. For full details of this task please 11 | see the [DensePose evaluation](evaluation.md) page. 12 | 13 | This task is part of the 14 | [COCO+Mapillary Joint Recognition Challenge Workshop](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html) 15 | at ICCV 2019. For further details about the joint workshop, as well as **new rules regarding technical reports and awards**, please 16 | visit the workshop page. 17 | Please also see the related COCO 18 | [detection](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-detection), 19 | [panoptic](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-panoptic) 20 | and 21 | [keypoints](http://cocodataset.org/workshop/coco-mapillary-iccv-2019.html#coco-keypoints) 22 | tasks. 23 | 24 | The COCO train, validation, and test sets, containing more than 39,000 images 25 | and 56,000 person instances labeled with DensePose annotations are available 26 | for [download](http://cocodataset.org/#download). 27 | Annotations on train ( 28 | [train 1](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_train.json), 29 | [train 2](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_valminusminival.json) 30 | ) and [val](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_minival.json) 31 | with over 48,000 people are publicly available. 32 | [Test set](https://dl.fbaipublicfiles.com/densepose/densepose_coco_2014_test.json) 33 | with the list of images is also available for download. 34 | 35 | Evaluation server for the 2019 task is 36 | [open](https://competitions.codalab.org/competitions/20660). 37 | 38 | ## Dates 39 | 40 | []() | []() 41 | ---- | ----- 42 | **October 4, 2019** | Submission deadline (23:59 PST) 43 | October 11, 2019 | Technical report submission deadline 44 | October 18, 2019 | Challenge winners notified 45 | October 27, 2019 | Winners present at ICCV 2019 Workshop 46 | 47 | ## Organizers 48 | 49 | Vasil Khalidov (Facebook AI Research) 50 | 51 | Natalia Neverova (Facebook AI Research) 52 | 53 | Riza Alp Güler (Imperial College London / Ariel AI) 54 | 55 | Iasonas Kokkinos (UCL / Ariel AI) 56 | 57 | ## Task Guidelines 58 | 59 | Participants are recommended but not restricted to train 60 | their algorithms on COCO DensePose train and val sets. 61 | The [download](http://cocodataset.org/#download) page has 62 | links to all COCO data. When participating in this task, 63 | please specify any and all external data used for training 64 | in the "method description" when uploading results to the 65 | evaluation server. A more thorough explanation of all these 66 | details is available on the 67 | [guidelines](http://cocodataset.org/#guidelines) page, 68 | please be sure to review it carefully prior to participating. 69 | Results in the [correct format](results_format.md) must be 70 | [uploaded](upload.md) to the 71 | [evaluation server](https://competitions.codalab.org/competitions/20660). 72 | The [evaluation](evaluation.md) page lists detailed information 73 | regarding how results will be evaluated. Challenge participants 74 | with the most successful and innovative methods will be invited 75 | to present at the workshop. 76 | 77 | ## Tools and Instructions 78 | 79 | We provide extensive API support for the COCO images, 80 | annotations, and evaluation code. To download the COCO DensePose API, 81 | please visit our 82 | [GitHub repository](https://github.com/facebookresearch/DensePose/). 83 | Due to the large size of COCO and the complexity of this task, 84 | the process of participating may not seem simple. To help, we provide 85 | explanations and instructions for each step of the process: 86 | [download](http://cocodataset.org/#download), 87 | [data format](data_format.md), 88 | [results format](results_format.md), 89 | [upload](upload.md) and [evaluation](evaluation.md) pages. 90 | For additional questions, please contact vkhalidov@fb.com and nneverova@fb.com. 91 | 92 | -------------------------------------------------------------------------------- /challenge/2019_COCO_DensePose/results_format.md: -------------------------------------------------------------------------------- 1 | # Results Format 2 | 3 | This page describes the results format used by COCO DensePose evaluation 4 | procedure. The results format mimics the annotation format detailed on 5 | the [data format](data_format.md) page. Please review the annotation 6 | format before proceeding. 7 | 8 | Each algorithmically generated result is stored separately in its own 9 | result struct. This singleton result struct must contain the id of the 10 | image from which the result was generated (a single image will typically 11 | have multiple associated results). Results for the whole dataset are 12 | aggregated in a single array. Finally, this entire result struct array 13 | is stored to disk as a single JSON file (saved via 14 | [gason](https://github.com/cocodataset/cocoapi/blob/master/MatlabAPI/gason.m) 15 | in Matlab or [json.dump](https://docs.python.org/2/library/json.html) in Python). 16 | 17 | Example result JSON files are available in 18 | [example results](example_results.json). 19 | 20 | The data struct for each of the result types is described below. The format 21 | of the individual fields below (`category_id`, `bbox`, etc.) is the same as 22 | for the annotation (for details see the [data format](data_format.md) page). 23 | Bounding box coordinates `bbox` are floats measured from the top left image 24 | corner (and are 0-indexed). We recommend rounding coordinates to the nearest 25 | tenth of a pixel to reduce the resulting JSON file size. The dense estimates 26 | of patch indices and coordinates in the UV space for the specified bounding 27 | box are stored in `uv_shape` and `uv_data` fields. 28 | `uv_shape` contains the shape of `uv_data` array, it should be of size 29 | `(3, height, width)`, where `height` and `width` should match the bounding box 30 | size. `uv_data` should contain PNG-compressed patch indices and U and V 31 | coordinates scaled to the range `0-255`. 32 | 33 | An example of code that generates results in the form of a `pkl` file can 34 | be found in 35 | [json_dataset_evaluator.py](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/json_dataset_evaluator.py). 36 | We also provide an [example script](../encode_results_for_competition.py) to convert 37 | dense pose estimation results stored in a `pkl` file into a PNG-compressed 38 | JSON file. 39 | 40 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /challenge/2019_COCO_DensePose/upload.md: -------------------------------------------------------------------------------- 1 | # Upload Results to Evaluation Server 2 | 3 | This page describes the upload instructions for submitting results to the 4 | evaluation servers for the COCO DensePose challenge. Submitting results allows 5 | you to participate in the challenges and compare results to the 6 | state-of-the-art on the public leaderboards. Note that you can obtain results 7 | on val by running the 8 | [evaluation code](https://github.com/facebookresearch/DensePose/blob/master/detectron/datasets/densepose_cocoeval.py) 9 | locally. One can also take advantage of the 10 | [vkhalidov/densepose-codalab](https://hub.docker.com/r/vkhalidov/densepose-codalab/) 11 | docker image which was tailored specifically for evaluation. 12 | Submitting to the evaluation server provides results on the val and 13 | test sets. We now give detailed instructions for submitting to the evaluation 14 | server: 15 | 16 | 1. Create an account on CodaLab. This will allow you to participate in all COCO challenges. 17 | 18 | 2. Carefully review the [guidelines](http://cocodataset.org/#guidelines) for 19 | entering the COCO challenges and using the test sets. 20 | 21 | 3. Prepare a JSON file containing your results in the correct 22 | [results format](results_format.md) for the challenge you wish to enter. 23 | 24 | 4. File naming: the JSON file should be named `densepose_[subset]_[alg]_results.json`. 25 | Replace `[subset]` with the subset you are using (`val` or `test`), 26 | and `[alg]` with your algorithm name. Finally, place the JSON 27 | file into a zip file named `densepose_[subset]_[alg]_results.zip`. 28 | 29 | 5. To submit your zipped result file to the COCO DensePose Challenge, click on 30 | the “Participate” tab on the 31 | [CodaLab evaluation server](https://competitions.codalab.org/competitions/20660) page. 32 | When you select “Submit / View Results” on the left panel, you will be able to choose 33 | the subset. Please fill in the required fields and click “Submit”. A pop-up will 34 | prompt you to select the results zip file for upload. After the file is uploaded 35 | the evaluation server will begin processing. To view the status of your submission 36 | please select “Refresh Status”. Please be patient, the evaluation may take quite 37 | some time to complete (from ~20m to a few hours). If the status of your submission 38 | is “Failed” please check your file is named correctly and has the right format. 39 | 40 | 6. Please enter submission information into Codalab. The most important fields 41 | are "Team name", "Method description", and "Publication URL", which are used 42 | to populate the COCO leaderboard. Additionally, under "user setting" in the 43 | upper right, please add "Team members". There have been issues with the 44 | "Method Description", we may collect these via email if necessary. These 45 | settings are not intuitive, but we have no control of the Codalab website. 46 | For the "Method description", especially for COCO DensePose challenge entries, 47 | we encourage participants to give detailed method information that will help 48 | the award committee invite participants with the most innovative methods. 49 | Listing external data used is mandatory. You may also consider giving some 50 | basic performance breakdowns on test subset (e.g., single model versus 51 | ensemble results), runtime, or any other information you think may be pertinent 52 | to highlight the novelty or efficacy of your method. 53 | 54 | 7. After you submit your results to the test-dev eval server, you can control 55 | whether your results are publicly posted to the CodaLab leaderboard. To toggle 56 | the public visibility of your results please select either “post to leaderboard” 57 | or “remove from leaderboard”. Only one result can be published to the leaderboard 58 | at any time. 59 | 60 | 8. After evaluation is complete and the server shows a status of “Finished”, 61 | you will have the option to download your evaluation results by selecting 62 | “Download evaluation output from scoring step.” The zip file will contain the 63 | score file `scores.txt`. 64 | 65 | -------------------------------------------------------------------------------- /challenge/encode_results_for_competition.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2 2 | 3 | """encode_results.py: script to encode dense human pose estimation results 4 | in DensePose format into a packed representation using PNG compression. 5 | """ 6 | 7 | __author__ = "Vasil Khalidov" 8 | __copyright__ = "Copyright (c) 2018-present, Facebook, Inc." 9 | 10 | import os 11 | import sys 12 | import pickle 13 | import copy 14 | import json 15 | import time 16 | import argparse 17 | import numpy as np 18 | 19 | kPositiveAnswers = ['y', 'Y'] 20 | kNegativeAnswers = ['n', 'N'] 21 | kAnswers = kPositiveAnswers + kNegativeAnswers 22 | 23 | def _parseArguments(): 24 | parser = argparse.ArgumentParser() 25 | parser.add_argument('inPklResultsFile', help='Input pickle file with' 26 | ' dense human pose estimation results') 27 | parser.add_argument('outJsonPackedFile', help='Output JSON file with' 28 | ' packed dense human pose estimation results, which can be' 29 | ' used for submission') 30 | args = parser.parse_args() 31 | return args 32 | 33 | def _encodePngData(arr): 34 | """ 35 | Encode array data as a PNG image using the highest compression rate 36 | @param arr [in] Data stored in an array of size (3, M, N) of type uint8 37 | @return Base64-encoded string containing PNG-compressed data 38 | """ 39 | from PIL import Image 40 | import StringIO 41 | assert len(arr.shape) == 3, "Expected a 3D array as an input," \ 42 | " got a {0}D array".format(len(arr.shape)) 43 | assert arr.shape[0] == 3, "Expected first array dimension of size 3," \ 44 | " got {0}".format(arr.shape[0]) 45 | assert arr.dtype == np.uint8, "Expected an array of type np.uint8, " \ 46 | " got {0}".format(arr.dtype) 47 | data = np.moveaxis(arr, 0, -1) 48 | im = Image.fromarray(data) 49 | fStream = StringIO.StringIO() 50 | im.save(fStream, format='png', optimize=True) 51 | s = fStream.getvalue() 52 | return s.encode('base64') 53 | 54 | def _statusStr(i, dataLen): 55 | kProgressWidth = 20 56 | kProgressTemplate = '[{0}] {1: 4d}%' 57 | progressVisNDone = min(max(0, i * kProgressWidth // dataLen), 58 | kProgressWidth) 59 | progressVisNTodo = kProgressWidth - progressVisNDone 60 | progressVis = '*' * progressVisNDone + ' ' * progressVisNTodo 61 | progressNum = i * 100 // dataLen 62 | progressStr = kProgressTemplate.format(progressVis, progressNum) 63 | return progressStr 64 | 65 | def _savePngJson(hInPklResultsFile, hOutJsonPackedFile): 66 | from PIL import Image 67 | import StringIO 68 | dataFPickle = pickle.load(hInPklResultsFile) 69 | statusStr = '' 70 | dataLen = len(dataFPickle) 71 | for i, x in enumerate(dataFPickle): 72 | x['uv_shape'] = x['uv'].shape 73 | x['uv_data'] = _encodePngData(x['uv']) 74 | del x['uv'] 75 | sys.stdout.write('\b' * len(statusStr)) 76 | statusStr = _statusStr(i, dataLen) 77 | sys.stdout.write(statusStr) 78 | sys.stdout.write('\n') 79 | json.dump(dataFPickle, hOutJsonPackedFile, ensure_ascii=False, 80 | sort_keys=True, indent=4) 81 | 82 | def main(): 83 | args = _parseArguments() 84 | if os.path.exists(args.outJsonPackedFile): 85 | answer = '' 86 | while not answer in kAnswers: 87 | answer = raw_input('File "{0}" already exists, overwrite? [y/n] ' 88 | .format(args.outJsonPackedFile)) 89 | if answer in kNegativeAnswers: 90 | sys.exit(1) 91 | 92 | with open(args.inPklResultsFile, 'rb') as hIn, \ 93 | open(args.outJsonPackedFile, 'w') as hOut: 94 | print('Encoding png: {0}'.format(args.outJsonPackedFile)) 95 | start = time.clock() 96 | _savePngJson(hIn, hOut) 97 | end = time.clock() 98 | print('Finished encoding png, time {0}s'.format(end - start)) 99 | 100 | if __name__ == "__main__": 101 | main() 102 | -------------------------------------------------------------------------------- /cmake/Summary.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Summary.cmake 2 | 3 | # Prints configuration summary. 4 | function (detectron_print_config_summary) 5 | message(STATUS "Summary:") 6 | message(STATUS " CMake version : ${CMAKE_VERSION}") 7 | message(STATUS " CMake command : ${CMAKE_COMMAND}") 8 | message(STATUS " System name : ${CMAKE_SYSTEM_NAME}") 9 | message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}") 10 | message(STATUS " C++ compiler version : ${CMAKE_CXX_COMPILER_VERSION}") 11 | message(STATUS " CXX flags : ${CMAKE_CXX_FLAGS}") 12 | message(STATUS " Caffe2 version : ${CAFFE2_VERSION}") 13 | message(STATUS " Caffe2 include path : ${CAFFE2_INCLUDE_DIRS}") 14 | if (CAFFE2_USE_CUDA OR CAFFE2_FOUND_CUDA) 15 | message(STATUS " Caffe2 found CUDA : True") 16 | message(STATUS " CUDA version : ${CUDA_VERSION}") 17 | message(STATUS " CuDNN version : ${CUDNN_VERSION}") 18 | else() 19 | message(STATUS " Caffe2 found CUDA : False") 20 | endif() 21 | endfunction() 22 | -------------------------------------------------------------------------------- /cmake/legacy/Dependencies.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Dependencies.cmake 2 | 3 | # Find CUDA. 4 | include(cmake/legacy/Cuda.cmake) 5 | if (HAVE_CUDA) 6 | # CUDA 9.x requires GCC version <= 6 7 | if ((CUDA_VERSION VERSION_EQUAL 9.0) OR 8 | (CUDA_VERSION VERSION_GREATER 9.0 AND CUDA_VERSION VERSION_LESS 10.0)) 9 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND 10 | NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 7.0 AND 11 | CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER) 12 | message(FATAL_ERROR 13 | "CUDA ${CUDA_VERSION} is not compatible with GCC version >= 7. " 14 | "Use the following option to use another version (for example): \n" 15 | " -DCUDA_HOST_COMPILER=/usr/bin/gcc-6\n") 16 | endif() 17 | # CUDA 8.0 requires GCC version <= 5 18 | elseif (CUDA_VERSION VERSION_EQUAL 8.0) 19 | if (CMAKE_C_COMPILER_ID STREQUAL "GNU" AND 20 | NOT CMAKE_C_COMPILER_VERSION VERSION_LESS 6.0 AND 21 | CUDA_HOST_COMPILER STREQUAL CMAKE_C_COMPILER) 22 | message(FATAL_ERROR 23 | "CUDA 8.0 is not compatible with GCC version >= 6. " 24 | "Use the following option to use another version (for example): \n" 25 | " -DCUDA_HOST_COMPILER=/usr/bin/gcc-5\n") 26 | endif() 27 | endif() 28 | endif() 29 | 30 | # Find CUDNN. 31 | if (HAVE_CUDA) 32 | find_package(CuDNN REQUIRED) 33 | if (CUDNN_FOUND) 34 | caffe2_include_directories(${CUDNN_INCLUDE_DIRS}) 35 | endif() 36 | endif() 37 | -------------------------------------------------------------------------------- /cmake/legacy/Modules/FindCuDNN.cmake: -------------------------------------------------------------------------------- 1 | # Copied from https://github.com/caffe2/caffe2/blob/master/cmake/Modules/FindCuDNN.cmake 2 | 3 | # - Try to find cuDNN 4 | # 5 | # The following variables are optionally searched for defaults 6 | # CUDNN_ROOT_DIR: Base directory where all cuDNN components are found 7 | # 8 | # The following are set after configuration is done: 9 | # CUDNN_FOUND 10 | # CUDNN_INCLUDE_DIRS 11 | # CUDNN_LIBRARIES 12 | # CUDNN_LIBRARY_DIRS 13 | 14 | include(FindPackageHandleStandardArgs) 15 | 16 | set(CUDNN_ROOT_DIR "" CACHE PATH "Folder contains NVIDIA cuDNN") 17 | 18 | find_path(CUDNN_INCLUDE_DIR cudnn.h 19 | HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR} 20 | PATH_SUFFIXES cuda/include include) 21 | 22 | find_library(CUDNN_LIBRARY cudnn 23 | HINTS ${CUDNN_ROOT_DIR} ${CUDA_TOOLKIT_ROOT_DIR} 24 | PATH_SUFFIXES lib lib64 cuda/lib cuda/lib64 lib/x64) 25 | 26 | find_package_handle_standard_args( 27 | CUDNN DEFAULT_MSG CUDNN_INCLUDE_DIR CUDNN_LIBRARY) 28 | 29 | if(CUDNN_FOUND) 30 | # get cuDNN version 31 | file(READ ${CUDNN_INCLUDE_DIR}/cudnn.h CUDNN_HEADER_CONTENTS) 32 | string(REGEX MATCH "define CUDNN_MAJOR * +([0-9]+)" 33 | CUDNN_VERSION_MAJOR "${CUDNN_HEADER_CONTENTS}") 34 | string(REGEX REPLACE "define CUDNN_MAJOR * +([0-9]+)" "\\1" 35 | CUDNN_VERSION_MAJOR "${CUDNN_VERSION_MAJOR}") 36 | string(REGEX MATCH "define CUDNN_MINOR * +([0-9]+)" 37 | CUDNN_VERSION_MINOR "${CUDNN_HEADER_CONTENTS}") 38 | string(REGEX REPLACE "define CUDNN_MINOR * +([0-9]+)" "\\1" 39 | CUDNN_VERSION_MINOR "${CUDNN_VERSION_MINOR}") 40 | string(REGEX MATCH "define CUDNN_PATCHLEVEL * +([0-9]+)" 41 | CUDNN_VERSION_PATCH "${CUDNN_HEADER_CONTENTS}") 42 | string(REGEX REPLACE "define CUDNN_PATCHLEVEL * +([0-9]+)" "\\1" 43 | CUDNN_VERSION_PATCH "${CUDNN_VERSION_PATCH}") 44 | # Assemble cuDNN version 45 | if(NOT CUDNN_VERSION_MAJOR) 46 | set(CUDNN_VERSION "?") 47 | else() 48 | set(CUDNN_VERSION "${CUDNN_VERSION_MAJOR}.${CUDNN_VERSION_MINOR}.${CUDNN_VERSION_PATCH}") 49 | endif() 50 | 51 | set(CUDNN_INCLUDE_DIRS ${CUDNN_INCLUDE_DIR}) 52 | set(CUDNN_LIBRARIES ${CUDNN_LIBRARY}) 53 | message(STATUS "Found cuDNN: v${CUDNN_VERSION} (include: ${CUDNN_INCLUDE_DIR}, library: ${CUDNN_LIBRARY})") 54 | mark_as_advanced(CUDNN_ROOT_DIR CUDNN_LIBRARY CUDNN_INCLUDE_DIR) 55 | endif() 56 | -------------------------------------------------------------------------------- /cmake/legacy/Summary.cmake: -------------------------------------------------------------------------------- 1 | # Adapted from https://github.com/caffe2/caffe2/blob/master/cmake/Summary.cmake 2 | 3 | # Prints configuration summary. 4 | function (detectron_print_config_summary) 5 | message(STATUS "Summary:") 6 | message(STATUS " CMake version : ${CMAKE_VERSION}") 7 | message(STATUS " CMake command : ${CMAKE_COMMAND}") 8 | message(STATUS " System name : ${CMAKE_SYSTEM_NAME}") 9 | message(STATUS " C++ compiler : ${CMAKE_CXX_COMPILER}") 10 | message(STATUS " C++ compiler version : ${CMAKE_CXX_COMPILER_VERSION}") 11 | message(STATUS " CXX flags : ${CMAKE_CXX_FLAGS}") 12 | message(STATUS " Caffe2 version : ${CAFFE2_VERSION}") 13 | message(STATUS " Caffe2 include path : ${CAFFE2_INCLUDE_DIRS}") 14 | message(STATUS " Have CUDA : ${HAVE_CUDA}") 15 | if (${HAVE_CUDA}) 16 | message(STATUS " CUDA version : ${CUDA_VERSION}") 17 | message(STATUS " CuDNN version : ${CUDNN_VERSION}") 18 | endif() 19 | endfunction() 20 | -------------------------------------------------------------------------------- /cmake/legacy/legacymake.cmake: -------------------------------------------------------------------------------- 1 | # This file contains legacy cmake scripts that is going to be removed 2 | # in a future release. 3 | 4 | # Add CMake modules. 5 | list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/legacy/Modules) 6 | 7 | # Add compiler flags. 8 | set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -std=c11") 9 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -O2 -fPIC -Wno-narrowing") 10 | 11 | # Include Caffe2 CMake utils. 12 | include(cmake/legacy/Utils.cmake) 13 | 14 | # Find dependencies. 15 | include(cmake/legacy/Dependencies.cmake) 16 | 17 | # Print configuration summary. 18 | include(cmake/legacy/Summary.cmake) 19 | detectron_print_config_summary() 20 | 21 | # Collect custom ops sources. 22 | file(GLOB CUSTOM_OPS_CPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cc) 23 | file(GLOB CUSTOM_OPS_GPU_SRCS ${CMAKE_CURRENT_SOURCE_DIR}/detectron/ops/*.cu) 24 | 25 | # Install custom CPU ops lib. 26 | add_library( 27 | caffe2_detectron_custom_ops SHARED 28 | ${CUSTOM_OPS_CPU_SRCS}) 29 | 30 | target_include_directories( 31 | caffe2_detectron_custom_ops PRIVATE 32 | ${CAFFE2_INCLUDE_DIRS}) 33 | target_link_libraries(caffe2_detectron_custom_ops caffe2) 34 | install(TARGETS caffe2_detectron_custom_ops DESTINATION lib) 35 | 36 | # Install custom GPU ops lib. 37 | if (${HAVE_CUDA}) 38 | # Additional -I prefix is required for CMake versions before commit (< 3.7): 39 | # https://github.com/Kitware/CMake/commit/7ded655f7ba82ea72a82d0555449f2df5ef38594 40 | list(APPEND CUDA_INCLUDE_DIRS -I${CAFFE2_INCLUDE_DIRS}) 41 | CUDA_ADD_LIBRARY( 42 | caffe2_detectron_custom_ops_gpu SHARED 43 | ${CUSTOM_OPS_CPU_SRCS} 44 | ${CUSTOM_OPS_GPU_SRCS}) 45 | 46 | target_link_libraries(caffe2_detectron_custom_ops_gpu caffe2_gpu) 47 | install(TARGETS caffe2_detectron_custom_ops_gpu DESTINATION lib) 48 | endif() 49 | -------------------------------------------------------------------------------- /configs/DensePoseKeyPointsMask_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | MASK_ON: True 8 | KEYPOINTS_ON: True 9 | NUM_GPUS: 8 10 | SOLVER: 11 | WEIGHT_DECAY: 0.0001 12 | LR_POLICY: steps_with_decay 13 | GAMMA: 0.1 14 | WARM_UP_ITERS: 3000 15 | WARM_UP_FACTOR: 0.0000001 16 | # Linear scaling rule: 17 | # 1 GPU: 18 | # BASE_LR: 0.00025 19 | # MAX_ITER: 720000 20 | # STEPS: [0, 480000, 640000] 21 | # 2 GPUs: 22 | # BASE_LR: 0.0005 23 | # MAX_ITER: 360000 24 | # STEPS: [0, 240000, 320000] 25 | # 4 GPUs: 26 | # BASE_LR: 0.001 27 | # MAX_ITER: 180000 28 | # STEPS: [0, 120000, 160000] 29 | #8 GPUs: 30 | BASE_LR: 0.002 31 | MAX_ITER: 230000 32 | STEPS: [0, 150000, 200000] 33 | FPN: 34 | FPN_ON: True 35 | MULTILEVEL_ROIS: True 36 | MULTILEVEL_RPN: True 37 | FAST_RCNN: 38 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 39 | ROI_XFORM_METHOD: RoIAlign 40 | ROI_XFORM_RESOLUTION: 14 41 | ROI_XFORM_SAMPLING_RATIO: 2 42 | BODY_UV_RCNN: 43 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 44 | NUM_STACKED_CONVS: 8 45 | NUM_PATCHES: 24 46 | USE_DECONV_OUTPUT: True 47 | CONV_INIT: MSRAFill 48 | CONV_HEAD_DIM: 512 49 | UP_SCALE: 2 50 | HEATMAP_SIZE: 56 51 | ROI_XFORM_METHOD: RoIAlign 52 | ROI_XFORM_RESOLUTION: 14 53 | ROI_XFORM_SAMPLING_RATIO: 2 54 | ## 55 | # Loss weights for annotation masks.(14 Parts) 56 | INDEX_WEIGHTS : 2.0 57 | # Loss weights for surface parts. (24 Parts) 58 | PART_WEIGHTS : 0.3 59 | # Loss weights for UV regression. 60 | POINT_REGRESSION_WEIGHTS : 0.1 61 | ## 62 | BODY_UV_IMS: True 63 | MRCNN: 64 | ROI_MASK_HEAD: mask_rcnn_heads.mask_rcnn_fcn_head_v1up4convs 65 | RESOLUTION: 28 66 | ROI_XFORM_METHOD: RoIAlign 67 | ROI_XFORM_RESOLUTION: 14 68 | ROI_XFORM_SAMPLING_RATIO: 2 # default 0 69 | DILATION: 1 # default 2 70 | CONV_INIT: MSRAFill # default: GaussianFill 71 | KRCNN: 72 | ROI_KEYPOINTS_HEAD: keypoint_rcnn_heads.add_roi_pose_head_v1convX 73 | NUM_STACKED_CONVS: 8 74 | NUM_KEYPOINTS: 17 75 | USE_DECONV_OUTPUT: True 76 | CONV_INIT: MSRAFill 77 | CONV_HEAD_DIM: 512 78 | UP_SCALE: 2 79 | HEATMAP_SIZE: 56 # ROI_XFORM_RESOLUTION (14) * UP_SCALE (2) * USE_DECONV_OUTPUT (2) 80 | ROI_XFORM_METHOD: RoIAlign 81 | ROI_XFORM_RESOLUTION: 14 82 | ROI_XFORM_SAMPLING_RATIO: 2 83 | KEYPOINT_CONFIDENCE: bbox 84 | TRAIN: 85 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 86 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 87 | SCALES: (640, 672, 704, 736, 768, 800) 88 | MAX_SIZE: 1333 89 | IMS_PER_BATCH: 1 90 | BATCH_SIZE_PER_IM: 512 91 | USE_FLIPPED: True 92 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 93 | TEST: 94 | DATASETS: ('dense_coco_2014_minival',) 95 | PROPOSAL_LIMIT: 1000 96 | SCALE: 800 97 | MAX_SIZE: 1333 98 | NMS: 0.5 99 | FORCE_JSON_DATASET_EVAL: True 100 | DETECTIONS_PER_IM: 20 101 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 102 | RPN_POST_NMS_TOP_N: 1000 103 | OUTPUT_DIR: '' 104 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet101_FPN.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 90000 29 | STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet101_FPN_32x8d_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | 36 | RESNETS: 37 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 38 | TRANS_FUNC: bottleneck_transformation 39 | NUM_GROUPS: 32 40 | WIDTH_PER_GROUP: 8 41 | 42 | FAST_RCNN: 43 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 44 | ROI_XFORM_METHOD: RoIAlign 45 | ROI_XFORM_RESOLUTION: 7 46 | ROI_XFORM_SAMPLING_RATIO: 2 47 | BODY_UV_RCNN: 48 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 49 | NUM_STACKED_CONVS: 8 50 | NUM_PATCHES: 24 51 | USE_DECONV_OUTPUT: True 52 | CONV_INIT: MSRAFill 53 | CONV_HEAD_DIM: 512 54 | UP_SCALE: 2 55 | HEATMAP_SIZE: 56 56 | ROI_XFORM_METHOD: RoIAlign 57 | ROI_XFORM_RESOLUTION: 14 58 | ROI_XFORM_SAMPLING_RATIO: 2 59 | ## 60 | # Loss weights for annotation masks.(14 Parts) 61 | INDEX_WEIGHTS : 2.0 62 | # Loss weights for surface parts. (24 Parts) 63 | PART_WEIGHTS : 0.3 64 | # Loss weights for UV regression. 65 | POINT_REGRESSION_WEIGHTS : 0.1 66 | ## 67 | BODY_UV_IMS: True 68 | TRAIN: 69 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 70 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 71 | SCALES: (640, 672, 704, 736, 768, 800) 72 | MAX_SIZE: 1333 73 | IMS_PER_BATCH: 3 74 | BATCH_SIZE_PER_IM: 512 75 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 76 | USE_FLIPPED: True 77 | TEST: 78 | DATASETS: ('dense_coco_2014_minival',) 79 | PROPOSAL_LIMIT: 1000 80 | SCALE: 800 81 | MAX_SIZE: 1333 82 | NMS: 0.5 83 | FORCE_JSON_DATASET_EVAL: True 84 | DETECTIONS_PER_IM: 20 85 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 86 | RPN_POST_NMS_TOP_N: 1000 87 | OUTPUT_DIR: '' 88 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet101_FPN_32x8d_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | 35 | RESNETS: 36 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 37 | TRANS_FUNC: bottleneck_transformation 38 | NUM_GROUPS: 32 39 | WIDTH_PER_GROUP: 8 40 | 41 | FAST_RCNN: 42 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 43 | ROI_XFORM_METHOD: RoIAlign 44 | ROI_XFORM_RESOLUTION: 7 45 | ROI_XFORM_SAMPLING_RATIO: 2 46 | BODY_UV_RCNN: 47 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 48 | NUM_STACKED_CONVS: 8 49 | NUM_PATCHES: 24 50 | USE_DECONV_OUTPUT: True 51 | CONV_INIT: MSRAFill 52 | CONV_HEAD_DIM: 512 53 | UP_SCALE: 2 54 | HEATMAP_SIZE: 56 55 | ROI_XFORM_METHOD: RoIAlign 56 | ROI_XFORM_RESOLUTION: 14 57 | ROI_XFORM_SAMPLING_RATIO: 2 58 | ## 59 | # Loss weights for annotation masks.(14 Parts) 60 | INDEX_WEIGHTS : 2.0 61 | # Loss weights for surface parts. (24 Parts) 62 | PART_WEIGHTS : 0.3 63 | # Loss weights for UV regression. 64 | POINT_REGRESSION_WEIGHTS : 0.1 65 | ## 66 | BODY_UV_IMS: True 67 | TRAIN: 68 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 69 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 70 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 71 | SCALES: (640, 672, 704, 736, 768, 800) 72 | MAX_SIZE: 1333 73 | IMS_PER_BATCH: 3 74 | BATCH_SIZE_PER_IM: 512 75 | USE_FLIPPED: True 76 | TEST: 77 | DATASETS: ('dense_coco_2014_minival',) 78 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 79 | PROPOSAL_LIMIT: 1000 80 | SCALE: 800 81 | MAX_SIZE: 1333 82 | NMS: 0.5 83 | FORCE_JSON_DATASET_EVAL: True 84 | DETECTIONS_PER_IM: 20 85 | OUTPUT_DIR: '' 86 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet101_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-101.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 69 | USE_FLIPPED: True 70 | TEST: 71 | DATASETS: ('dense_coco_2014_minival',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet101_FPN_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-101.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet50_FPN.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 90000 29 | STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('dense_coco_2014_train.pkl','dense_coco_2014_valminusminival.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('dense_coco_2014_minival.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet50_FPN_s1x-e2e.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | FASTER_RCNN: True 6 | BODY_UV_ON: True 7 | NUM_GPUS: 8 8 | SOLVER: 9 | WEIGHT_DECAY: 0.0001 10 | LR_POLICY: steps_with_decay 11 | GAMMA: 0.1 12 | WARM_UP_ITERS: 1000 13 | WARM_UP_FACTOR: 0.1 14 | # Linear scaling rule: 15 | # 1 GPU: 16 | # BASE_LR: 0.00025 17 | # MAX_ITER: 720000 18 | # STEPS: [0, 480000, 640000] 19 | # 2 GPUs: 20 | # BASE_LR: 0.0005 21 | # MAX_ITER: 360000 22 | # STEPS: [0, 240000, 320000] 23 | # 4 GPUs: 24 | # BASE_LR: 0.001 25 | # MAX_ITER: 180000 26 | # STEPS: [0, 120000, 160000] 27 | #8 GPUs: 28 | BASE_LR: 0.002 29 | MAX_ITER: 130000 30 | STEPS: [0, 100000, 120000] 31 | FPN: 32 | FPN_ON: True 33 | MULTILEVEL_ROIS: True 34 | MULTILEVEL_RPN: True 35 | FAST_RCNN: 36 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 37 | ROI_XFORM_METHOD: RoIAlign 38 | ROI_XFORM_RESOLUTION: 7 39 | ROI_XFORM_SAMPLING_RATIO: 2 40 | BODY_UV_RCNN: 41 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 42 | NUM_STACKED_CONVS: 8 43 | NUM_PATCHES: 24 44 | USE_DECONV_OUTPUT: True 45 | CONV_INIT: MSRAFill 46 | CONV_HEAD_DIM: 512 47 | UP_SCALE: 2 48 | HEATMAP_SIZE: 56 49 | ROI_XFORM_METHOD: RoIAlign 50 | ROI_XFORM_RESOLUTION: 14 51 | ROI_XFORM_SAMPLING_RATIO: 2 52 | ## 53 | # Loss weights for annotation masks.(14 Parts) 54 | INDEX_WEIGHTS : 2.0 55 | # Loss weights for surface parts. (24 Parts) 56 | PART_WEIGHTS : 0.3 57 | # Loss weights for UV regression. 58 | POINT_REGRESSION_WEIGHTS : 0.1 59 | ## 60 | BODY_UV_IMS: True 61 | TRAIN: 62 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 63 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | RPN_PRE_NMS_TOP_N: 2000 # Per FPN level 70 | TEST: 71 | DATASETS: ('dense_coco_2014_minival',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 79 | RPN_POST_NMS_TOP_N: 1000 80 | OUTPUT_DIR: '' 81 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet50_FPN_s1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | # BASE_LR: 0.00025 16 | # MAX_ITER: 720000 17 | # STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | BASE_LR: 0.002 28 | MAX_ITER: 130000 29 | STEPS: [0, 100000, 120000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /configs/DensePose_ResNet50_FPN_single_GPU.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | BODY_UV_ON: True 6 | NUM_GPUS: 1 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | GAMMA: 0.1 11 | WARM_UP_ITERS: 1000 12 | WARM_UP_FACTOR: 0.1 13 | # Linear scaling rule: 14 | # 1 GPU: 15 | BASE_LR: 0.00025 16 | MAX_ITER: 720000 17 | STEPS: [0, 480000, 640000] 18 | # 2 GPUs: 19 | # BASE_LR: 0.0005 20 | # MAX_ITER: 360000 21 | # STEPS: [0, 240000, 320000] 22 | # 4 GPUs: 23 | # BASE_LR: 0.001 24 | # MAX_ITER: 180000 25 | # STEPS: [0, 120000, 160000] 26 | #8 GPUs: 27 | # BASE_LR: 0.002 28 | # MAX_ITER: 90000 29 | # STEPS: [0, 60000, 80000] 30 | FPN: 31 | FPN_ON: True 32 | MULTILEVEL_ROIS: True 33 | MULTILEVEL_RPN: True 34 | FAST_RCNN: 35 | ROI_BOX_HEAD: fast_rcnn_heads.add_roi_2mlp_head 36 | ROI_XFORM_METHOD: RoIAlign 37 | ROI_XFORM_RESOLUTION: 7 38 | ROI_XFORM_SAMPLING_RATIO: 2 39 | BODY_UV_RCNN: 40 | ROI_HEAD: body_uv_rcnn_heads.add_roi_body_uv_head_v1convX 41 | NUM_STACKED_CONVS: 8 42 | NUM_PATCHES: 24 43 | USE_DECONV_OUTPUT: True 44 | CONV_INIT: MSRAFill 45 | CONV_HEAD_DIM: 512 46 | UP_SCALE: 2 47 | HEATMAP_SIZE: 56 48 | ROI_XFORM_METHOD: RoIAlign 49 | ROI_XFORM_RESOLUTION: 14 50 | ROI_XFORM_SAMPLING_RATIO: 2 51 | ## 52 | # Loss weights for annotation masks.(14 Parts) 53 | INDEX_WEIGHTS : 2.0 54 | # Loss weights for surface parts. (24 Parts) 55 | PART_WEIGHTS : 0.3 56 | # Loss weights for UV regression. 57 | POINT_REGRESSION_WEIGHTS : 0.1 58 | ## 59 | BODY_UV_IMS: True 60 | TRAIN: 61 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 62 | DATASETS: ('dense_coco_2014_train', 'dense_coco_2014_valminusminival') 63 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-train_fpn_resnet50.pkl','https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-valminusminival_fpn_resnet50.pkl') 64 | SCALES: (640, 672, 704, 736, 768, 800) 65 | MAX_SIZE: 1333 66 | IMS_PER_BATCH: 3 67 | BATCH_SIZE_PER_IM: 512 68 | USE_FLIPPED: True 69 | TEST: 70 | DATASETS: ('dense_coco_2014_minival',) 71 | PROPOSAL_FILES: ('https://dl.fbaipublicfiles.com/densepose/DensePose-RPN-minival_fpn_resnet50.pkl',) 72 | PROPOSAL_LIMIT: 1000 73 | SCALE: 800 74 | MAX_SIZE: 1333 75 | NMS: 0.5 76 | FORCE_JSON_DATASET_EVAL: True 77 | DETECTIONS_PER_IM: 20 78 | OUTPUT_DIR: '' 79 | -------------------------------------------------------------------------------- /configs/rpn_densepose_only_R-50-FPN_1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet50_conv5_body 4 | NUM_CLASSES: 2 5 | RPN_ONLY: True 6 | NUM_GPUS: 8 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | BASE_LR: 0.02 11 | GAMMA: 0.1 12 | MAX_ITER: 90000 13 | STEPS: [0, 60000, 80000] 14 | FPN: 15 | FPN_ON: True 16 | MULTILEVEL_RPN: True 17 | RPN_MAX_LEVEL: 6 18 | RPN_MIN_LEVEL: 2 19 | RPN_ANCHOR_START_SIZE: 32 20 | RPN_ASPECT_RATIOS: (0.5, 1, 2) 21 | TRAIN: 22 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/MSRA/R-50.pkl 23 | DATASETS: ('keypoints_coco_2014_train', 'keypoints_coco_2014_valminusminival') 24 | SCALES: (800,) 25 | MAX_SIZE: 1333 26 | TEST: 27 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/35998996/12_2017_baselines/rpn_person_only_R-50-FPN_1x.yaml.08_10_08.0ZWmJm6F/output/train/keypoints_coco_2014_train%3Akeypoints_coco_2014_valminusminival/generalized_rcnn/model_final.pkl 28 | DATASETS: ('dense_coco_2014_minival', 'dense_coco_2014_train', 'dense_coco_2014_valminusminival') 29 | SCALE: 800 30 | MAX_SIZE: 1333 31 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 32 | RPN_POST_NMS_TOP_N: 2000 33 | OUTPUT_DIR: . 34 | -------------------------------------------------------------------------------- /configs/rpn_densepose_only_X-101-32x8d-FPN_1x.yaml: -------------------------------------------------------------------------------- 1 | MODEL: 2 | TYPE: generalized_rcnn 3 | CONV_BODY: FPN.add_fpn_ResNet101_conv5_body 4 | NUM_CLASSES: 2 5 | RPN_ONLY: True 6 | NUM_GPUS: 1 7 | SOLVER: 8 | WEIGHT_DECAY: 0.0001 9 | LR_POLICY: steps_with_decay 10 | BASE_LR: 0.02 11 | GAMMA: 0.1 12 | MAX_ITER: 90000 13 | STEPS: [0, 60000, 80000] 14 | FPN: 15 | FPN_ON: True 16 | MULTILEVEL_RPN: True 17 | RPN_MAX_LEVEL: 6 18 | RPN_MIN_LEVEL: 2 19 | RPN_ANCHOR_START_SIZE: 32 20 | RPN_ASPECT_RATIOS: (0.5, 1, 2) 21 | RESNETS: 22 | STRIDE_1X1: False # default True for MSRA; False for C2 or Torch models 23 | TRANS_FUNC: bottleneck_transformation 24 | NUM_GROUPS: 32 25 | WIDTH_PER_GROUP: 8 26 | TRAIN: 27 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/ImageNetPretrained/20171220/X-101-32x8d.pkl 28 | DATASETS: ('keypoints_coco_2014_train', 'keypoints_coco_2014_valminusminival') 29 | SCALES: (800,) 30 | MAX_SIZE: 1333 31 | TEST: 32 | WEIGHTS: https://dl.fbaipublicfiles.com/detectron/36760438/12_2017_baselines/rpn_person_only_X-101-32x8d-FPN_1x.yaml.06_04_23.M2oJlDPW/output/train/keypoints_coco_2014_train%3Akeypoints_coco_2014_valminusminival/generalized_rcnn/model_final.pkl 33 | DATASETS: ( 'dense_coco_2014_minival', 'dense_coco_2014_valminusminival') 34 | SCALE: 800 35 | MAX_SIZE: 1333 36 | RPN_PRE_NMS_TOP_N: 1000 # Per FPN level 37 | RPN_POST_NMS_TOP_N: 2000 38 | OUTPUT_DIR: /home/goku/DensePose/CleanJSONs/ 39 | -------------------------------------------------------------------------------- /detectron/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/__init__.py -------------------------------------------------------------------------------- /detectron/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/core/__init__.py -------------------------------------------------------------------------------- /detectron/datasets/VOCdevkit-matlab-wrapper/get_voc_opts.m: -------------------------------------------------------------------------------- 1 | function VOCopts = get_voc_opts(path) 2 | 3 | tmp = pwd; 4 | cd(path); 5 | try 6 | addpath('VOCcode'); 7 | VOCinit; 8 | catch 9 | rmpath('VOCcode'); 10 | cd(tmp); 11 | error(sprintf('VOCcode directory not found under %s', path)); 12 | end 13 | rmpath('VOCcode'); 14 | cd(tmp); 15 | -------------------------------------------------------------------------------- /detectron/datasets/VOCdevkit-matlab-wrapper/voc_eval.m: -------------------------------------------------------------------------------- 1 | function res = voc_eval(path, comp_id, test_set, output_dir) 2 | 3 | VOCopts = get_voc_opts(path); 4 | VOCopts.testset = test_set; 5 | 6 | for i = 1:length(VOCopts.classes) 7 | cls = VOCopts.classes{i}; 8 | res(i) = voc_eval_cls(cls, VOCopts, comp_id, output_dir); 9 | end 10 | 11 | fprintf('\n~~~~~~~~~~~~~~~~~~~~\n'); 12 | fprintf('Results:\n'); 13 | aps = [res(:).ap]'; 14 | fprintf('%.1f\n', aps * 100); 15 | fprintf('%.1f\n', mean(aps) * 100); 16 | fprintf('~~~~~~~~~~~~~~~~~~~~\n'); 17 | 18 | function res = voc_eval_cls(cls, VOCopts, comp_id, output_dir) 19 | 20 | test_set = VOCopts.testset; 21 | year = VOCopts.dataset(4:end); 22 | 23 | addpath(fullfile(VOCopts.datadir, 'VOCcode')); 24 | 25 | res_fn = sprintf(VOCopts.detrespath, comp_id, cls); 26 | 27 | recall = []; 28 | prec = []; 29 | ap = 0; 30 | ap_auc = 0; 31 | 32 | do_eval = (str2num(year) <= 2007) | ~strcmp(test_set, 'test'); 33 | if do_eval 34 | % Bug in VOCevaldet requires that tic has been called first 35 | tic; 36 | [recall, prec, ap] = VOCevaldet(VOCopts, comp_id, cls, true); 37 | ap_auc = xVOCap(recall, prec); 38 | 39 | % force plot limits 40 | ylim([0 1]); 41 | xlim([0 1]); 42 | 43 | print(gcf, '-djpeg', '-r0', ... 44 | [output_dir '/' cls '_pr.jpg']); 45 | end 46 | fprintf('!!! %s : %.4f %.4f\n', cls, ap, ap_auc); 47 | 48 | res.recall = recall; 49 | res.prec = prec; 50 | res.ap = ap; 51 | res.ap_auc = ap_auc; 52 | 53 | save([output_dir '/' cls '_pr.mat'], ... 54 | 'res', 'recall', 'prec', 'ap', 'ap_auc'); 55 | 56 | rmpath(fullfile(VOCopts.datadir, 'VOCcode')); 57 | -------------------------------------------------------------------------------- /detectron/datasets/VOCdevkit-matlab-wrapper/xVOCap.m: -------------------------------------------------------------------------------- 1 | function ap = xVOCap(rec,prec) 2 | % From the PASCAL VOC 2011 devkit 3 | 4 | mrec=[0 ; rec ; 1]; 5 | mpre=[0 ; prec ; 0]; 6 | for i=numel(mpre)-1:-1:1 7 | mpre(i)=max(mpre(i),mpre(i+1)); 8 | end 9 | i=find(mrec(2:end)~=mrec(1:end-1))+1; 10 | ap=sum((mrec(i)-mrec(i-1)).*mpre(i)); 11 | -------------------------------------------------------------------------------- /detectron/datasets/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/datasets/__init__.py -------------------------------------------------------------------------------- /detectron/datasets/cityscapes_json_dataset_evaluator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Functions for evaluating results on Cityscapes.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import cv2 16 | import logging 17 | import os 18 | import uuid 19 | 20 | import pycocotools.mask as mask_util 21 | 22 | from detectron.core.config import cfg 23 | from detectron.datasets.dataset_catalog import get_raw_dir 24 | 25 | logger = logging.getLogger(__name__) 26 | 27 | 28 | def evaluate_masks( 29 | json_dataset, 30 | all_boxes, 31 | all_segms, 32 | output_dir, 33 | use_salt=True, 34 | cleanup=False 35 | ): 36 | if cfg.CLUSTER.ON_CLUSTER: 37 | # On the cluster avoid saving these files in the job directory 38 | output_dir = '/tmp' 39 | res_file = os.path.join( 40 | output_dir, 'segmentations_' + json_dataset.name + '_results') 41 | if use_salt: 42 | res_file += '_{}'.format(str(uuid.uuid4())) 43 | res_file += '.json' 44 | 45 | results_dir = os.path.join(output_dir, 'results') 46 | if not os.path.exists(results_dir): 47 | os.mkdir(results_dir) 48 | 49 | os.environ['CITYSCAPES_DATASET'] = get_raw_dir(json_dataset.name) 50 | os.environ['CITYSCAPES_RESULTS'] = output_dir 51 | 52 | # Load the Cityscapes eval script *after* setting the required env vars, 53 | # since the script reads their values into global variables (at load time). 54 | import cityscapesscripts.evaluation.evalInstanceLevelSemanticLabeling \ 55 | as cityscapes_eval 56 | 57 | roidb = json_dataset.get_roidb() 58 | for i, entry in enumerate(roidb): 59 | im_name = entry['image'] 60 | 61 | basename = os.path.splitext(os.path.basename(im_name))[0] 62 | txtname = os.path.join(output_dir, basename + 'pred.txt') 63 | with open(txtname, 'w') as fid_txt: 64 | if i % 10 == 0: 65 | logger.info('i: {}: {}'.format(i, basename)) 66 | for j in range(1, len(all_segms)): 67 | clss = json_dataset.classes[j] 68 | clss_id = cityscapes_eval.name2label[clss].id 69 | segms = all_segms[j][i] 70 | boxes = all_boxes[j][i] 71 | if segms == []: 72 | continue 73 | masks = mask_util.decode(segms) 74 | 75 | for k in range(boxes.shape[0]): 76 | score = boxes[k, -1] 77 | mask = masks[:, :, k] 78 | pngname = os.path.join( 79 | 'results', 80 | basename + '_' + clss + '_{}.png'.format(k)) 81 | # write txt 82 | fid_txt.write('{} {} {}\n'.format(pngname, clss_id, score)) 83 | # save mask 84 | cv2.imwrite(os.path.join(output_dir, pngname), mask * 255) 85 | logger.info('Evaluating...') 86 | cityscapes_eval.main([]) 87 | return None 88 | -------------------------------------------------------------------------------- /detectron/datasets/coco_to_cityscapes_id.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | # mapping coco categories to cityscapes (our converted json) id 9 | # cityscapes 10 | # INFO roidb.py: 220: 1 bicycle: 7286 11 | # INFO roidb.py: 220: 2 car: 53684 12 | # INFO roidb.py: 220: 3 person: 35704 13 | # INFO roidb.py: 220: 4 train: 336 14 | # INFO roidb.py: 220: 5 truck: 964 15 | # INFO roidb.py: 220: 6 motorcycle: 1468 16 | # INFO roidb.py: 220: 7 bus: 758 17 | # INFO roidb.py: 220: 8 rider: 3504 18 | 19 | # coco (val5k) 20 | # INFO roidb.py: 220: 1 person: 21296 21 | # INFO roidb.py: 220: 2 bicycle: 628 22 | # INFO roidb.py: 220: 3 car: 3818 23 | # INFO roidb.py: 220: 4 motorcycle: 732 24 | # INFO roidb.py: 220: 5 airplane: 286 <------ irrelevant 25 | # INFO roidb.py: 220: 6 bus: 564 26 | # INFO roidb.py: 220: 7 train: 380 27 | # INFO roidb.py: 220: 8 truck: 828 28 | 29 | 30 | def cityscapes_to_coco(cityscapes_id): 31 | lookup = { 32 | 0: 0, # ... background 33 | 1: 2, # bicycle 34 | 2: 3, # car 35 | 3: 1, # person 36 | 4: 7, # train 37 | 5: 8, # truck 38 | 6: 4, # motorcycle 39 | 7: 6, # bus 40 | 8: -1, # rider (-1 means rand init) 41 | } 42 | return lookup[cityscapes_id] 43 | 44 | 45 | def cityscapes_to_coco_with_rider(cityscapes_id): 46 | lookup = { 47 | 0: 0, # ... background 48 | 1: 2, # bicycle 49 | 2: 3, # car 50 | 3: 1, # person 51 | 4: 7, # train 52 | 5: 8, # truck 53 | 6: 4, # motorcycle 54 | 7: 6, # bus 55 | 8: 1, # rider ("person", *rider has human right!*) 56 | } 57 | return lookup[cityscapes_id] 58 | 59 | 60 | def cityscapes_to_coco_without_person_rider(cityscapes_id): 61 | lookup = { 62 | 0: 0, # ... background 63 | 1: 2, # bicycle 64 | 2: 3, # car 65 | 3: -1, # person (ignore) 66 | 4: 7, # train 67 | 5: 8, # truck 68 | 6: 4, # motorcycle 69 | 7: 6, # bus 70 | 8: -1, # rider (ignore) 71 | } 72 | return lookup[cityscapes_id] 73 | 74 | 75 | def cityscapes_to_coco_all_random(cityscapes_id): 76 | lookup = { 77 | 0: -1, # ... background 78 | 1: -1, # bicycle 79 | 2: -1, # car 80 | 3: -1, # person (ignore) 81 | 4: -1, # train 82 | 5: -1, # truck 83 | 6: -1, # motorcycle 84 | 7: -1, # bus 85 | 8: -1, # rider (ignore) 86 | } 87 | return lookup[cityscapes_id] 88 | -------------------------------------------------------------------------------- /detectron/datasets/data/README.md: -------------------------------------------------------------------------------- 1 | # Setting Up Datasets 2 | 3 | This directory contains symlinks to data locations. 4 | 5 | ## Creating Symlinks for COCO 6 | 7 | Symlink the COCO dataset: 8 | 9 | ``` 10 | ln -s /path/to/coco $DETECTRON/detectron/datasets/data/coco 11 | ``` 12 | 13 | We assume that your local COCO dataset copy at `/path/to/coco` has the following directory structure: 14 | 15 | ``` 16 | coco 17 | |_ coco_train2014 18 | | |_ .jpg 19 | | |_ ... 20 | | |_ .jpg 21 | |_ coco_val2014 22 | |_ ... 23 | |_ annotations 24 | |_ instances_train2014.json 25 | |_ ... 26 | ``` 27 | 28 | If that is not the case, you may need to do something similar to: 29 | 30 | ``` 31 | mkdir -p $DETECTRON/detectron/datasets/data/coco 32 | ln -s /path/to/coco_train2014 $DETECTRON/detectron/datasets/data/coco/ 33 | ln -s /path/to/coco_val2014 $DETECTRON/detectron/datasets/data/coco/ 34 | ln -s /path/to/json/annotations $DETECTRON/detectron/datasets/data/coco/annotations 35 | ``` 36 | 37 | ### COCO Minival Annotations 38 | 39 | Our custom `minival` and `valminusminival` annotations are available for download [here](https://dl.fbaipublicfiles.com/detectron/coco/coco_annotations_minival.tgz). 40 | Please note that `minival` is exactly equivalent to the recently defined 2017 `val` set. 41 | Similarly, the union of `valminusminival` and the 2014 `train` is exactly equivalent to the 2017 `train` set. To complete installation of the COCO dataset, you will need to copy the `minival` and `valminusminival` json annotation files to the `coco/annotations` directory referenced above. 42 | 43 | ## Creating Symlinks for PASCAL VOC 44 | 45 | We assume that your symlinked `detectron/datasets/data/VOC` directory has the following structure: 46 | 47 | ``` 48 | VOC 49 | |_ JPEGImages 50 | | |_ .jpg 51 | | |_ ... 52 | | |_ .jpg 53 | |_ annotations 54 | | |_ voc__train.json 55 | | |_ voc__val.json 56 | | |_ ... 57 | |_ VOCdevkit 58 | ``` 59 | 60 | Create symlinks for `VOC`: 61 | 62 | ``` 63 | mkdir -p $DETECTRON/detectron/datasets/data/VOC 64 | ln -s /path/to/VOC/JPEGImages $DETECTRON/detectron/datasets/data/VOC/JPEGImages 65 | ln -s /path/to/VOC/json/annotations $DETECTRON/detectron/datasets/data/VOC/annotations 66 | ln -s /path/to/VOC/devkit $DETECTRON/detectron/datasets/data/VOC/VOCdevkit 67 | ``` 68 | 69 | ### PASCAL VOC Annotations in COCO Format 70 | 71 | We expect PASCAL VOC annotations converted to COCO json format, which are available for download [here](https://storage.googleapis.com/coco-dataset/external/PASCAL_VOC.zip ). 72 | 73 | ## Creating Symlinks for Cityscapes: 74 | 75 | We assume that your symlinked `detectron/datasets/data/cityscapes` directory has the following structure: 76 | 77 | ``` 78 | cityscapes 79 | |_ images 80 | | |_ .jpg 81 | | |_ ... 82 | | |_ .jpg 83 | |_ annotations 84 | | |_ instanceonly_gtFile_train.json 85 | | |_ ... 86 | |_ raw 87 | |_ gtFine 88 | |_ ... 89 | |_ README.md 90 | ``` 91 | 92 | Create symlinks for `cityscapes`: 93 | 94 | ``` 95 | mkdir -p $DETECTRON/detectron/datasets/data/cityscapes 96 | ln -s /path/to/cityscapes/images $DETECTRON/detectron/datasets/data/cityscapes/images 97 | ln -s /path/to/cityscapes/json/annotations $DETECTRON/detectron/datasets/data/cityscapes/annotations 98 | ln -s /path/to/cityscapes/root $DETECTRON/detectron/datasets/data/cityscapes/raw 99 | ``` 100 | 101 | ### Cityscapes Annotations in COCO Format 102 | 103 | We expect Cityscapes annotations converted to COCO json format, which we will make available for download soon. 104 | -------------------------------------------------------------------------------- /detectron/datasets/dummy_datasets.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | """Provide stub objects that can act as stand-in "dummy" datasets for simple use 8 | cases, like getting all classes in a dataset. This exists so that demos can be 9 | run without requiring users to download/install datasets first. 10 | """ 11 | 12 | from __future__ import absolute_import 13 | from __future__ import division 14 | from __future__ import print_function 15 | from __future__ import unicode_literals 16 | 17 | from detectron.utils.collections import AttrDict 18 | 19 | 20 | def get_coco_dataset(): 21 | """A dummy COCO dataset that includes only the 'classes' field.""" 22 | ds = AttrDict() 23 | classes = [ 24 | '__background__', 'person', 'bicycle', 'car', 'motorcycle', 'airplane', 25 | 'bus', 'train', 'truck', 'boat', 'traffic light', 'fire hydrant', 26 | 'stop sign', 'parking meter', 'bench', 'bird', 'cat', 'dog', 'horse', 27 | 'sheep', 'cow', 'elephant', 'bear', 'zebra', 'giraffe', 'backpack', 28 | 'umbrella', 'handbag', 'tie', 'suitcase', 'frisbee', 'skis', 29 | 'snowboard', 'sports ball', 'kite', 'baseball bat', 'baseball glove', 30 | 'skateboard', 'surfboard', 'tennis racket', 'bottle', 'wine glass', 31 | 'cup', 'fork', 'knife', 'spoon', 'bowl', 'banana', 'apple', 'sandwich', 32 | 'orange', 'broccoli', 'carrot', 'hot dog', 'pizza', 'donut', 'cake', 33 | 'chair', 'couch', 'potted plant', 'bed', 'dining table', 'toilet', 'tv', 34 | 'laptop', 'mouse', 'remote', 'keyboard', 'cell phone', 'microwave', 35 | 'oven', 'toaster', 'sink', 'refrigerator', 'book', 'clock', 'vase', 36 | 'scissors', 'teddy bear', 'hair drier', 'toothbrush' 37 | ] 38 | ds.classes = {i: name for i, name in enumerate(classes)} 39 | return ds 40 | -------------------------------------------------------------------------------- /detectron/modeling/VGG16.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """VGG16 from https://arxiv.org/abs/1409.1556.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from detectron.core.config import cfg 16 | 17 | 18 | def add_VGG16_conv5_body(model): 19 | model.Conv('data', 'conv1_1', 3, 64, 3, pad=1, stride=1) 20 | model.Relu('conv1_1', 'conv1_1') 21 | model.Conv('conv1_1', 'conv1_2', 64, 64, 3, pad=1, stride=1) 22 | model.Relu('conv1_2', 'conv1_2') 23 | model.MaxPool('conv1_2', 'pool1', kernel=2, pad=0, stride=2) 24 | model.Conv('pool1', 'conv2_1', 64, 128, 3, pad=1, stride=1) 25 | model.Relu('conv2_1', 'conv2_1') 26 | model.Conv('conv2_1', 'conv2_2', 128, 128, 3, pad=1, stride=1) 27 | model.Relu('conv2_2', 'conv2_2') 28 | model.MaxPool('conv2_2', 'pool2', kernel=2, pad=0, stride=2) 29 | model.StopGradient('pool2', 'pool2') 30 | model.Conv('pool2', 'conv3_1', 128, 256, 3, pad=1, stride=1) 31 | model.Relu('conv3_1', 'conv3_1') 32 | model.Conv('conv3_1', 'conv3_2', 256, 256, 3, pad=1, stride=1) 33 | model.Relu('conv3_2', 'conv3_2') 34 | model.Conv('conv3_2', 'conv3_3', 256, 256, 3, pad=1, stride=1) 35 | model.Relu('conv3_3', 'conv3_3') 36 | model.MaxPool('conv3_3', 'pool3', kernel=2, pad=0, stride=2) 37 | model.Conv('pool3', 'conv4_1', 256, 512, 3, pad=1, stride=1) 38 | model.Relu('conv4_1', 'conv4_1') 39 | model.Conv('conv4_1', 'conv4_2', 512, 512, 3, pad=1, stride=1) 40 | model.Relu('conv4_2', 'conv4_2') 41 | model.Conv('conv4_2', 'conv4_3', 512, 512, 3, pad=1, stride=1) 42 | model.Relu('conv4_3', 'conv4_3') 43 | model.MaxPool('conv4_3', 'pool4', kernel=2, pad=0, stride=2) 44 | model.Conv('pool4', 'conv5_1', 512, 512, 3, pad=1, stride=1) 45 | model.Relu('conv5_1', 'conv5_1') 46 | model.Conv('conv5_1', 'conv5_2', 512, 512, 3, pad=1, stride=1) 47 | model.Relu('conv5_2', 'conv5_2') 48 | model.Conv('conv5_2', 'conv5_3', 512, 512, 3, pad=1, stride=1) 49 | blob_out = model.Relu('conv5_3', 'conv5_3') 50 | return blob_out, 512, 1. / 16. 51 | 52 | 53 | def add_VGG16_roi_fc_head(model, blob_in, dim_in, spatial_scale): 54 | model.RoIFeatureTransform( 55 | blob_in, 56 | 'pool5', 57 | blob_rois='rois', 58 | method=cfg.FAST_RCNN.ROI_XFORM_METHOD, 59 | resolution=7, 60 | sampling_ratio=cfg.FAST_RCNN.ROI_XFORM_SAMPLING_RATIO, 61 | spatial_scale=spatial_scale 62 | ) 63 | model.FC('pool5', 'fc6', dim_in * 7 * 7, 4096) 64 | model.Relu('fc6', 'fc6') 65 | model.FC('fc6', 'fc7', 4096, 4096) 66 | blob_out = model.Relu('fc7', 'fc7') 67 | return blob_out, 4096 68 | -------------------------------------------------------------------------------- /detectron/modeling/VGG_CNN_M_1024.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """VGG_CNN_M_1024 from https://arxiv.org/abs/1405.3531.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from detectron.core.config import cfg 16 | 17 | 18 | def add_VGG_CNN_M_1024_conv5_body(model): 19 | model.Conv('data', 'conv1', 3, 96, 7, pad=0, stride=2) 20 | model.Relu('conv1', 'conv1') 21 | model.LRN('conv1', 'norm1', size=5, alpha=0.0005, beta=0.75, bias=2.) 22 | model.MaxPool('norm1', 'pool1', kernel=3, pad=0, stride=2) 23 | model.StopGradient('pool1', 'pool1') 24 | # No updates at conv1 and below (norm1 and pool1 have no params, 25 | # so we can stop gradients before them, too) 26 | model.Conv('pool1', 'conv2', 96, 256, 5, pad=0, stride=2) 27 | model.Relu('conv2', 'conv2') 28 | model.LRN('conv2', 'norm2', size=5, alpha=0.0005, beta=0.75, bias=2.) 29 | model.MaxPool('norm2', 'pool2', kernel=3, pad=0, stride=2) 30 | model.Conv('pool2', 'conv3', 256, 512, 3, pad=1, stride=1) 31 | model.Relu('conv3', 'conv3') 32 | model.Conv('conv3', 'conv4', 512, 512, 3, pad=1, stride=1) 33 | model.Relu('conv4', 'conv4') 34 | model.Conv('conv4', 'conv5', 512, 512, 3, pad=1, stride=1) 35 | blob_out = model.Relu('conv5', 'conv5') 36 | return blob_out, 512, 1. / 16. 37 | 38 | 39 | def add_VGG_CNN_M_1024_roi_fc_head(model, blob_in, dim_in, spatial_scale): 40 | model.RoIFeatureTransform( 41 | blob_in, 42 | 'pool5', 43 | blob_rois='rois', 44 | method=cfg.FAST_RCNN.ROI_XFORM_METHOD, 45 | resolution=6, 46 | sampling_ratio=cfg.FAST_RCNN.ROI_XFORM_SAMPLING_RATIO, 47 | spatial_scale=spatial_scale 48 | ) 49 | model.FC('pool5', 'fc6', dim_in * 6 * 6, 4096) 50 | model.Relu('fc6', 'fc6') 51 | model.FC('fc6', 'fc7', 4096, 1024) 52 | blob_out = model.Relu('fc7', 'fc7') 53 | return blob_out, 1024 54 | -------------------------------------------------------------------------------- /detectron/modeling/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /detectron/modeling/generate_anchors.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | # 8 | # Based on: 9 | # -------------------------------------------------------- 10 | # Faster R-CNN 11 | # Copyright (c) 2015 Microsoft 12 | # Licensed under The MIT License [see LICENSE for details] 13 | # Written by Ross Girshick and Sean Bell 14 | # -------------------------------------------------------- 15 | 16 | import numpy as np 17 | 18 | # Verify that we compute the same anchors as Shaoqing's matlab implementation: 19 | # 20 | # >> load output/rpn_cachedir/faster_rcnn_VOC2007_ZF_stage1_rpn/anchors.mat 21 | # >> anchors 22 | # 23 | # anchors = 24 | # 25 | # -83 -39 100 56 26 | # -175 -87 192 104 27 | # -359 -183 376 200 28 | # -55 -55 72 72 29 | # -119 -119 136 136 30 | # -247 -247 264 264 31 | # -35 -79 52 96 32 | # -79 -167 96 184 33 | # -167 -343 184 360 34 | 35 | # array([[ -83., -39., 100., 56.], 36 | # [-175., -87., 192., 104.], 37 | # [-359., -183., 376., 200.], 38 | # [ -55., -55., 72., 72.], 39 | # [-119., -119., 136., 136.], 40 | # [-247., -247., 264., 264.], 41 | # [ -35., -79., 52., 96.], 42 | # [ -79., -167., 96., 184.], 43 | # [-167., -343., 184., 360.]]) 44 | 45 | 46 | def generate_anchors( 47 | stride=16, sizes=(32, 64, 128, 256, 512), aspect_ratios=(0.5, 1, 2) 48 | ): 49 | """Generates a matrix of anchor boxes in (x1, y1, x2, y2) format. Anchors 50 | are centered on stride / 2, have (approximate) sqrt areas of the specified 51 | sizes, and aspect ratios as given. 52 | """ 53 | return _generate_anchors( 54 | stride, 55 | np.array(sizes, dtype=np.float) / stride, 56 | np.array(aspect_ratios, dtype=np.float) 57 | ) 58 | 59 | 60 | def _generate_anchors(base_size, scales, aspect_ratios): 61 | """Generate anchor (reference) windows by enumerating aspect ratios X 62 | scales wrt a reference (0, 0, base_size - 1, base_size - 1) window. 63 | """ 64 | anchor = np.array([1, 1, base_size, base_size], dtype=np.float) - 1 65 | anchors = _ratio_enum(anchor, aspect_ratios) 66 | anchors = np.vstack( 67 | [_scale_enum(anchors[i, :], scales) for i in range(anchors.shape[0])] 68 | ) 69 | return anchors 70 | 71 | 72 | def _whctrs(anchor): 73 | """Return width, height, x center, and y center for an anchor (window).""" 74 | w = anchor[2] - anchor[0] + 1 75 | h = anchor[3] - anchor[1] + 1 76 | x_ctr = anchor[0] + 0.5 * (w - 1) 77 | y_ctr = anchor[1] + 0.5 * (h - 1) 78 | return w, h, x_ctr, y_ctr 79 | 80 | 81 | def _mkanchors(ws, hs, x_ctr, y_ctr): 82 | """Given a vector of widths (ws) and heights (hs) around a center 83 | (x_ctr, y_ctr), output a set of anchors (windows). 84 | """ 85 | ws = ws[:, np.newaxis] 86 | hs = hs[:, np.newaxis] 87 | anchors = np.hstack( 88 | ( 89 | x_ctr - 0.5 * (ws - 1), 90 | y_ctr - 0.5 * (hs - 1), 91 | x_ctr + 0.5 * (ws - 1), 92 | y_ctr + 0.5 * (hs - 1) 93 | ) 94 | ) 95 | return anchors 96 | 97 | 98 | def _ratio_enum(anchor, ratios): 99 | """Enumerate a set of anchors for each aspect ratio wrt an anchor.""" 100 | w, h, x_ctr, y_ctr = _whctrs(anchor) 101 | size = w * h 102 | size_ratios = size / ratios 103 | ws = np.round(np.sqrt(size_ratios)) 104 | hs = np.round(ws * ratios) 105 | anchors = _mkanchors(ws, hs, x_ctr, y_ctr) 106 | return anchors 107 | 108 | 109 | def _scale_enum(anchor, scales): 110 | """Enumerate a set of anchors for each scale wrt an anchor.""" 111 | w, h, x_ctr, y_ctr = _whctrs(anchor) 112 | ws = w * scales 113 | hs = h * scales 114 | anchors = _mkanchors(ws, hs, x_ctr, y_ctr) 115 | return anchors 116 | -------------------------------------------------------------------------------- /detectron/modeling/name_compat.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Handle mapping from old network building function names to new names. 9 | 10 | Flexible network configuration is achieved by specifying the function name that 11 | builds a network module (e.g., the name of the conv backbone or the mask roi 12 | head). However we may wish to change names over time without breaking previous 13 | config files. This module provides backwards naming compatibility by providing 14 | a mapping from the old name to the new name. 15 | 16 | When renaming functions, it's generally a good idea to codemod existing yaml 17 | config files. An easy way to batch edit, by example, is a shell command like 18 | 19 | $ find . -name "*.yaml" -exec sed -i -e \ 20 | 's/head_builder\.add_roi_2mlp_head/fast_rcnn_heads.add_roi_2mlp_head/g' {} \; 21 | 22 | to perform the renaming: 23 | head_builder.add_roi_2mlp_head => fast_rcnn_heads.add_roi_2mlp_head 24 | """ 25 | 26 | from __future__ import absolute_import 27 | from __future__ import division 28 | from __future__ import print_function 29 | from __future__ import unicode_literals 30 | 31 | 32 | _RENAME = { 33 | # Removed "ResNet_" from the name because it wasn't relevent 34 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v1up4convs': 35 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v1up4convs', 36 | # Removed "ResNet_" from the name because it wasn't relevent 37 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v1up': 38 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v1up', 39 | # Removed "ResNet_" from the name because it wasn't relevent 40 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v0upshare': 41 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v0upshare', 42 | # Removed "ResNet_" from the name because it wasn't relevent 43 | 'mask_rcnn_heads.ResNet_mask_rcnn_fcn_head_v0up': 44 | 'mask_rcnn_heads.mask_rcnn_fcn_head_v0up', 45 | # Removed head_builder module in favor of the more specific fast_rcnn name 46 | 'head_builder.add_roi_2mlp_head': 47 | 'fast_rcnn_heads.add_roi_2mlp_head', 48 | } 49 | 50 | 51 | def get_new_name(func_name): 52 | if func_name in _RENAME: 53 | func_name = _RENAME[func_name] 54 | return func_name 55 | -------------------------------------------------------------------------------- /detectron/modeling/rfcn_heads.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | from detectron.core.config import cfg 14 | from detectron.utils.c2 import const_fill 15 | from detectron.utils.c2 import gauss_fill 16 | 17 | 18 | # ---------------------------------------------------------------------------- # 19 | # R-FCN outputs and losses 20 | # ---------------------------------------------------------------------------- # 21 | 22 | def add_rfcn_outputs(model, blob_in, dim_in, dim_reduce, spatial_scale): 23 | if dim_reduce is not None: 24 | # Optional dim reduction 25 | blob_in = model.Conv( 26 | blob_in, 27 | 'conv_dim_reduce', 28 | dim_in, 29 | dim_reduce, 30 | kernel=1, 31 | pad=0, 32 | stride=1, 33 | weight_init=gauss_fill(0.01), 34 | bias_init=const_fill(0.0) 35 | ) 36 | blob_in = model.Relu(blob_in, blob_in) 37 | dim_in = dim_reduce 38 | # Classification conv 39 | model.Conv( 40 | blob_in, 41 | 'conv_cls', 42 | dim_in, 43 | model.num_classes * cfg.RFCN.PS_GRID_SIZE**2, 44 | kernel=1, 45 | pad=0, 46 | stride=1, 47 | weight_init=gauss_fill(0.01), 48 | bias_init=const_fill(0.0) 49 | ) 50 | # Bounding-box regression conv 51 | num_bbox_reg_classes = ( 52 | 2 if cfg.MODEL.CLS_AGNOSTIC_BBOX_REG else model.num_classes 53 | ) 54 | model.Conv( 55 | blob_in, 56 | 'conv_bbox_pred', 57 | dim_in, 58 | 4 * num_bbox_reg_classes * cfg.RFCN.PS_GRID_SIZE**2, 59 | kernel=1, 60 | pad=0, 61 | stride=1, 62 | weight_init=gauss_fill(0.01), 63 | bias_init=const_fill(0.0) 64 | ) 65 | # Classification PS RoI pooling 66 | model.net.PSRoIPool( 67 | ['conv_cls', 'rois'], ['psroipooled_cls', '_mapping_channel_cls'], 68 | group_size=cfg.RFCN.PS_GRID_SIZE, 69 | output_dim=model.num_classes, 70 | spatial_scale=spatial_scale 71 | ) 72 | model.AveragePool( 73 | 'psroipooled_cls', 'cls_score_4d', kernel=cfg.RFCN.PS_GRID_SIZE 74 | ) 75 | model.net.Reshape( 76 | 'cls_score_4d', ['cls_score', '_cls_scores_shape'], 77 | shape=(-1, cfg.MODEL.NUM_CLASSES) 78 | ) 79 | if not model.train: 80 | model.Softmax('cls_score', 'cls_prob', engine='CUDNN') 81 | # Bbox regression PS RoI pooling 82 | model.net.PSRoIPool( 83 | ['conv_bbox_pred', 'rois'], 84 | ['psroipooled_bbox', '_mapping_channel_bbox'], 85 | group_size=cfg.RFCN.PS_GRID_SIZE, 86 | output_dim=4 * num_bbox_reg_classes, 87 | spatial_scale=spatial_scale 88 | ) 89 | model.AveragePool( 90 | 'psroipooled_bbox', 'bbox_pred', kernel=cfg.RFCN.PS_GRID_SIZE 91 | ) 92 | -------------------------------------------------------------------------------- /detectron/ops/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/ops/__init__.py -------------------------------------------------------------------------------- /detectron/ops/generate_proposal_labels.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import logging 14 | 15 | from detectron.datasets import json_dataset 16 | from detectron.datasets import roidb as roidb_utils 17 | from detectron.utils import blob as blob_utils 18 | import detectron.roi_data.fast_rcnn as fast_rcnn_roi_data 19 | 20 | logger = logging.getLogger(__name__) 21 | 22 | 23 | class GenerateProposalLabelsOp(object): 24 | 25 | def forward(self, inputs, outputs): 26 | """See modeling.detector.GenerateProposalLabels for inputs/outputs 27 | documentation. 28 | """ 29 | # During training we reuse the data loader code. We populate roidb 30 | # entries on the fly using the rois generated by RPN. 31 | # im_info: [[im_height, im_width, im_scale], ...] 32 | rois = inputs[0].data 33 | roidb = blob_utils.deserialize(inputs[1].data) 34 | im_info = inputs[2].data 35 | im_scales = im_info[:, 2] 36 | output_blob_names = fast_rcnn_roi_data.get_fast_rcnn_blob_names() 37 | # For historical consistency with the original Faster R-CNN 38 | # implementation we are *not* filtering crowd proposals. 39 | # This choice should be investigated in the future (it likely does 40 | # not matter). 41 | json_dataset.add_proposals(roidb, rois, im_scales, crowd_thresh=0) 42 | roidb_utils.add_bbox_regression_targets(roidb) 43 | blobs = {k: [] for k in output_blob_names} 44 | fast_rcnn_roi_data.add_fast_rcnn_blobs(blobs, im_scales, roidb) 45 | for i, k in enumerate(output_blob_names): 46 | blob_utils.py_op_copy_blob(blobs[k], outputs[i]) 47 | -------------------------------------------------------------------------------- /detectron/ops/pool_points_interp.cc: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | 10 | #include "pool_points_interp.h" 11 | 12 | namespace caffe2 { 13 | //namespace { 14 | 15 | REGISTER_CPU_OPERATOR(PoolPointsInterp, 16 | PoolPointsInterpOp); 17 | REGISTER_CPU_OPERATOR(PoolPointsInterpGradient, 18 | PoolPointsInterpGradientOp); 19 | 20 | // Input: X, points; Output: Y 21 | OPERATOR_SCHEMA(PoolPointsInterp).NumInputs(2).NumOutputs(1); 22 | // Input: X, points, dY (aka "gradOutput"); 23 | // Output: dX (aka "gradInput") 24 | OPERATOR_SCHEMA(PoolPointsInterpGradient).NumInputs(3).NumOutputs(1); 25 | 26 | class GetPoolPointsInterpGradient : public GradientMakerBase { 27 | using GradientMakerBase::GradientMakerBase; 28 | vector GetGradientDefs() override { 29 | return SingleGradientDef( 30 | "PoolPointsInterpGradient", "", 31 | vector{I(0), I(1), GO(0)}, 32 | vector{GI(0)}); 33 | } 34 | }; 35 | 36 | REGISTER_GRADIENT(PoolPointsInterp, GetPoolPointsInterpGradient); 37 | 38 | //} // namespace 39 | } // namespace caffe2 40 | -------------------------------------------------------------------------------- /detectron/ops/pool_points_interp.h: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | 10 | #ifndef POOL_POINTS_INTERP_OP_H_ 11 | #define POOL_POINTS_INTERP_OP_H_ 12 | 13 | #include "caffe2/core/context.h" 14 | #include "caffe2/core/logging.h" 15 | #include "caffe2/core/operator.h" 16 | 17 | namespace caffe2 { 18 | 19 | template 20 | class PoolPointsInterpOp final : public Operator { 21 | public: 22 | PoolPointsInterpOp(const OperatorDef& operator_def, Workspace* ws) 23 | : Operator(operator_def, ws), 24 | spatial_scale_(OperatorBase::GetSingleArgument( 25 | "spatial_scale", 1.)) { 26 | DCHECK_GT(spatial_scale_, 0); 27 | } 28 | USE_OPERATOR_CONTEXT_FUNCTIONS; 29 | 30 | bool RunOnDevice() override { 31 | CAFFE_NOT_IMPLEMENTED; 32 | } 33 | 34 | protected: 35 | float spatial_scale_; 36 | }; 37 | 38 | template 39 | class PoolPointsInterpGradientOp final : public Operator { 40 | public: 41 | PoolPointsInterpGradientOp(const OperatorDef& def, Workspace* ws) 42 | : Operator(def, ws), 43 | spatial_scale_(OperatorBase::GetSingleArgument( 44 | "spatial_scale", 1.)){ 45 | DCHECK_GT(spatial_scale_, 0); 46 | } 47 | USE_OPERATOR_CONTEXT_FUNCTIONS; 48 | 49 | bool RunOnDevice() override { 50 | CAFFE_NOT_IMPLEMENTED; 51 | } 52 | 53 | protected: 54 | float spatial_scale_; 55 | }; 56 | 57 | } // namespace caffe2 58 | 59 | #endif // PoolPointsInterpOp 60 | -------------------------------------------------------------------------------- /detectron/ops/zero_even_op.cc: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #include "zero_even_op.h" 10 | 11 | namespace caffe2 { 12 | 13 | template <> 14 | bool ZeroEvenOp::RunOnDevice() { 15 | // Retrieve the input tensor. 16 | const auto& X = Input(0); 17 | CAFFE_ENFORCE(X.ndim() == 1); 18 | 19 | // Initialize the output tensor to a copy of the input tensor. 20 | auto* Y = Output(0); 21 | Y->CopyFrom(X); 22 | 23 | // Set output elements at even indices to zero. 24 | auto* Y_data = Y->mutable_data(); 25 | for (auto i = 0; i < Y->size(); i += 2) { 26 | Y_data[i] = 0.0f; 27 | } 28 | 29 | return true; 30 | } 31 | 32 | REGISTER_CPU_OPERATOR(ZeroEven, ZeroEvenOp); 33 | 34 | OPERATOR_SCHEMA(ZeroEven) 35 | .NumInputs(1) 36 | .NumOutputs(1) 37 | .Input( 38 | 0, 39 | "X", 40 | "1D input tensor") 41 | .Output( 42 | 0, 43 | "Y", 44 | "1D output tensor"); 45 | 46 | } // namespace caffe2 47 | -------------------------------------------------------------------------------- /detectron/ops/zero_even_op.cu: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #include "caffe2/core/context_gpu.h" 10 | 11 | #include "zero_even_op.h" 12 | 13 | namespace caffe2 { 14 | 15 | namespace { 16 | 17 | template 18 | __global__ void SetEvenIndsToVal(size_t num_even_inds, T val, T* data) { 19 | CUDA_1D_KERNEL_LOOP(i, num_even_inds) { 20 | data[i << 1] = val; 21 | } 22 | } 23 | 24 | } // namespace 25 | 26 | template <> 27 | bool ZeroEvenOp::RunOnDevice() { 28 | // Retrieve the input tensor. 29 | const auto& X = Input(0); 30 | CAFFE_ENFORCE(X.ndim() == 1); 31 | 32 | // Initialize the output tensor to a copy of the input tensor. 33 | auto* Y = Output(0); 34 | Y->CopyFrom(X); 35 | 36 | // Set output elements at even indices to zero. 37 | auto output_size = Y->size(); 38 | 39 | if (output_size > 0) { 40 | size_t num_even_inds = output_size / 2 + output_size % 2; 41 | SetEvenIndsToVal 42 | <<>>( 46 | num_even_inds, 47 | 0.0f, 48 | Y->mutable_data()); 49 | } 50 | 51 | return true; 52 | } 53 | 54 | REGISTER_CUDA_OPERATOR(ZeroEven, ZeroEvenOp); 55 | 56 | } // namespace caffe2 57 | -------------------------------------------------------------------------------- /detectron/ops/zero_even_op.h: -------------------------------------------------------------------------------- 1 | /** 2 | # Copyright (c) Facebook, Inc. and its affiliates. 3 | # All rights reserved. 4 | # 5 | # This source code is licensed under the license found in the 6 | # LICENSE file in the root directory of this source tree. 7 | */ 8 | 9 | #ifndef ZERO_EVEN_OP_H_ 10 | #define ZERO_EVEN_OP_H_ 11 | 12 | #include "caffe2/core/context.h" 13 | #include "caffe2/core/operator.h" 14 | //#include "caffe2/utils/math.h" 15 | 16 | namespace caffe2 { 17 | 18 | /** 19 | * ZeroEven operator. Zeros elements at even indices of an 1D array. 20 | * Elements at odd indices are preserved. 21 | * 22 | * This toy operator is an example of a custom operator and may be a useful 23 | * reference for adding new custom operators to the Detectron codebase. 24 | */ 25 | template 26 | class ZeroEvenOp final : public Operator { 27 | public: 28 | // Introduce Operator helper members. 29 | USE_OPERATOR_CONTEXT_FUNCTIONS; 30 | 31 | ZeroEvenOp(const OperatorDef& operator_def, Workspace* ws) 32 | : Operator(operator_def, ws) {} 33 | 34 | bool RunOnDevice() override; 35 | }; 36 | 37 | } // namespace caffe2 38 | 39 | #endif // ZERO_EVEN_OP_H_ 40 | -------------------------------------------------------------------------------- /detectron/roi_data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/roi_data/__init__.py -------------------------------------------------------------------------------- /detectron/roi_data/data_utils.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Common utility functions for RPN and RetinaNet minibtach blobs preparation. 9 | """ 10 | 11 | from __future__ import absolute_import 12 | from __future__ import division 13 | from __future__ import print_function 14 | from __future__ import unicode_literals 15 | 16 | from collections import namedtuple 17 | import logging 18 | import numpy as np 19 | import threading 20 | 21 | from detectron.core.config import cfg 22 | from detectron.modeling.generate_anchors import generate_anchors 23 | import detectron.utils.boxes as box_utils 24 | 25 | logger = logging.getLogger(__name__) 26 | 27 | 28 | # octave and aspect fields are only used on RetinaNet. Octave corresponds to the 29 | # scale of the anchor and aspect denotes which aspect ratio is used in the range 30 | # of aspect ratios 31 | FieldOfAnchors = namedtuple( 32 | 'FieldOfAnchors', [ 33 | 'field_of_anchors', 'num_cell_anchors', 'stride', 'field_size', 34 | 'octave', 'aspect' 35 | ] 36 | ) 37 | 38 | # Cache for memoizing _get_field_of_anchors 39 | _threadlocal_foa = threading.local() 40 | 41 | 42 | def get_field_of_anchors( 43 | stride, anchor_sizes, anchor_aspect_ratios, octave=None, aspect=None 44 | ): 45 | global _threadlocal_foa 46 | if not hasattr(_threadlocal_foa, 'cache'): 47 | _threadlocal_foa.cache = {} 48 | 49 | cache_key = str(stride) + str(anchor_sizes) + str(anchor_aspect_ratios) 50 | if cache_key in _threadlocal_foa.cache: 51 | return _threadlocal_foa.cache[cache_key] 52 | 53 | # Anchors at a single feature cell 54 | cell_anchors = generate_anchors( 55 | stride=stride, sizes=anchor_sizes, aspect_ratios=anchor_aspect_ratios 56 | ) 57 | num_cell_anchors = cell_anchors.shape[0] 58 | 59 | # Generate canonical proposals from shifted anchors 60 | # Enumerate all shifted positions on the (H, W) grid 61 | fpn_max_size = cfg.FPN.COARSEST_STRIDE * np.ceil( 62 | cfg.TRAIN.MAX_SIZE / float(cfg.FPN.COARSEST_STRIDE) 63 | ) 64 | field_size = int(np.ceil(fpn_max_size / float(stride))) 65 | shifts = np.arange(0, field_size) * stride 66 | shift_x, shift_y = np.meshgrid(shifts, shifts) 67 | shift_x = shift_x.ravel() 68 | shift_y = shift_y.ravel() 69 | shifts = np.vstack((shift_x, shift_y, shift_x, shift_y)).transpose() 70 | 71 | # Broacast anchors over shifts to enumerate all anchors at all positions 72 | # in the (H, W) grid: 73 | # - add A cell anchors of shape (1, A, 4) to 74 | # - K shifts of shape (K, 1, 4) to get 75 | # - all shifted anchors of shape (K, A, 4) 76 | # - reshape to (K*A, 4) shifted anchors 77 | A = num_cell_anchors 78 | K = shifts.shape[0] 79 | field_of_anchors = ( 80 | cell_anchors.reshape((1, A, 4)) + 81 | shifts.reshape((1, K, 4)).transpose((1, 0, 2)) 82 | ) 83 | field_of_anchors = field_of_anchors.reshape((K * A, 4)) 84 | foa = FieldOfAnchors( 85 | field_of_anchors=field_of_anchors.astype(np.float32), 86 | num_cell_anchors=num_cell_anchors, 87 | stride=stride, 88 | field_size=field_size, 89 | octave=octave, 90 | aspect=aspect 91 | ) 92 | _threadlocal_foa.cache[cache_key] = foa 93 | return foa 94 | 95 | 96 | def unmap(data, count, inds, fill=0): 97 | """Unmap a subset of item (data) back to the original set of items (of 98 | size count)""" 99 | if count == len(inds): 100 | return data 101 | 102 | if len(data.shape) == 1: 103 | ret = np.empty((count, ), dtype=data.dtype) 104 | ret.fill(fill) 105 | ret[inds] = data 106 | else: 107 | ret = np.empty((count, ) + data.shape[1:], dtype=data.dtype) 108 | ret.fill(fill) 109 | ret[inds, :] = data 110 | return ret 111 | 112 | 113 | def compute_targets(ex_rois, gt_rois, weights=(1.0, 1.0, 1.0, 1.0)): 114 | """Compute bounding-box regression targets for an image.""" 115 | return box_utils.bbox_transform_inv(ex_rois, gt_rois, weights).astype( 116 | np.float32, copy=False 117 | ) 118 | -------------------------------------------------------------------------------- /detectron/roi_data/minibatch.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | # 8 | # Based on: 9 | # -------------------------------------------------------- 10 | # Fast R-CNN 11 | # Copyright (c) 2015 Microsoft 12 | # Licensed under The MIT License [see LICENSE for details] 13 | # Written by Ross Girshick 14 | # -------------------------------------------------------- 15 | 16 | """Construct minibatches for Detectron networks.""" 17 | 18 | from __future__ import absolute_import 19 | from __future__ import division 20 | from __future__ import print_function 21 | from __future__ import unicode_literals 22 | 23 | import cv2 24 | import logging 25 | import numpy as np 26 | 27 | from detectron.core.config import cfg 28 | import detectron.roi_data.fast_rcnn as fast_rcnn_roi_data 29 | import detectron.roi_data.retinanet as retinanet_roi_data 30 | import detectron.roi_data.rpn as rpn_roi_data 31 | import detectron.utils.blob as blob_utils 32 | 33 | logger = logging.getLogger(__name__) 34 | 35 | 36 | def get_minibatch_blob_names(is_training=True): 37 | """Return blob names in the order in which they are read by the data loader. 38 | """ 39 | # data blob: holds a batch of N images, each with 3 channels 40 | blob_names = ['data'] 41 | if cfg.RPN.RPN_ON: 42 | # RPN-only or end-to-end Faster R-CNN 43 | blob_names += rpn_roi_data.get_rpn_blob_names(is_training=is_training) 44 | elif cfg.RETINANET.RETINANET_ON: 45 | blob_names += retinanet_roi_data.get_retinanet_blob_names( 46 | is_training=is_training 47 | ) 48 | else: 49 | # Fast R-CNN like models trained on precomputed proposals 50 | blob_names += fast_rcnn_roi_data.get_fast_rcnn_blob_names( 51 | is_training=is_training 52 | ) 53 | return blob_names 54 | 55 | 56 | def get_minibatch(roidb): 57 | """Given a roidb, construct a minibatch sampled from it.""" 58 | # We collect blobs from each image onto a list and then concat them into a 59 | # single tensor, hence we initialize each blob to an empty list 60 | blobs = {k: [] for k in get_minibatch_blob_names()} 61 | # Get the input image blob, formatted for caffe2 62 | im_blob, im_scales = _get_image_blob(roidb) 63 | blobs['data'] = im_blob 64 | if cfg.RPN.RPN_ON: 65 | # RPN-only or end-to-end Faster/Mask R-CNN 66 | valid = rpn_roi_data.add_rpn_blobs(blobs, im_scales, roidb) 67 | elif cfg.RETINANET.RETINANET_ON: 68 | im_width, im_height = im_blob.shape[3], im_blob.shape[2] 69 | # im_width, im_height corresponds to the network input: padded image 70 | # (if needed) width and height. We pass it as input and slice the data 71 | # accordingly so that we don't need to use SampleAsOp 72 | valid = retinanet_roi_data.add_retinanet_blobs( 73 | blobs, im_scales, roidb, im_width, im_height 74 | ) 75 | else: 76 | # Fast R-CNN like models trained on precomputed proposals 77 | valid = fast_rcnn_roi_data.add_fast_rcnn_blobs(blobs, im_scales, roidb) 78 | return blobs, valid 79 | 80 | 81 | def _get_image_blob(roidb): 82 | """Builds an input blob from the images in the roidb at the specified 83 | scales. 84 | """ 85 | num_images = len(roidb) 86 | # Sample random scales to use for each image in this batch 87 | scale_inds = np.random.randint( 88 | 0, high=len(cfg.TRAIN.SCALES), size=num_images 89 | ) 90 | processed_ims = [] 91 | im_scales = [] 92 | for i in range(num_images): 93 | im = cv2.imread(roidb[i]['image']) 94 | assert im is not None, \ 95 | 'Failed to read image \'{}\''.format(roidb[i]['image']) 96 | if roidb[i]['flipped']: 97 | im = im[:, ::-1, :] 98 | target_size = cfg.TRAIN.SCALES[scale_inds[i]] 99 | im, im_scale = blob_utils.prep_im_for_blob( 100 | im, cfg.PIXEL_MEANS, target_size, cfg.TRAIN.MAX_SIZE 101 | ) 102 | im_scales.append(im_scale) 103 | processed_ims.append(im) 104 | 105 | # Create a blob to hold the input images 106 | blob = blob_utils.im_list_to_blob(processed_ims) 107 | 108 | return blob, im_scales 109 | -------------------------------------------------------------------------------- /detectron/tests/test_batch_permutation_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.logging as logging_utils 22 | import detectron.utils.c2 as c2_utils 23 | 24 | 25 | class BatchPermutationOpTest(unittest.TestCase): 26 | def _run_op_test(self, X, I, check_grad=False): 27 | with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 28 | op = core.CreateOperator('BatchPermutation', ['X', 'I'], ['Y']) 29 | workspace.FeedBlob('X', X) 30 | workspace.FeedBlob('I', I) 31 | workspace.RunOperatorOnce(op) 32 | Y = workspace.FetchBlob('Y') 33 | 34 | if check_grad: 35 | gc = gradient_checker.GradientChecker( 36 | stepsize=0.1, 37 | threshold=0.001, 38 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 39 | ) 40 | 41 | res, grad, grad_estimated = gc.CheckSimple(op, [X, I], 0, [0]) 42 | self.assertTrue(res, 'Grad check failed') 43 | 44 | Y_ref = X[I] 45 | np.testing.assert_allclose(Y, Y_ref, rtol=1e-5, atol=1e-08) 46 | 47 | def _run_speed_test(self, iters=5, N=1024): 48 | """This function provides an example of how to benchmark custom 49 | operators using the Caffe2 'prof_dag' network execution type. Please 50 | note that for 'prof_dag' to work, Caffe2 must be compiled with profiling 51 | support using the `-DUSE_PROF=ON` option passed to `cmake` when building 52 | Caffe2. 53 | """ 54 | net = core.Net('test') 55 | net.Proto().type = 'prof_dag' 56 | net.Proto().num_workers = 2 57 | Y = net.BatchPermutation(['X', 'I'], 'Y') 58 | Y_flat = net.FlattenToVec([Y], 'Y_flat') 59 | loss = net.AveragedLoss([Y_flat], 'loss') 60 | net.AddGradientOperators([loss]) 61 | workspace.CreateNet(net) 62 | 63 | X = np.random.randn(N, 256, 14, 14) 64 | for _i in range(iters): 65 | I = np.random.permutation(N) 66 | workspace.FeedBlob('X', X.astype(np.float32)) 67 | workspace.FeedBlob('I', I.astype(np.int32)) 68 | workspace.RunNet(net.Proto().name) 69 | np.testing.assert_allclose( 70 | workspace.FetchBlob('Y'), X[I], rtol=1e-5, atol=1e-08 71 | ) 72 | 73 | def test_forward_and_gradient(self): 74 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 75 | I = np.array([0, 1], dtype=np.int32) 76 | self._run_op_test(A, I, check_grad=True) 77 | 78 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 79 | I = np.array([1, 0], dtype=np.int32) 80 | self._run_op_test(A, I, check_grad=True) 81 | 82 | A = np.random.randn(10, 3, 5, 7).astype(np.float32) 83 | I = np.array(np.random.permutation(10), dtype=np.int32) 84 | self._run_op_test(A, I, check_grad=True) 85 | 86 | def test_size_exceptions(self): 87 | A = np.random.randn(2, 256, 42, 86).astype(np.float32) 88 | I = np.array(np.random.permutation(10), dtype=np.int32) 89 | with self.assertRaises(RuntimeError): 90 | self._run_op_test(A, I) 91 | 92 | # See doc string in _run_speed_test 93 | # def test_perf(self): 94 | # with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 95 | # self._run_speed_test() 96 | 97 | 98 | if __name__ == '__main__': 99 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 100 | c2_utils.import_detectron_ops() 101 | assert 'BatchPermutation' in workspace.RegisteredOperators() 102 | logging_utils.setup_logging(__name__) 103 | unittest.main() 104 | -------------------------------------------------------------------------------- /detectron/tests/test_bbox_transform.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from pycocotools import mask as COCOmask 17 | 18 | import detectron.utils.boxes as box_utils 19 | 20 | 21 | def random_boxes(mean_box, stdev, N): 22 | boxes = np.random.randn(N, 4) * stdev + mean_box 23 | return boxes.astype(dtype=np.float32) 24 | 25 | 26 | class TestBboxTransform(unittest.TestCase): 27 | def test_bbox_transform_and_inverse(self): 28 | weights = (5, 5, 10, 10) 29 | src_boxes = random_boxes([10, 10, 20, 20], 1, 10) 30 | dst_boxes = random_boxes([10, 10, 20, 20], 1, 10) 31 | deltas = box_utils.bbox_transform_inv( 32 | src_boxes, dst_boxes, weights=weights 33 | ) 34 | dst_boxes_reconstructed = box_utils.bbox_transform( 35 | src_boxes, deltas, weights=weights 36 | ) 37 | np.testing.assert_array_almost_equal( 38 | dst_boxes, dst_boxes_reconstructed, decimal=5 39 | ) 40 | 41 | def test_bbox_dataset_to_prediction_roundtrip(self): 42 | """Simulate the process of reading a ground-truth box from a dataset, 43 | make predictions from proposals, convert the predictions back to the 44 | dataset format, and then use the COCO API to compute IoU overlap between 45 | the gt box and the predictions. These should have IoU of 1. 46 | """ 47 | weights = (5, 5, 10, 10) 48 | # 1/ "read" a box from a dataset in the default (x1, y1, w, h) format 49 | gt_xywh_box = [10, 20, 100, 150] 50 | # 2/ convert it to our internal (x1, y1, x2, y2) format 51 | gt_xyxy_box = box_utils.xywh_to_xyxy(gt_xywh_box) 52 | # 3/ consider nearby proposal boxes 53 | prop_xyxy_boxes = random_boxes(gt_xyxy_box, 10, 10) 54 | # 4/ compute proposal-to-gt transformation deltas 55 | deltas = box_utils.bbox_transform_inv( 56 | prop_xyxy_boxes, np.array([gt_xyxy_box]), weights=weights 57 | ) 58 | # 5/ use deltas to transform proposals to xyxy predicted box 59 | pred_xyxy_boxes = box_utils.bbox_transform( 60 | prop_xyxy_boxes, deltas, weights=weights 61 | ) 62 | # 6/ convert xyxy predicted box to xywh predicted box 63 | pred_xywh_boxes = box_utils.xyxy_to_xywh(pred_xyxy_boxes) 64 | # 7/ use COCO API to compute IoU 65 | not_crowd = [int(False)] * pred_xywh_boxes.shape[0] 66 | ious = COCOmask.iou(pred_xywh_boxes, np.array([gt_xywh_box]), not_crowd) 67 | np.testing.assert_array_almost_equal(ious, np.ones(ious.shape)) 68 | 69 | def test_cython_bbox_iou_against_coco_api_bbox_iou(self): 70 | """Check that our cython implementation of bounding box IoU overlap 71 | matches the COCO API implementation. 72 | """ 73 | def _do_test(b1, b2): 74 | # Compute IoU overlap with the cython implementation 75 | cython_iou = box_utils.bbox_overlaps(b1, b2) 76 | # Compute IoU overlap with the COCO API implementation 77 | # (requires converting boxes from xyxy to xywh format) 78 | xywh_b1 = box_utils.xyxy_to_xywh(b1) 79 | xywh_b2 = box_utils.xyxy_to_xywh(b2) 80 | not_crowd = [int(False)] * b2.shape[0] 81 | coco_ious = COCOmask.iou(xywh_b1, xywh_b2, not_crowd) 82 | # IoUs should be similar 83 | np.testing.assert_array_almost_equal( 84 | cython_iou, coco_ious, decimal=5 85 | ) 86 | 87 | # Test small boxes 88 | b1 = random_boxes([10, 10, 20, 20], 5, 10) 89 | b2 = random_boxes([10, 10, 20, 20], 5, 10) 90 | _do_test(b1, b2) 91 | 92 | # Test bigger boxes 93 | b1 = random_boxes([10, 10, 110, 20], 20, 10) 94 | b2 = random_boxes([10, 10, 110, 20], 20, 10) 95 | _do_test(b1, b2) 96 | 97 | 98 | if __name__ == '__main__': 99 | unittest.main() 100 | -------------------------------------------------------------------------------- /detectron/tests/test_loader.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import logging 15 | import unittest 16 | import mock 17 | 18 | from caffe2.proto import caffe2_pb2 19 | from caffe2.python import core 20 | from caffe2.python import muji 21 | from caffe2.python import workspace 22 | 23 | from detectron.core.config import assert_and_infer_cfg 24 | from detectron.core.config import cfg 25 | from detectron.roi_data.loader import RoIDataLoader 26 | import detectron.utils.logging as logging_utils 27 | 28 | 29 | def get_roidb_blobs(roidb): 30 | blobs = {} 31 | blobs['data'] = np.stack([entry['data'] for entry in roidb]) 32 | return blobs, True 33 | 34 | 35 | def get_net(data_loader, name): 36 | logger = logging.getLogger(__name__) 37 | blob_names = data_loader.get_output_names() 38 | net = core.Net(name) 39 | net.type = 'dag' 40 | for gpu_id in range(cfg.NUM_GPUS): 41 | with core.NameScope('gpu_{}'.format(gpu_id)): 42 | with core.DeviceScope(muji.OnGPU(gpu_id)): 43 | for blob_name in blob_names: 44 | blob = core.ScopedName(blob_name) 45 | workspace.CreateBlob(blob) 46 | net.DequeueBlobs( 47 | data_loader._blobs_queue_name, blob_names) 48 | logger.info("Protobuf:\n" + str(net.Proto())) 49 | 50 | return net 51 | 52 | 53 | def get_roidb_sample_data(sample_data): 54 | roidb = [] 55 | for _ in range(np.random.randint(4, 10)): 56 | roidb.append({'data': sample_data}) 57 | return roidb 58 | 59 | 60 | def create_loader_and_network(sample_data, name): 61 | roidb = get_roidb_sample_data(sample_data) 62 | loader = RoIDataLoader(roidb) 63 | net = get_net(loader, 'dequeue_net_train') 64 | loader.register_sigint_handler() 65 | loader.start(prefill=False) 66 | return loader, net 67 | 68 | 69 | def run_net(net): 70 | workspace.RunNetOnce(net) 71 | gpu_dev = core.DeviceOption(caffe2_pb2.CUDA, 0) 72 | name_scope = 'gpu_{}'.format(0) 73 | with core.NameScope(name_scope): 74 | with core.DeviceScope(gpu_dev): 75 | data = workspace.FetchBlob(core.ScopedName('data')) 76 | return data 77 | 78 | 79 | class TestRoIDataLoader(unittest.TestCase): 80 | @mock.patch( 81 | 'detectron.roi_data.loader.get_minibatch_blob_names', 82 | return_value=[u'data'] 83 | ) 84 | @mock.patch( 85 | 'detectron.roi_data.loader.get_minibatch', 86 | side_effect=get_roidb_blobs 87 | ) 88 | def test_two_parallel_loaders(self, _1, _2): 89 | train_data = np.random.rand(2, 3, 3).astype(np.float32) 90 | train_loader, train_net = create_loader_and_network(train_data, 91 | 'dequeue_net_train') 92 | test_data = np.random.rand(2, 4, 4).astype(np.float32) 93 | test_loader, test_net = create_loader_and_network(test_data, 94 | 'dequeue_net_test') 95 | for _ in range(5): 96 | data = run_net(train_net) 97 | self.assertEqual(data[0].tolist(), train_data.tolist()) 98 | data = run_net(test_net) 99 | self.assertEqual(data[0].tolist(), test_data.tolist()) 100 | test_loader.shutdown() 101 | train_loader.shutdown() 102 | 103 | 104 | if __name__ == '__main__': 105 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 106 | logger = logging_utils.setup_logging(__name__) 107 | logger.setLevel(logging.DEBUG) 108 | logging.getLogger('detectron.roi_data.loader').setLevel(logging.INFO) 109 | np.random.seed(cfg.RNG_SEED) 110 | cfg.TRAIN.ASPECT_GROUPING = False 111 | cfg.NUM_GPUS = 2 112 | assert_and_infer_cfg() 113 | unittest.main() 114 | -------------------------------------------------------------------------------- /detectron/tests/test_smooth_l1_loss_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.c2 as c2_utils 22 | import detectron.utils.logging as logging_utils 23 | 24 | 25 | class SmoothL1LossTest(unittest.TestCase): 26 | def test_forward_and_gradient(self): 27 | Y = np.random.randn(128, 4 * 21).astype(np.float32) 28 | Y_hat = np.random.randn(128, 4 * 21).astype(np.float32) 29 | inside_weights = np.random.randn(128, 4 * 21).astype(np.float32) 30 | inside_weights[inside_weights < 0] = 0 31 | outside_weights = np.random.randn(128, 4 * 21).astype(np.float32) 32 | outside_weights[outside_weights < 0] = 0 33 | scale = np.random.random() 34 | beta = np.random.random() 35 | 36 | op = core.CreateOperator( 37 | 'SmoothL1Loss', ['Y_hat', 'Y', 'inside_weights', 'outside_weights'], 38 | ['loss'], 39 | scale=scale, 40 | beta=beta 41 | ) 42 | 43 | gc = gradient_checker.GradientChecker( 44 | stepsize=0.005, 45 | threshold=0.005, 46 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 47 | ) 48 | 49 | res, grad, grad_estimated = gc.CheckSimple( 50 | op, [Y_hat, Y, inside_weights, outside_weights], 0, [0] 51 | ) 52 | 53 | self.assertTrue( 54 | grad.shape == grad_estimated.shape, 55 | 'Fail check: grad.shape != grad_estimated.shape' 56 | ) 57 | 58 | # To inspect the gradient and estimated gradient: 59 | # np.set_printoptions(precision=3, suppress=True) 60 | # print('grad:') 61 | # print(grad) 62 | # print('grad_estimated:') 63 | # print(grad_estimated) 64 | 65 | self.assertTrue(res) 66 | 67 | 68 | if __name__ == '__main__': 69 | c2_utils.import_detectron_ops() 70 | assert 'SmoothL1Loss' in workspace.RegisteredOperators() 71 | logging_utils.setup_logging(__name__) 72 | unittest.main() 73 | -------------------------------------------------------------------------------- /detectron/tests/test_spatial_narrow_as_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import gradient_checker 19 | from caffe2.python import workspace 20 | 21 | import detectron.utils.c2 as c2_utils 22 | import detectron.utils.logging as logging_utils 23 | 24 | 25 | class SpatialNarrowAsOpTest(unittest.TestCase): 26 | def _run_test(self, A, B, check_grad=False): 27 | with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 28 | op = core.CreateOperator('SpatialNarrowAs', ['A', 'B'], ['C']) 29 | workspace.FeedBlob('A', A) 30 | workspace.FeedBlob('B', B) 31 | workspace.RunOperatorOnce(op) 32 | C = workspace.FetchBlob('C') 33 | 34 | if check_grad: 35 | gc = gradient_checker.GradientChecker( 36 | stepsize=0.005, 37 | threshold=0.005, 38 | device_option=core.DeviceOption(caffe2_pb2.CUDA, 0) 39 | ) 40 | 41 | res, grad, grad_estimated = gc.CheckSimple(op, [A, B], 0, [0]) 42 | self.assertTrue(res, 'Grad check failed') 43 | 44 | dims = C.shape 45 | C_ref = A[:dims[0], :dims[1], :dims[2], :dims[3]] 46 | np.testing.assert_allclose(C, C_ref, rtol=1e-5, atol=1e-08) 47 | 48 | def test_small_forward_and_gradient(self): 49 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 50 | B = np.random.randn(2, 3, 2, 2).astype(np.float32) 51 | self._run_test(A, B, check_grad=True) 52 | 53 | A = np.random.randn(2, 3, 5, 7).astype(np.float32) 54 | B = np.random.randn(2, 3, 5).astype(np.float32) 55 | self._run_test(A, B, check_grad=True) 56 | 57 | def test_large_forward(self): 58 | A = np.random.randn(2, 256, 42, 100).astype(np.float32) 59 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 60 | self._run_test(A, B) 61 | 62 | A = np.random.randn(2, 256, 42, 87).astype(np.float32) 63 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 64 | self._run_test(A, B) 65 | 66 | def test_size_exceptions(self): 67 | A = np.random.randn(2, 256, 42, 86).astype(np.float32) 68 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 69 | with self.assertRaises(RuntimeError): 70 | self._run_test(A, B) 71 | 72 | A = np.random.randn(2, 255, 42, 88).astype(np.float32) 73 | B = np.random.randn(2, 256, 35, 87).astype(np.float32) 74 | with self.assertRaises(RuntimeError): 75 | self._run_test(A, B) 76 | 77 | 78 | if __name__ == '__main__': 79 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 80 | c2_utils.import_detectron_ops() 81 | assert 'SpatialNarrowAs' in workspace.RegisteredOperators() 82 | logging_utils.setup_logging(__name__) 83 | unittest.main() 84 | -------------------------------------------------------------------------------- /detectron/tests/test_zero_even_op.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################### 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | from __future__ import unicode_literals 12 | 13 | import numpy as np 14 | import unittest 15 | 16 | from caffe2.proto import caffe2_pb2 17 | from caffe2.python import core 18 | from caffe2.python import workspace 19 | 20 | import detectron.utils.c2 as c2_utils 21 | 22 | 23 | class ZeroEvenOpTest(unittest.TestCase): 24 | 25 | def _run_zero_even_op(self, X): 26 | op = core.CreateOperator('ZeroEven', ['X'], ['Y']) 27 | workspace.FeedBlob('X', X) 28 | workspace.RunOperatorOnce(op) 29 | Y = workspace.FetchBlob('Y') 30 | return Y 31 | 32 | def _run_zero_even_op_gpu(self, X): 33 | with core.DeviceScope(core.DeviceOption(caffe2_pb2.CUDA, 0)): 34 | op = core.CreateOperator('ZeroEven', ['X'], ['Y']) 35 | workspace.FeedBlob('X', X) 36 | workspace.RunOperatorOnce(op) 37 | Y = workspace.FetchBlob('Y') 38 | return Y 39 | 40 | def test_throws_on_non_1D_arrays(self): 41 | X = np.zeros((2, 2), dtype=np.float32) 42 | with self.assertRaisesRegexp(RuntimeError, 'X\.ndim\(\) == 1'): 43 | self._run_zero_even_op(X) 44 | 45 | def test_handles_empty_arrays(self): 46 | X = np.array([], dtype=np.float32) 47 | Y_exp = np.copy(X) 48 | Y_act = self._run_zero_even_op(X) 49 | np.testing.assert_allclose(Y_act, Y_exp) 50 | 51 | def test_sets_vals_at_even_inds_to_zero(self): 52 | X = np.array([0, 1, 2, 3, 4], dtype=np.float32) 53 | Y_exp = np.array([0, 1, 0, 3, 0], dtype=np.float32) 54 | Y_act = self._run_zero_even_op(X) 55 | np.testing.assert_allclose(Y_act[0::2], Y_exp[0::2]) 56 | 57 | def test_preserves_vals_at_odd_inds(self): 58 | X = np.array([0, 1, 2, 3, 4], dtype=np.float32) 59 | Y_exp = np.array([0, 1, 0, 3, 0], dtype=np.float32) 60 | Y_act = self._run_zero_even_op(X) 61 | np.testing.assert_allclose(Y_act[1::2], Y_exp[1::2]) 62 | 63 | def test_handles_even_length_arrays(self): 64 | X = np.random.rand(64).astype(np.float32) 65 | Y_exp = np.copy(X) 66 | Y_exp[0::2] = 0.0 67 | Y_act = self._run_zero_even_op(X) 68 | np.testing.assert_allclose(Y_act, Y_exp) 69 | 70 | def test_handles_odd_length_arrays(self): 71 | X = np.random.randn(77).astype(np.float32) 72 | Y_exp = np.copy(X) 73 | Y_exp[0::2] = 0.0 74 | Y_act = self._run_zero_even_op(X) 75 | np.testing.assert_allclose(Y_act, Y_exp) 76 | 77 | def test_gpu_throws_on_non_1D_arrays(self): 78 | X = np.zeros((2, 2), dtype=np.float32) 79 | with self.assertRaisesRegexp(RuntimeError, 'X\.ndim\(\) == 1'): 80 | self._run_zero_even_op_gpu(X) 81 | 82 | def test_gpu_handles_empty_arrays(self): 83 | X = np.array([], dtype=np.float32) 84 | Y_exp = np.copy(X) 85 | Y_act = self._run_zero_even_op_gpu(X) 86 | np.testing.assert_allclose(Y_act, Y_exp) 87 | 88 | def test_gpu_sets_vals_at_even_inds_to_zero(self): 89 | X = np.array([0, 1, 2, 3, 4], dtype=np.float32) 90 | Y_exp = np.array([0, 1, 0, 3, 0], dtype=np.float32) 91 | Y_act = self._run_zero_even_op_gpu(X) 92 | np.testing.assert_allclose(Y_act[0::2], Y_exp[0::2]) 93 | 94 | def test_gpu_preserves_vals_at_odd_inds(self): 95 | X = np.array([0, 1, 2, 3, 4], dtype=np.float32) 96 | Y_exp = np.array([0, 1, 0, 3, 0], dtype=np.float32) 97 | Y_act = self._run_zero_even_op_gpu(X) 98 | np.testing.assert_allclose(Y_act[1::2], Y_exp[1::2]) 99 | 100 | def test_gpu_handles_even_length_arrays(self): 101 | X = np.random.rand(64).astype(np.float32) 102 | Y_exp = np.copy(X) 103 | Y_exp[0::2] = 0.0 104 | Y_act = self._run_zero_even_op_gpu(X) 105 | np.testing.assert_allclose(Y_act, Y_exp) 106 | 107 | def test_gpu_handles_odd_length_arrays(self): 108 | X = np.random.randn(77).astype(np.float32) 109 | Y_exp = np.copy(X) 110 | Y_exp[0::2] = 0.0 111 | Y_act = self._run_zero_even_op_gpu(X) 112 | np.testing.assert_allclose(Y_act, Y_exp) 113 | 114 | 115 | if __name__ == '__main__': 116 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 117 | c2_utils.import_custom_ops() 118 | assert 'ZeroEven' in workspace.RegisteredOperators() 119 | unittest.main() 120 | -------------------------------------------------------------------------------- /detectron/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/facebookresearch/DensePose/51fb9f110a454c77b0c5acfa0c7cceb317f38aa1/detectron/utils/__init__.py -------------------------------------------------------------------------------- /detectron/utils/collections.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """A simple attribute dictionary used for representing configuration options.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | 16 | class AttrDict(dict): 17 | 18 | IMMUTABLE = '__immutable__' 19 | 20 | def __init__(self, *args, **kwargs): 21 | super(AttrDict, self).__init__(*args, **kwargs) 22 | self.__dict__[AttrDict.IMMUTABLE] = False 23 | 24 | def __getattr__(self, name): 25 | if name in self.__dict__: 26 | return self.__dict__[name] 27 | elif name in self: 28 | return self[name] 29 | else: 30 | raise AttributeError(name) 31 | 32 | def __setattr__(self, name, value): 33 | if not self.__dict__[AttrDict.IMMUTABLE]: 34 | if name in self.__dict__: 35 | self.__dict__[name] = value 36 | else: 37 | self[name] = value 38 | else: 39 | raise AttributeError( 40 | 'Attempted to set "{}" to "{}", but AttrDict is immutable'. 41 | format(name, value) 42 | ) 43 | 44 | def immutable(self, is_immutable): 45 | """Set immutability to is_immutable and recursively apply the setting 46 | to all nested AttrDicts. 47 | """ 48 | self.__dict__[AttrDict.IMMUTABLE] = is_immutable 49 | # Recursively set immutable state 50 | for v in self.__dict__.values(): 51 | if isinstance(v, AttrDict): 52 | v.immutable(is_immutable) 53 | for v in self.values(): 54 | if isinstance(v, AttrDict): 55 | v.immutable(is_immutable) 56 | 57 | def is_immutable(self): 58 | return self.__dict__[AttrDict.IMMUTABLE] 59 | -------------------------------------------------------------------------------- /detectron/utils/colormap.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """An awesome colormap for really neat visualizations.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import numpy as np 16 | 17 | 18 | def colormap(rgb=False): 19 | color_list = np.array( 20 | [ 21 | 0.000, 0.447, 0.741, 22 | 0.850, 0.325, 0.098, 23 | 0.929, 0.694, 0.125, 24 | 0.494, 0.184, 0.556, 25 | 0.466, 0.674, 0.188, 26 | 0.301, 0.745, 0.933, 27 | 0.635, 0.078, 0.184, 28 | 0.300, 0.300, 0.300, 29 | 0.600, 0.600, 0.600, 30 | 1.000, 0.000, 0.000, 31 | 1.000, 0.500, 0.000, 32 | 0.749, 0.749, 0.000, 33 | 0.000, 1.000, 0.000, 34 | 0.000, 0.000, 1.000, 35 | 0.667, 0.000, 1.000, 36 | 0.333, 0.333, 0.000, 37 | 0.333, 0.667, 0.000, 38 | 0.333, 1.000, 0.000, 39 | 0.667, 0.333, 0.000, 40 | 0.667, 0.667, 0.000, 41 | 0.667, 1.000, 0.000, 42 | 1.000, 0.333, 0.000, 43 | 1.000, 0.667, 0.000, 44 | 1.000, 1.000, 0.000, 45 | 0.000, 0.333, 0.500, 46 | 0.000, 0.667, 0.500, 47 | 0.000, 1.000, 0.500, 48 | 0.333, 0.000, 0.500, 49 | 0.333, 0.333, 0.500, 50 | 0.333, 0.667, 0.500, 51 | 0.333, 1.000, 0.500, 52 | 0.667, 0.000, 0.500, 53 | 0.667, 0.333, 0.500, 54 | 0.667, 0.667, 0.500, 55 | 0.667, 1.000, 0.500, 56 | 1.000, 0.000, 0.500, 57 | 1.000, 0.333, 0.500, 58 | 1.000, 0.667, 0.500, 59 | 1.000, 1.000, 0.500, 60 | 0.000, 0.333, 1.000, 61 | 0.000, 0.667, 1.000, 62 | 0.000, 1.000, 1.000, 63 | 0.333, 0.000, 1.000, 64 | 0.333, 0.333, 1.000, 65 | 0.333, 0.667, 1.000, 66 | 0.333, 1.000, 1.000, 67 | 0.667, 0.000, 1.000, 68 | 0.667, 0.333, 1.000, 69 | 0.667, 0.667, 1.000, 70 | 0.667, 1.000, 1.000, 71 | 1.000, 0.000, 1.000, 72 | 1.000, 0.333, 1.000, 73 | 1.000, 0.667, 1.000, 74 | 0.167, 0.000, 0.000, 75 | 0.333, 0.000, 0.000, 76 | 0.500, 0.000, 0.000, 77 | 0.667, 0.000, 0.000, 78 | 0.833, 0.000, 0.000, 79 | 1.000, 0.000, 0.000, 80 | 0.000, 0.167, 0.000, 81 | 0.000, 0.333, 0.000, 82 | 0.000, 0.500, 0.000, 83 | 0.000, 0.667, 0.000, 84 | 0.000, 0.833, 0.000, 85 | 0.000, 1.000, 0.000, 86 | 0.000, 0.000, 0.167, 87 | 0.000, 0.000, 0.333, 88 | 0.000, 0.000, 0.500, 89 | 0.000, 0.000, 0.667, 90 | 0.000, 0.000, 0.833, 91 | 0.000, 0.000, 1.000, 92 | 0.000, 0.000, 0.000, 93 | 0.143, 0.143, 0.143, 94 | 0.286, 0.286, 0.286, 95 | 0.429, 0.429, 0.429, 96 | 0.571, 0.571, 0.571, 97 | 0.714, 0.714, 0.714, 98 | 0.857, 0.857, 0.857, 99 | 1.000, 1.000, 1.000 100 | ] 101 | ).astype(np.float32) 102 | color_list = color_list.reshape((-1, 3)) * 255 103 | if not rgb: 104 | color_list = color_list[:, ::-1] 105 | return color_list 106 | -------------------------------------------------------------------------------- /detectron/utils/coordinator.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Coordinated access to a shared multithreading/processing queue.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import contextlib 16 | import logging 17 | import Queue 18 | import threading 19 | import traceback 20 | 21 | log = logging.getLogger(__name__) 22 | 23 | 24 | class Coordinator(object): 25 | 26 | def __init__(self): 27 | self._event = threading.Event() 28 | 29 | def request_stop(self): 30 | log.debug('Coordinator stopping') 31 | self._event.set() 32 | 33 | def should_stop(self): 34 | return self._event.is_set() 35 | 36 | def wait_for_stop(self): 37 | return self._event.wait() 38 | 39 | @contextlib.contextmanager 40 | def stop_on_exception(self): 41 | try: 42 | yield 43 | except Exception: 44 | if not self.should_stop(): 45 | traceback.print_exc() 46 | self.request_stop() 47 | 48 | 49 | def coordinated_get(coordinator, queue): 50 | while not coordinator.should_stop(): 51 | try: 52 | return queue.get(block=True, timeout=1.0) 53 | except Queue.Empty: 54 | continue 55 | raise Exception('Coordinator stopped during get()') 56 | 57 | 58 | def coordinated_put(coordinator, queue, element): 59 | while not coordinator.should_stop(): 60 | try: 61 | queue.put(element, block=True, timeout=1.0) 62 | return 63 | except Queue.Full: 64 | continue 65 | raise Exception('Coordinator stopped during put()') 66 | -------------------------------------------------------------------------------- /detectron/utils/cython_bbox.pyx: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2017-present, Facebook, Inc. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | ############################################################################## 15 | # 16 | # Based on: 17 | # -------------------------------------------------------- 18 | # Fast R-CNN 19 | # Copyright (c) 2015 Microsoft 20 | # Licensed under The MIT License [see LICENSE for details] 21 | # Written by Sergey Karayev 22 | # -------------------------------------------------------- 23 | 24 | cimport cython 25 | import numpy as np 26 | cimport numpy as np 27 | 28 | DTYPE = np.float32 29 | ctypedef np.float32_t DTYPE_t 30 | 31 | @cython.boundscheck(False) 32 | def bbox_overlaps( 33 | np.ndarray[DTYPE_t, ndim=2] boxes, 34 | np.ndarray[DTYPE_t, ndim=2] query_boxes): 35 | """ 36 | Parameters 37 | ---------- 38 | boxes: (N, 4) ndarray of float 39 | query_boxes: (K, 4) ndarray of float 40 | Returns 41 | ------- 42 | overlaps: (N, K) ndarray of overlap between boxes and query_boxes 43 | """ 44 | cdef unsigned int N = boxes.shape[0] 45 | cdef unsigned int K = query_boxes.shape[0] 46 | cdef np.ndarray[DTYPE_t, ndim=2] overlaps = np.zeros((N, K), dtype=DTYPE) 47 | cdef DTYPE_t iw, ih, box_area 48 | cdef DTYPE_t ua 49 | cdef unsigned int k, n 50 | with nogil: 51 | for k in range(K): 52 | box_area = ( 53 | (query_boxes[k, 2] - query_boxes[k, 0] + 1) * 54 | (query_boxes[k, 3] - query_boxes[k, 1] + 1) 55 | ) 56 | for n in range(N): 57 | iw = ( 58 | min(boxes[n, 2], query_boxes[k, 2]) - 59 | max(boxes[n, 0], query_boxes[k, 0]) + 1 60 | ) 61 | if iw > 0: 62 | ih = ( 63 | min(boxes[n, 3], query_boxes[k, 3]) - 64 | max(boxes[n, 1], query_boxes[k, 1]) + 1 65 | ) 66 | if ih > 0: 67 | ua = float( 68 | (boxes[n, 2] - boxes[n, 0] + 1) * 69 | (boxes[n, 3] - boxes[n, 1] + 1) + 70 | box_area - iw * ih 71 | ) 72 | overlaps[n, k] = iw * ih / ua 73 | return overlaps 74 | -------------------------------------------------------------------------------- /detectron/utils/env.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Environment helper functions.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import os 16 | import sys 17 | 18 | # Default value of the CMake install prefix 19 | _CMAKE_INSTALL_PREFIX = '/usr/local' 20 | 21 | 22 | def get_runtime_dir(): 23 | """Retrieve the path to the runtime directory.""" 24 | return sys.path[0] 25 | 26 | 27 | def get_py_bin_ext(): 28 | """Retrieve python binary extension.""" 29 | return '.py' 30 | 31 | 32 | def set_up_matplotlib(): 33 | """Set matplotlib up.""" 34 | import matplotlib 35 | # Use a non-interactive backend 36 | matplotlib.use('Agg') 37 | 38 | 39 | def exit_on_error(): 40 | """Exit from a detectron tool when there's an error.""" 41 | sys.exit(1) 42 | 43 | 44 | def import_nccl_ops(): 45 | """Import NCCL ops.""" 46 | # There is no need to load NCCL ops since the 47 | # NCCL dependency is built into the Caffe2 gpu lib 48 | pass 49 | 50 | 51 | def get_detectron_ops_lib(): 52 | """Retrieve Detectron ops library.""" 53 | # Candidate prefixes for the detectron ops lib path 54 | prefixes = [_CMAKE_INSTALL_PREFIX, sys.prefix, sys.exec_prefix] + sys.path 55 | # Search for detectron ops lib 56 | for prefix in prefixes: 57 | ops_path = os.path.join(prefix, 'lib/libcaffe2_detectron_ops_gpu.so') 58 | if os.path.exists(ops_path): 59 | # TODO(ilijar): Switch to using a logger 60 | print('Found Detectron ops lib: {}'.format(ops_path)) 61 | break 62 | assert os.path.exists(ops_path), \ 63 | ('Detectron ops lib not found; make sure that your Caffe2 ' 64 | 'version includes Detectron module') 65 | return ops_path 66 | 67 | 68 | def get_custom_ops_lib(): 69 | """Retrieve custom ops library.""" 70 | det_dir, _ = os.path.split(os.path.dirname(__file__)) 71 | root_dir, _ = os.path.split(det_dir) 72 | custom_ops_lib = os.path.join( 73 | root_dir, 'build/libcaffe2_detectron_custom_ops_gpu.so') 74 | assert os.path.exists(custom_ops_lib), \ 75 | 'Custom ops lib not found at \'{}\''.format(custom_ops_lib) 76 | return custom_ops_lib 77 | -------------------------------------------------------------------------------- /detectron/utils/image.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Image helper functions.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import cv2 16 | import numpy as np 17 | 18 | 19 | def aspect_ratio_rel(im, aspect_ratio): 20 | """Performs width-relative aspect ratio transformation.""" 21 | im_h, im_w = im.shape[:2] 22 | im_ar_w = int(round(aspect_ratio * im_w)) 23 | im_ar = cv2.resize(im, dsize=(im_ar_w, im_h)) 24 | return im_ar 25 | 26 | 27 | def aspect_ratio_abs(im, aspect_ratio): 28 | """Performs absolute aspect ratio transformation.""" 29 | im_h, im_w = im.shape[:2] 30 | im_area = im_h * im_w 31 | 32 | im_ar_w = np.sqrt(im_area * aspect_ratio) 33 | im_ar_h = np.sqrt(im_area / aspect_ratio) 34 | assert np.isclose(im_ar_w / im_ar_h, aspect_ratio) 35 | 36 | im_ar = cv2.resize(im, dsize=(int(im_ar_w), int(im_ar_h))) 37 | return im_ar 38 | -------------------------------------------------------------------------------- /detectron/utils/io.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """IO utilities.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import cPickle as pickle 16 | import hashlib 17 | import logging 18 | import os 19 | import re 20 | import sys 21 | import urllib2 22 | 23 | logger = logging.getLogger(__name__) 24 | 25 | 26 | def save_object(obj, file_name): 27 | """Save a Python object by pickling it.""" 28 | file_name = os.path.abspath(file_name) 29 | with open(file_name, 'wb') as f: 30 | pickle.dump(obj, f, pickle.HIGHEST_PROTOCOL) 31 | 32 | 33 | def cache_url(url_or_file, cache_dir): 34 | """Download the file specified by the URL to the cache_dir and return the 35 | path to the cached file. If the argument is not a URL, simply return it as 36 | is. 37 | """ 38 | is_url = re.match(r'^(?:http)s?://', url_or_file, re.IGNORECASE) is not None 39 | 40 | if not is_url: 41 | return url_or_file 42 | # 43 | url = url_or_file 44 | # 45 | Len_filename = len( url.split('/')[-1] ) 46 | BASE_URL = url[0:-Len_filename-1] 47 | # 48 | cache_file_path = url.replace(BASE_URL, cache_dir) 49 | if os.path.exists(cache_file_path): 50 | #assert_cache_file_is_ok(url, cache_file_path) 51 | return cache_file_path 52 | 53 | cache_file_dir = os.path.dirname(cache_file_path) 54 | if not os.path.exists(cache_file_dir): 55 | os.makedirs(cache_file_dir) 56 | 57 | logger.info('Downloading remote file {} to {}'.format(url, cache_file_path)) 58 | download_url(url, cache_file_path) 59 | #assert_cache_file_is_ok(url, cache_file_path) 60 | return cache_file_path 61 | 62 | 63 | def assert_cache_file_is_ok(url, file_path): 64 | """Check that cache file has the correct hash.""" 65 | # File is already in the cache, verify that the md5sum matches and 66 | # return local path 67 | cache_file_md5sum = _get_file_md5sum(file_path) 68 | ref_md5sum = _get_reference_md5sum(url) 69 | assert cache_file_md5sum == ref_md5sum, \ 70 | ('Target URL {} appears to be downloaded to the local cache file ' 71 | '{}, but the md5 hash of the local file does not match the ' 72 | 'reference (actual: {} vs. expected: {}). You may wish to delete ' 73 | 'the cached file and try again to trigger automatic ' 74 | 'download.').format(url, file_path, cache_file_md5sum, ref_md5sum) 75 | 76 | 77 | def _progress_bar(count, total): 78 | """Report download progress. 79 | Credit: 80 | https://stackoverflow.com/questions/3173320/text-progress-bar-in-the-console/27871113 81 | """ 82 | bar_len = 60 83 | filled_len = int(round(bar_len * count / float(total))) 84 | 85 | percents = round(100.0 * count / float(total), 1) 86 | bar = '=' * filled_len + '-' * (bar_len - filled_len) 87 | 88 | sys.stdout.write( 89 | ' [{}] {}% of {:.1f}MB file \r'. 90 | format(bar, percents, total / 1024 / 1024) 91 | ) 92 | sys.stdout.flush() 93 | if count >= total: 94 | sys.stdout.write('\n') 95 | 96 | 97 | def download_url( 98 | url, dst_file_path, chunk_size=8192, progress_hook=_progress_bar 99 | ): 100 | """Download url and write it to dst_file_path. 101 | Credit: 102 | https://stackoverflow.com/questions/2028517/python-urllib2-progress-hook 103 | """ 104 | response = urllib2.urlopen(url) 105 | total_size = response.info().getheader('Content-Length').strip() 106 | total_size = int(total_size) 107 | bytes_so_far = 0 108 | 109 | with open(dst_file_path, 'wb') as f: 110 | while 1: 111 | chunk = response.read(chunk_size) 112 | bytes_so_far += len(chunk) 113 | if not chunk: 114 | break 115 | if progress_hook: 116 | progress_hook(bytes_so_far, total_size) 117 | f.write(chunk) 118 | 119 | return bytes_so_far 120 | 121 | 122 | def _get_file_md5sum(file_name): 123 | """Compute the md5 hash of a file.""" 124 | hash_obj = hashlib.md5() 125 | with open(file_name, 'r') as f: 126 | hash_obj.update(f.read()) 127 | return hash_obj.hexdigest() 128 | 129 | 130 | def _get_reference_md5sum(url): 131 | """By convention the md5 hash for url is stored in url + '.md5sum'.""" 132 | url_md5sum = url + '.md5sum' 133 | md5sum = urllib2.urlopen(url_md5sum).read().strip() 134 | return md5sum 135 | -------------------------------------------------------------------------------- /detectron/utils/logging.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Utilities for logging.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | from collections import deque 16 | from email.mime.text import MIMEText 17 | import json 18 | import logging 19 | import numpy as np 20 | import smtplib 21 | import sys 22 | 23 | # Print lower precision floating point values than default FLOAT_REPR 24 | json.encoder.FLOAT_REPR = lambda o: format(o, '.6f') 25 | 26 | 27 | def log_json_stats(stats, sort_keys=True): 28 | print('json_stats: {:s}'.format(json.dumps(stats, sort_keys=sort_keys))) 29 | 30 | 31 | class SmoothedValue(object): 32 | """Track a series of values and provide access to smoothed values over a 33 | window or the global series average. 34 | """ 35 | 36 | def __init__(self, window_size): 37 | self.deque = deque(maxlen=window_size) 38 | self.series = [] 39 | self.total = 0.0 40 | self.count = 0 41 | 42 | def AddValue(self, value): 43 | self.deque.append(value) 44 | self.series.append(value) 45 | self.count += 1 46 | self.total += value 47 | 48 | def GetMedianValue(self): 49 | return np.median(self.deque) 50 | 51 | def GetAverageValue(self): 52 | return np.mean(self.deque) 53 | 54 | def GetGlobalAverageValue(self): 55 | return self.total / self.count 56 | 57 | 58 | def send_email(subject, body, to): 59 | s = smtplib.SMTP('localhost') 60 | mime = MIMEText(body) 61 | mime['Subject'] = subject 62 | mime['To'] = to 63 | s.sendmail('detectron', to, mime.as_string()) 64 | 65 | 66 | def setup_logging(name): 67 | FORMAT = '%(levelname)s %(filename)s:%(lineno)4d: %(message)s' 68 | # Manually clear root loggers to prevent any module that may have called 69 | # logging.basicConfig() from blocking our logging setup 70 | logging.root.handlers = [] 71 | logging.basicConfig(level=logging.INFO, format=FORMAT, stream=sys.stdout) 72 | logger = logging.getLogger(name) 73 | return logger 74 | -------------------------------------------------------------------------------- /detectron/utils/lr_policy.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Learning rate policies.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import numpy as np 16 | 17 | from detectron.core.config import cfg 18 | 19 | 20 | def get_lr_at_iter(it): 21 | """Get the learning rate at iteration it according to the cfg.SOLVER 22 | settings. 23 | """ 24 | lr = get_lr_func()(it) 25 | if it < cfg.SOLVER.WARM_UP_ITERS: 26 | method = cfg.SOLVER.WARM_UP_METHOD 27 | if method == 'constant': 28 | warmup_factor = cfg.SOLVER.WARM_UP_FACTOR 29 | elif method == 'linear': 30 | alpha = it / cfg.SOLVER.WARM_UP_ITERS 31 | warmup_factor = cfg.SOLVER.WARM_UP_FACTOR * (1 - alpha) + alpha 32 | else: 33 | raise KeyError('Unknown SOLVER.WARM_UP_METHOD: {}'.format(method)) 34 | lr *= warmup_factor 35 | return np.float32(lr) 36 | 37 | 38 | # ---------------------------------------------------------------------------- # 39 | # Learning rate policy functions 40 | # ---------------------------------------------------------------------------- # 41 | 42 | def lr_func_steps_with_lrs(cur_iter): 43 | """For cfg.SOLVER.LR_POLICY = 'steps_with_lrs' 44 | 45 | Change the learning rate to specified values at specified iterations. 46 | 47 | Example: 48 | cfg.SOLVER.MAX_ITER: 90 49 | cfg.SOLVER.STEPS: [0, 60, 80] 50 | cfg.SOLVER.LRS: [0.02, 0.002, 0.0002] 51 | for cur_iter in [0, 59] use 0.02 52 | in [60, 79] use 0.002 53 | in [80, inf] use 0.0002 54 | """ 55 | ind = get_step_index(cur_iter) 56 | return cfg.SOLVER.LRS[ind] 57 | 58 | 59 | def lr_func_steps_with_decay(cur_iter): 60 | """For cfg.SOLVER.LR_POLICY = 'steps_with_decay' 61 | 62 | Change the learning rate specified iterations based on the formula 63 | lr = base_lr * gamma ** lr_step_count. 64 | 65 | Example: 66 | cfg.SOLVER.MAX_ITER: 90 67 | cfg.SOLVER.STEPS: [0, 60, 80] 68 | cfg.SOLVER.BASE_LR: 0.02 69 | cfg.SOLVER.GAMMA: 0.1 70 | for cur_iter in [0, 59] use 0.02 = 0.02 * 0.1 ** 0 71 | in [60, 79] use 0.002 = 0.02 * 0.1 ** 1 72 | in [80, inf] use 0.0002 = 0.02 * 0.1 ** 2 73 | """ 74 | ind = get_step_index(cur_iter) 75 | return cfg.SOLVER.BASE_LR * cfg.SOLVER.GAMMA ** ind 76 | 77 | 78 | def lr_func_step(cur_iter): 79 | """For cfg.SOLVER.LR_POLICY = 'step' 80 | """ 81 | return ( 82 | cfg.SOLVER.BASE_LR * 83 | cfg.SOLVER.GAMMA ** (cur_iter // cfg.SOLVER.STEP_SIZE)) 84 | 85 | 86 | # ---------------------------------------------------------------------------- # 87 | # Helpers 88 | # ---------------------------------------------------------------------------- # 89 | 90 | def get_step_index(cur_iter): 91 | """Given an iteration, find which learning rate step we're at.""" 92 | assert cfg.SOLVER.STEPS[0] == 0, 'The first step should always start at 0.' 93 | steps = cfg.SOLVER.STEPS + [cfg.SOLVER.MAX_ITER] 94 | for ind, step in enumerate(steps): # NoQA 95 | if cur_iter < step: 96 | break 97 | return ind - 1 98 | 99 | 100 | def get_lr_func(): 101 | policy = 'lr_func_' + cfg.SOLVER.LR_POLICY 102 | if policy not in globals(): 103 | raise NotImplementedError( 104 | 'Unknown LR policy: {}'.format(cfg.SOLVER.LR_POLICY)) 105 | else: 106 | return globals()[policy] 107 | -------------------------------------------------------------------------------- /detectron/utils/timer.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | # 8 | # Based on: 9 | # -------------------------------------------------------- 10 | # Fast R-CNN 11 | # Copyright (c) 2015 Microsoft 12 | # Licensed under The MIT License [see LICENSE for details] 13 | # Written by Ross Girshick 14 | # -------------------------------------------------------- 15 | 16 | """Timing related functions.""" 17 | 18 | from __future__ import absolute_import 19 | from __future__ import division 20 | from __future__ import print_function 21 | from __future__ import unicode_literals 22 | 23 | import time 24 | 25 | 26 | class Timer(object): 27 | """A simple timer.""" 28 | 29 | def __init__(self): 30 | self.reset() 31 | 32 | def tic(self): 33 | # using time.time instead of time.clock because time time.clock 34 | # does not normalize for multithreading 35 | self.start_time = time.time() 36 | 37 | def toc(self, average=True): 38 | self.diff = time.time() - self.start_time 39 | self.total_time += self.diff 40 | self.calls += 1 41 | self.average_time = self.total_time / self.calls 42 | if average: 43 | return self.average_time 44 | else: 45 | return self.diff 46 | 47 | def reset(self): 48 | self.total_time = 0. 49 | self.calls = 0 50 | self.start_time = 0. 51 | self.diff = 0. 52 | self.average_time = 0. 53 | -------------------------------------------------------------------------------- /detectron/utils/training_stats.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Utilities for training.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import datetime 16 | import numpy as np 17 | 18 | from caffe2.python import utils as c2_py_utils 19 | 20 | from detectron.core.config import cfg 21 | from detectron.utils.logging import log_json_stats 22 | from detectron.utils.logging import SmoothedValue 23 | from detectron.utils.timer import Timer 24 | import detectron.utils.net as nu 25 | 26 | 27 | class TrainingStats(object): 28 | """Track vital training statistics.""" 29 | 30 | def __init__(self, model): 31 | # Window size for smoothing tracked values (with median filtering) 32 | self.WIN_SZ = 20 33 | # Output logging period in SGD iterations 34 | self.LOG_PERIOD = 20 35 | self.smoothed_losses_and_metrics = { 36 | key: SmoothedValue(self.WIN_SZ) 37 | for key in model.losses + model.metrics 38 | } 39 | self.losses_and_metrics = { 40 | key: 0 41 | for key in model.losses + model.metrics 42 | } 43 | self.smoothed_total_loss = SmoothedValue(self.WIN_SZ) 44 | self.smoothed_mb_qsize = SmoothedValue(self.WIN_SZ) 45 | self.iter_total_loss = np.nan 46 | self.iter_timer = Timer() 47 | self.model = model 48 | 49 | def IterTic(self): 50 | self.iter_timer.tic() 51 | 52 | def IterToc(self): 53 | return self.iter_timer.toc(average=False) 54 | 55 | def ResetIterTimer(self): 56 | self.iter_timer.reset() 57 | 58 | def UpdateIterStats(self): 59 | """Update tracked iteration statistics.""" 60 | for k in self.losses_and_metrics.keys(): 61 | if k in self.model.losses: 62 | self.losses_and_metrics[k] = nu.sum_multi_gpu_blob(k) 63 | else: 64 | self.losses_and_metrics[k] = nu.average_multi_gpu_blob(k) 65 | for k, v in self.smoothed_losses_and_metrics.items(): 66 | v.AddValue(self.losses_and_metrics[k]) 67 | self.iter_total_loss = np.sum( 68 | np.array([self.losses_and_metrics[k] for k in self.model.losses]) 69 | ) 70 | self.smoothed_total_loss.AddValue(self.iter_total_loss) 71 | self.smoothed_mb_qsize.AddValue( 72 | self.model.roi_data_loader._minibatch_queue.qsize() 73 | ) 74 | 75 | def LogIterStats(self, cur_iter, lr): 76 | """Log the tracked statistics.""" 77 | if (cur_iter % self.LOG_PERIOD == 0 or 78 | cur_iter == cfg.SOLVER.MAX_ITER - 1): 79 | stats = self.GetStats(cur_iter, lr) 80 | log_json_stats(stats) 81 | 82 | def GetStats(self, cur_iter, lr): 83 | eta_seconds = self.iter_timer.average_time * ( 84 | cfg.SOLVER.MAX_ITER - cur_iter 85 | ) 86 | eta = str(datetime.timedelta(seconds=int(eta_seconds))) 87 | mem_stats = c2_py_utils.GetGPUMemoryUsageStats() 88 | mem_usage = np.max(mem_stats['max_by_gpu'][:cfg.NUM_GPUS]) 89 | stats = dict( 90 | iter=cur_iter, 91 | lr=float(lr), 92 | time=self.iter_timer.average_time, 93 | loss=self.smoothed_total_loss.GetMedianValue(), 94 | eta=eta, 95 | mb_qsize=int( 96 | np.round(self.smoothed_mb_qsize.GetMedianValue()) 97 | ), 98 | mem=int(np.ceil(mem_usage / 1024 / 1024)) 99 | ) 100 | for k, v in self.smoothed_losses_and_metrics.items(): 101 | stats[k] = v.GetMedianValue() 102 | return stats 103 | -------------------------------------------------------------------------------- /docker/Dockerfile: -------------------------------------------------------------------------------- 1 | # Use Caffe2 image as parent image 2 | FROM caffe2/caffe2:snapshot-py2-cuda9.0-cudnn7-ubuntu16.04 3 | 4 | RUN mv /usr/local/caffe2 /usr/local/caffe2_build 5 | ENV Caffe2_DIR /usr/local/caffe2_build 6 | 7 | ENV PYTHONPATH /usr/local/caffe2_build:${PYTHONPATH} 8 | ENV LD_LIBRARY_PATH /usr/local/caffe2_build/lib:${LD_LIBRARY_PATH} 9 | 10 | # Clone the Detectron repository 11 | RUN git clone https://github.com/facebookresearch/densepose /densepose 12 | 13 | # Install Python dependencies 14 | RUN pip install -r /densepose/requirements.txt 15 | 16 | # Install the COCO API 17 | RUN git clone https://github.com/cocodataset/cocoapi.git /cocoapi 18 | WORKDIR /cocoapi/PythonAPI 19 | RUN make install 20 | 21 | # Go to Densepose root 22 | WORKDIR /densepose 23 | 24 | # Set up Python modules 25 | RUN make 26 | 27 | # [Optional] Build custom ops 28 | RUN make ops 29 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.13 2 | pyyaml>=3.12 3 | matplotlib 4 | opencv-python>=3.2 5 | setuptools 6 | Cython 7 | mock 8 | scipy 9 | h5py 10 | memory_profiler 11 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | from __future__ import absolute_import 9 | from __future__ import division 10 | from __future__ import print_function 11 | 12 | from Cython.Build import cythonize 13 | from setuptools import Extension 14 | from setuptools import setup 15 | 16 | import numpy as np 17 | 18 | _NP_INCLUDE_DIRS = np.get_include() 19 | 20 | 21 | # Extension modules 22 | ext_modules = [ 23 | Extension( 24 | name='detectron.utils.cython_bbox', 25 | sources=[ 26 | 'detectron/utils/cython_bbox.pyx' 27 | ], 28 | extra_compile_args=[ 29 | '-Wno-cpp' 30 | ], 31 | include_dirs=[ 32 | _NP_INCLUDE_DIRS 33 | ] 34 | ), 35 | Extension( 36 | name='detectron.utils.cython_nms', 37 | sources=[ 38 | 'detectron/utils/cython_nms.pyx' 39 | ], 40 | extra_compile_args=[ 41 | '-Wno-cpp' 42 | ], 43 | include_dirs=[ 44 | _NP_INCLUDE_DIRS 45 | ] 46 | ) 47 | ] 48 | 49 | setup( 50 | name='Detectron', 51 | packages=['detectron'], 52 | ext_modules=cythonize(ext_modules) 53 | ) 54 | -------------------------------------------------------------------------------- /tools/test_net.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Perform inference on one or more datasets.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cv2 # NOQA (Must import before importing caffe2 due to bug in cv2) 17 | import os 18 | import pprint 19 | import sys 20 | import time 21 | 22 | from caffe2.python import workspace 23 | 24 | from detectron.core.config import assert_and_infer_cfg 25 | from detectron.core.config import cfg 26 | from detectron.core.config import merge_cfg_from_file 27 | from detectron.core.config import merge_cfg_from_list 28 | from detectron.core.test_engine import run_inference 29 | from detectron.utils.logging import setup_logging 30 | import detectron.utils.c2 as c2_utils 31 | 32 | c2_utils.import_detectron_ops() 33 | c2_utils.import_custom_ops() 34 | 35 | 36 | #utils.c2.import_custom_ops() 37 | #utils.c2.import_detectron_ops() 38 | 39 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 40 | # thread safe and causes unwanted GPU memory allocations. 41 | cv2.ocl.setUseOpenCL(False) 42 | 43 | 44 | def parse_args(): 45 | parser = argparse.ArgumentParser(description='Test a Fast R-CNN network') 46 | parser.add_argument( 47 | '--cfg', 48 | dest='cfg_file', 49 | help='optional config file', 50 | default=None, 51 | type=str 52 | ) 53 | parser.add_argument( 54 | '--wait', 55 | dest='wait', 56 | help='wait until net file exists', 57 | default=True, 58 | type=bool 59 | ) 60 | parser.add_argument( 61 | '--vis', dest='vis', help='visualize detections', action='store_true' 62 | ) 63 | parser.add_argument( 64 | '--multi-gpu-testing', 65 | dest='multi_gpu_testing', 66 | help='using cfg.NUM_GPUS for inference', 67 | action='store_true' 68 | ) 69 | parser.add_argument( 70 | '--range', 71 | dest='range', 72 | help='start (inclusive) and end (exclusive) indices', 73 | default=None, 74 | type=int, 75 | nargs=2 76 | ) 77 | parser.add_argument( 78 | 'opts', 79 | help='See detectron/core/config.py for all options', 80 | default=None, 81 | nargs=argparse.REMAINDER 82 | ) 83 | if len(sys.argv) == 1: 84 | parser.print_help() 85 | sys.exit(1) 86 | return parser.parse_args() 87 | 88 | 89 | if __name__ == '__main__': 90 | workspace.GlobalInit(['caffe2', '--caffe2_log_level=0']) 91 | logger = setup_logging(__name__) 92 | args = parse_args() 93 | logger.info('Called with args:') 94 | logger.info(args) 95 | if args.cfg_file is not None: 96 | merge_cfg_from_file(args.cfg_file) 97 | if args.opts is not None: 98 | merge_cfg_from_list(args.opts) 99 | assert_and_infer_cfg() 100 | logger.info('Testing with config:') 101 | logger.info(pprint.pformat(cfg)) 102 | 103 | while not os.path.exists(cfg.TEST.WEIGHTS) and args.wait: 104 | logger.info('Waiting for \'{}\' to exist...'.format(cfg.TEST.WEIGHTS)) 105 | time.sleep(10) 106 | 107 | run_inference( 108 | cfg.TEST.WEIGHTS, 109 | ind_range=args.range, 110 | multi_gpu_testing=args.multi_gpu_testing, 111 | check_expected_results=True, 112 | ) 113 | -------------------------------------------------------------------------------- /tools/train_net.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Train a network with Detectron.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cv2 # NOQA (Must import before importing caffe2 due to bug in cv2) 17 | import logging 18 | import numpy as np 19 | import pprint 20 | import sys 21 | 22 | from caffe2.python import workspace 23 | 24 | from detectron.core.config import assert_and_infer_cfg 25 | from detectron.core.config import cfg 26 | from detectron.core.config import merge_cfg_from_file 27 | from detectron.core.config import merge_cfg_from_list 28 | from detectron.core.test_engine import run_inference 29 | from detectron.utils.logging import setup_logging 30 | import detectron.utils.c2 as c2_utils 31 | import detectron.utils.train 32 | 33 | c2_utils.import_contrib_ops() 34 | c2_utils.import_detectron_ops() 35 | c2_utils.import_custom_ops() 36 | 37 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 38 | # thread safe and causes unwanted GPU memory allocations. 39 | cv2.ocl.setUseOpenCL(False) 40 | 41 | 42 | def parse_args(): 43 | parser = argparse.ArgumentParser( 44 | description='Train a network with Detectron' 45 | ) 46 | parser.add_argument( 47 | '--cfg', 48 | dest='cfg_file', 49 | help='Config file for training (and optionally testing)', 50 | default=None, 51 | type=str 52 | ) 53 | parser.add_argument( 54 | '--multi-gpu-testing', 55 | dest='multi_gpu_testing', 56 | help='Use cfg.NUM_GPUS GPUs for inference', 57 | action='store_true' 58 | ) 59 | parser.add_argument( 60 | '--skip-test', 61 | dest='skip_test', 62 | help='Do not test the final model', 63 | action='store_true' 64 | ) 65 | parser.add_argument( 66 | 'opts', 67 | help='See detectron/core/config.py for all options', 68 | default=None, 69 | nargs=argparse.REMAINDER 70 | ) 71 | if len(sys.argv) == 1: 72 | parser.print_help() 73 | sys.exit(1) 74 | return parser.parse_args() 75 | 76 | 77 | def main(): 78 | # Initialize C2 79 | workspace.GlobalInit( 80 | ['caffe2', '--caffe2_log_level=0', '--caffe2_gpu_memory_tracking=1'] 81 | ) 82 | # Set up logging and load config options 83 | logger = setup_logging(__name__) 84 | logging.getLogger('detectron.roi_data.loader').setLevel(logging.INFO) 85 | args = parse_args() 86 | logger.info('Called with args:') 87 | logger.info(args) 88 | if args.cfg_file is not None: 89 | merge_cfg_from_file(args.cfg_file) 90 | if args.opts is not None: 91 | merge_cfg_from_list(args.opts) 92 | assert_and_infer_cfg() 93 | logger.info('Training with config:') 94 | logger.info(pprint.pformat(cfg)) 95 | # Note that while we set the numpy random seed network training will not be 96 | # deterministic in general. There are sources of non-determinism that cannot 97 | # be removed with a reasonble execution-speed tradeoff (such as certain 98 | # non-deterministic cudnn functions). 99 | np.random.seed(cfg.RNG_SEED) 100 | # Execute the training run 101 | checkpoints = detectron.utils.train.train_model() 102 | # Test the trained model 103 | if not args.skip_test: 104 | test_model(checkpoints['final'], args.multi_gpu_testing, args.opts) 105 | 106 | 107 | def test_model(model_file, multi_gpu_testing, opts=None): 108 | """Test a model.""" 109 | # Clear memory before inference 110 | workspace.ResetWorkspace() 111 | # Run inference 112 | run_inference( 113 | model_file, multi_gpu_testing=multi_gpu_testing, 114 | check_expected_results=True, 115 | ) 116 | 117 | 118 | if __name__ == '__main__': 119 | main() 120 | -------------------------------------------------------------------------------- /tools/visualize_results.py: -------------------------------------------------------------------------------- 1 | # Copyright (c) Facebook, Inc. and its affiliates. 2 | # All rights reserved. 3 | # 4 | # This source code is licensed under the license found in the 5 | # LICENSE file in the root directory of this source tree. 6 | ############################################################################## 7 | 8 | """Script for visualizing results saved in a detections.pkl file.""" 9 | 10 | from __future__ import absolute_import 11 | from __future__ import division 12 | from __future__ import print_function 13 | from __future__ import unicode_literals 14 | 15 | import argparse 16 | import cPickle as pickle 17 | import cv2 18 | import os 19 | import sys 20 | 21 | from detectron.datasets.json_dataset import JsonDataset 22 | import detectron.utils.vis as vis_utils 23 | 24 | # OpenCL may be enabled by default in OpenCV3; disable it because it's not 25 | # thread safe and causes unwanted GPU memory allocations. 26 | cv2.ocl.setUseOpenCL(False) 27 | 28 | 29 | def parse_args(): 30 | parser = argparse.ArgumentParser() 31 | parser.add_argument( 32 | '--dataset', 33 | dest='dataset', 34 | help='dataset', 35 | default='coco_2014_minival', 36 | type=str 37 | ) 38 | parser.add_argument( 39 | '--detections', 40 | dest='detections', 41 | help='detections pkl file', 42 | default='', 43 | type=str 44 | ) 45 | parser.add_argument( 46 | '--thresh', 47 | dest='thresh', 48 | help='detection prob threshold', 49 | default=0.9, 50 | type=float 51 | ) 52 | parser.add_argument( 53 | '--output-dir', 54 | dest='output_dir', 55 | help='output directory', 56 | default='./tmp/vis-output', 57 | type=str 58 | ) 59 | parser.add_argument( 60 | '--first', 61 | dest='first', 62 | help='only visualize the first k images', 63 | default=0, 64 | type=int 65 | ) 66 | if len(sys.argv) == 1: 67 | parser.print_help() 68 | sys.exit(1) 69 | args = parser.parse_args() 70 | return args 71 | 72 | 73 | def vis(dataset, detections_pkl, thresh, output_dir, limit=0): 74 | ds = JsonDataset(dataset) 75 | roidb = ds.get_roidb() 76 | 77 | with open(detections_pkl, 'r') as f: 78 | dets = pickle.load(f) 79 | 80 | assert all(k in dets for k in ['all_boxes', 'all_segms', 'all_keyps']), \ 81 | 'Expected detections pkl file in the format used by test_engine.py' 82 | 83 | all_boxes = dets['all_boxes'] 84 | all_segms = dets['all_segms'] 85 | all_keyps = dets['all_keyps'] 86 | 87 | def id_or_index(ix, val): 88 | if len(val) == 0: 89 | return val 90 | else: 91 | return val[ix] 92 | 93 | for ix, entry in enumerate(roidb): 94 | if limit > 0 and ix >= limit: 95 | break 96 | if ix % 10 == 0: 97 | print('{:d}/{:d}'.format(ix + 1, len(roidb))) 98 | 99 | im = cv2.imread(entry['image']) 100 | im_name = os.path.splitext(os.path.basename(entry['image']))[0] 101 | 102 | cls_boxes_i = [ 103 | id_or_index(ix, cls_k_boxes) for cls_k_boxes in all_boxes 104 | ] 105 | cls_segms_i = [ 106 | id_or_index(ix, cls_k_segms) for cls_k_segms in all_segms 107 | ] 108 | cls_keyps_i = [ 109 | id_or_index(ix, cls_k_keyps) for cls_k_keyps in all_keyps 110 | ] 111 | 112 | vis_utils.vis_one_image( 113 | im[:, :, ::-1], 114 | '{:d}_{:s}'.format(ix, im_name), 115 | os.path.join(output_dir, 'vis'), 116 | cls_boxes_i, 117 | segms=cls_segms_i, 118 | keypoints=cls_keyps_i, 119 | thresh=thresh, 120 | box_alpha=0.8, 121 | dataset=ds, 122 | show_class=True 123 | ) 124 | 125 | 126 | if __name__ == '__main__': 127 | opts = parse_args() 128 | vis( 129 | opts.dataset, 130 | opts.detections, 131 | opts.thresh, 132 | opts.output_dir, 133 | limit=opts.first 134 | ) 135 | --------------------------------------------------------------------------------