Spaces:
Sleeping
Sleeping
# Apply Net | |
`apply_net` is a tool to print or visualize DensePose results on a set of images. | |
It has two modes: `dump` to save DensePose model results to a pickle file | |
and `show` to visualize them on images. | |
The `image.jpg` file that is used as an example in this doc can be found [here](http://images.cocodataset.org/train2017/000000117508.jpg) | |
## Dump Mode | |
The general command form is: | |
```bash | |
python apply_net.py dump [-h] [-v] [--output <dump_file>] <config> <model> <input> | |
``` | |
There are three mandatory arguments: | |
- `<config>`, configuration file for a given model; | |
- `<model>`, model file with trained parameters | |
- `<input>`, input image file name, pattern or folder | |
One can additionally provide `--output` argument to define the output file name, | |
which defaults to `output.pkl`. | |
Examples: | |
1. Dump results of the [R_50_FPN_s1x](https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl) DensePose model for images in a folder `images` to file `dump.pkl`: | |
```bash | |
python apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
images --output dump.pkl -v | |
``` | |
2. Dump results of the [R_50_FPN_s1x](https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl) DensePose model for images with file name matching a pattern `image*.jpg` to file `results.pkl`: | |
```bash | |
python apply_net.py dump configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
"image*.jpg" --output results.pkl -v | |
``` | |
If you want to load the pickle file generated by the above command: | |
``` | |
# make sure DensePose is in your PYTHONPATH, or use the following line to add it: | |
sys.path.append("/your_detectron2_path/detectron2_repo/projects/DensePose/") | |
f = open('/your_result_path/results.pkl', 'rb') | |
data = pickle.load(f) | |
``` | |
The file `results.pkl` contains the list of results per image, for each image the result is a dictionary. | |
**If you use a [IUV model](DENSEPOSE_IUV.md#-model-zoo-and-baselines)**, the dumped data will have the following format: | |
``` | |
data: [{'file_name': '/your_path/image1.jpg', | |
'scores': tensor([0.9884]), | |
'pred_boxes_XYXY': tensor([[ 69.6114, 0.0000, 706.9797, 706.0000]]), | |
'pred_densepose': [DensePoseChartResultWithConfidences(labels=tensor(...), uv=tensor(...), sigma_1=None, | |
sigma_2=None, kappa_u=None, kappa_v=None, fine_segm_confidence=None, coarse_segm_confidence=None), | |
DensePoseChartResultWithConfidences, ...] | |
} | |
{'file_name': '/your_path/image2.jpg', | |
'scores': tensor([0.9999, 0.5373, 0.3991]), | |
'pred_boxes_XYXY': tensor([[ 59.5734, 7.7535, 579.9311, 932.3619], | |
[612.9418, 686.1254, 612.9999, 704.6053], | |
[164.5081, 407.4034, 598.3944, 920.4266]]), | |
'pred_densepose': [DensePoseChartResultWithConfidences(labels=tensor(...), uv=tensor(...), sigma_1=None, | |
sigma_2=None, kappa_u=None, kappa_v=None, fine_segm_confidence=None, coarse_segm_confidence=None), | |
DensePoseChartResultWithConfidences, ...] | |
}] | |
``` | |
`DensePoseChartResultWithConfidences` contains the following fields: | |
- `labels` - a tensor of size `[H, W]` of type `torch.long` which contains fine segmentation labels (previously called `I`) | |
- `uv` - a tensor of size `[2, H, W]` of type `torch.float` which contains `U` and `V` coordinates | |
- various optional confidence-related fields (`sigma_1`, `sigma_2`, `kappa_u`, `kappa_v`, `fine_segm_confidence`, `coarse_segm_confidence`) | |
**If you use a [CSE model](DENSEPOSE_CSE.md#-model-zoo-and-baselines)**, the dumped data will have the following format: | |
``` | |
data: [{'file_name': '/your_path/image1.jpg', | |
'scores': tensor([0.9984, 0.9961]), | |
'pred_boxes_XYXY': tensor([[480.0093, 461.0796, 698.3614, 696.1011], | |
[78.1589, 168.6614, 307.1287, 653.8522]]), | |
'pred_densepose': DensePoseEmbeddingPredictorOutput(embedding=tensor(...), coarse_segm=tensor(...))} | |
{'file_name': '/your_path/image2.jpg', | |
'scores': tensor([0.9189, 0.9491]), | |
'pred_boxes_XYXY': tensor([[734.9685, 534.2003, 287.3923, 254.8859], | |
[434.2853, 765.1219, 132.1029, 867.9283]]), | |
'pred_densepose': DensePoseEmbeddingPredictorOutput(embedding=tensor(...), coarse_segm=tensor(...))}] | |
``` | |
`DensePoseEmbeddingPredictorOutput` contains the following fields: | |
- `embedding` - a tensor of size `[N, D, sz, sz]` of type `torch.float`, which contains embeddings of size `D` of the `N` detections in the image | |
- `coarse_segm` - a tensor of size `[N, 2, sz, sz]` of type `torch.float` which contains segmentation scores of the `N` detections in the image; e.g. a mask can be obtained by `coarse_segm.argmax(dim=1)` | |
`sz` is a fixed size for the tensors; you can resize them to the size of the bounding box, if needed | |
We can use the following code, to parse the outputs of the first | |
detected instance on the first image (IUV model). | |
``` | |
img_id, instance_id = 0, 0 # Look at the first image and the first detected instance | |
bbox_xyxy = data[img_id]['pred_boxes_XYXY'][instance_id] | |
result = data[img_id]['pred_densepose'][instance_id] | |
uv = result.uv | |
``` | |
The array `bbox_xyxy` contains (x0, y0, x1, y1) of the bounding box. | |
## Visualization Mode | |
The general command form is: | |
```bash | |
python apply_net.py show [-h] [-v] [--min_score <score>] [--nms_thresh <threshold>] [--output <image_file>] <config> <model> <input> <visualizations> | |
``` | |
There are four mandatory arguments: | |
- `<config>`, configuration file for a given model; | |
- `<model>`, model file with trained parameters | |
- `<input>`, input image file name, pattern or folder | |
- `<visualizations>`, visualizations specifier; currently available visualizations are: | |
* `bbox` - bounding boxes of detected persons; | |
* `dp_segm` - segmentation masks for detected persons; | |
* `dp_u` - each body part is colored according to the estimated values of the | |
U coordinate in part parameterization; | |
* `dp_v` - each body part is colored according to the estimated values of the | |
V coordinate in part parameterization; | |
* `dp_contour` - plots contours with color-coded U and V coordinates; | |
* `dp_iuv_texture` - transfers the texture from a given texture image file to detected instances, in IUV mode; | |
* `dp_vertex` - plots the rainbow visualization of the closest vertices prediction for a given mesh, in CSE mode; | |
* `dp_cse_texture` - transfers the texture from a given list of texture image files (one from each human or animal mesh) to detected instances, in CSE mode | |
One can additionally provide the following optional arguments: | |
- `--min_score` to only show detections with sufficient scores that are not lower than provided value | |
- `--nms_thresh` to additionally apply non-maximum suppression to detections at a given threshold | |
- `--output` to define visualization file name template, which defaults to `output.png`. | |
To distinguish output file names for different images, the tool appends 1-based entry index, | |
e.g. output.0001.png, output.0002.png, etc... | |
- `--texture_atlas` to define the texture atlas image for IUV texture transfer | |
- `--texture_atlases_map` to define the texture atlas images map (a dictionary `{mesh name: texture atlas image}`) for CSE texture transfer | |
The following examples show how to output results of a DensePose model | |
with ResNet-50 FPN backbone using different visualizations for image `image.jpg`: | |
1. Show bounding box and segmentation: | |
```bash | |
python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
image.jpg bbox,dp_segm -v | |
``` | |
 | |
2. Show bounding box and estimated U coordinates for body parts: | |
```bash | |
python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
image.jpg bbox,dp_u -v | |
``` | |
 | |
3. Show bounding box and estimated V coordinates for body parts: | |
```bash | |
python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
image.jpg bbox,dp_v -v | |
``` | |
 | |
4. Show bounding box and estimated U and V coordinates via contour plots: | |
```bash | |
python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
image.jpg dp_contour,bbox -v | |
``` | |
 | |
5. Show bounding box and texture transfer: | |
```bash | |
python apply_net.py show configs/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/densepose_rcnn_R_50_FPN_s1x/165712039/model_final_162be9.pkl \ | |
image.jpg dp_iuv_texture,bbox --texture_atlas texture_from_SURREAL.jpg -v | |
``` | |
 | |
6. Show bounding box and CSE rainbow visualization: | |
```bash | |
python apply_net.py show configs/cse/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/cse/densepose_rcnn_R_50_FPN_s1x/251155172/model_final_c4ea5f.pkl \ | |
image.jpg dp_vertex,bbox -v | |
``` | |
 | |
7. Show bounding box and CSE texture transfer: | |
```bash | |
python apply_net.py show configs/cse/densepose_rcnn_R_50_FPN_s1x.yaml \ | |
https://dl.fbaipublicfiles.com/densepose/cse/densepose_rcnn_R_50_FPN_s1x/251155172/model_final_c4ea5f.pkl \ | |
image.jpg dp_cse_texture,bbox --texture_atlases_map '{"smpl_27554": "smpl_uvSnapshot_colors.jpg"}' -v | |
``` | |
 | |
The texture files can be found in the `doc/images` folder | |