PawanratRung commited on
Commit
6759c69
·
verified ·
1 Parent(s): 6f9bbab

Create chart_output_to_chart_result.py

Browse files
3rdparty/densepose/converters/chart_output_to_chart_result.py ADDED
@@ -0,0 +1,183 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Copyright (c) Facebook, Inc. and its affiliates.
2
+
3
+ from typing import Dict
4
+ import torch
5
+ from torch.nn import functional as F
6
+
7
+ from detectron2.structures.boxes import Boxes, BoxMode
8
+
9
+ from ..structures import (
10
+ DensePoseChartPredictorOutput,
11
+ DensePoseChartResult,
12
+ DensePoseChartResultWithConfidences,
13
+ )
14
+ from . import resample_fine_and_coarse_segm_to_bbox
15
+ from .base import IntTupleBox, make_int_box
16
+
17
+
18
+ def resample_uv_tensors_to_bbox(
19
+ u: torch.Tensor,
20
+ v: torch.Tensor,
21
+ labels: torch.Tensor,
22
+ box_xywh_abs: IntTupleBox,
23
+ ) -> torch.Tensor:
24
+ """
25
+ Resamples U and V coordinate estimates for the given bounding box
26
+ Args:
27
+ u (tensor [1, C, H, W] of float): U coordinates
28
+ v (tensor [1, C, H, W] of float): V coordinates
29
+ labels (tensor [H, W] of long): labels obtained by resampling segmentation
30
+ outputs for the given bounding box
31
+ box_xywh_abs (tuple of 4 int): bounding box that corresponds to predictor outputs
32
+ Return:
33
+ Resampled U and V coordinates - a tensor [2, H, W] of float
34
+ """
35
+ x, y, w, h = box_xywh_abs
36
+ w = max(int(w), 1)
37
+ h = max(int(h), 1)
38
+ u_bbox = F.interpolate(u, (h, w), mode="bilinear", align_corners=False)
39
+ v_bbox = F.interpolate(v, (h, w), mode="bilinear", align_corners=False)
40
+ uv = torch.zeros([2, h, w], dtype=torch.float32, device=u.device)
41
+ for part_id in range(1, u_bbox.size(1)):
42
+ uv[0][labels == part_id] = u_bbox[0, part_id][labels == part_id]
43
+ uv[1][labels == part_id] = v_bbox[0, part_id][labels == part_id]
44
+ return uv
45
+
46
+
47
+ def resample_uv_to_bbox(
48
+ predictor_output: DensePoseChartPredictorOutput,
49
+ labels: torch.Tensor,
50
+ box_xywh_abs: IntTupleBox,
51
+ ) -> torch.Tensor:
52
+ """
53
+ Resamples U and V coordinate estimates for the given bounding box
54
+ Args:
55
+ predictor_output (DensePoseChartPredictorOutput): DensePose predictor
56
+ output to be resampled
57
+ labels (tensor [H, W] of long): labels obtained by resampling segmentation
58
+ outputs for the given bounding box
59
+ box_xywh_abs (tuple of 4 int): bounding box that corresponds to predictor outputs
60
+ Return:
61
+ Resampled U and V coordinates - a tensor [2, H, W] of float
62
+ """
63
+ return resample_uv_tensors_to_bbox(
64
+ predictor_output.u,
65
+ predictor_output.v,
66
+ labels,
67
+ box_xywh_abs,
68
+ )
69
+
70
+
71
+ def densepose_chart_predictor_output_to_result(
72
+ predictor_output: DensePoseChartPredictorOutput, boxes: Boxes
73
+ ) -> DensePoseChartResult:
74
+ """
75
+ Convert densepose chart predictor outputs to results
76
+ Args:
77
+ predictor_output (DensePoseChartPredictorOutput): DensePose predictor
78
+ output to be converted to results, must contain only 1 output
79
+ boxes (Boxes): bounding box that corresponds to the predictor output,
80
+ must contain only 1 bounding box
81
+ Return:
82
+ DensePose chart-based result (DensePoseChartResult)
83
+ """
84
+ assert len(predictor_output) == 1 and len(boxes) == 1, (
85
+ f"Predictor output to result conversion can operate only single outputs"
86
+ f", got {len(predictor_output)} predictor outputs and {len(boxes)} boxes"
87
+ )
88
+
89
+ boxes_xyxy_abs = boxes.tensor.clone()
90
+ boxes_xywh_abs = BoxMode.convert(boxes_xyxy_abs, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS)
91
+ box_xywh = make_int_box(boxes_xywh_abs[0])
92
+
93
+ labels = resample_fine_and_coarse_segm_to_bbox(predictor_output, box_xywh).squeeze(0)
94
+ uv = resample_uv_to_bbox(predictor_output, labels, box_xywh)
95
+ return DensePoseChartResult(labels=labels, uv=uv)
96
+
97
+
98
+ def resample_confidences_to_bbox(
99
+ predictor_output: DensePoseChartPredictorOutput,
100
+ labels: torch.Tensor,
101
+ box_xywh_abs: IntTupleBox,
102
+ ) -> Dict[str, torch.Tensor]:
103
+ """
104
+ Resamples confidences for the given bounding box
105
+ Args:
106
+ predictor_output (DensePoseChartPredictorOutput): DensePose predictor
107
+ output to be resampled
108
+ labels (tensor [H, W] of long): labels obtained by resampling segmentation
109
+ outputs for the given bounding box
110
+ box_xywh_abs (tuple of 4 int): bounding box that corresponds to predictor outputs
111
+ Return:
112
+ Resampled confidences - a dict of [H, W] tensors of float
113
+ """
114
+
115
+ x, y, w, h = box_xywh_abs
116
+ w = max(int(w), 1)
117
+ h = max(int(h), 1)
118
+
119
+ confidence_names = [
120
+ "sigma_1",
121
+ "sigma_2",
122
+ "kappa_u",
123
+ "kappa_v",
124
+ "fine_segm_confidence",
125
+ "coarse_segm_confidence",
126
+ ]
127
+ confidence_results = {key: None for key in confidence_names}
128
+ confidence_names = [
129
+ key for key in confidence_names if getattr(predictor_output, key) is not None
130
+ ]
131
+ confidence_base = torch.zeros([h, w], dtype=torch.float32, device=predictor_output.u.device)
132
+
133
+ # assign data from channels that correspond to the labels
134
+ for key in confidence_names:
135
+ resampled_confidence = F.interpolate(
136
+ getattr(predictor_output, key),
137
+ (h, w),
138
+ mode="bilinear",
139
+ align_corners=False,
140
+ )
141
+ result = confidence_base.clone()
142
+ for part_id in range(1, predictor_output.u.size(1)):
143
+ if resampled_confidence.size(1) != predictor_output.u.size(1):
144
+ # confidence is not part-based, don't try to fill it part by part
145
+ continue
146
+ result[labels == part_id] = resampled_confidence[0, part_id][labels == part_id]
147
+
148
+ if resampled_confidence.size(1) != predictor_output.u.size(1):
149
+ # confidence is not part-based, fill the data with the first channel
150
+ # (targeted for segmentation confidences that have only 1 channel)
151
+ result = resampled_confidence[0, 0]
152
+
153
+ confidence_results[key] = result
154
+
155
+ return confidence_results # pyre-ignore[7]
156
+
157
+
158
+ def densepose_chart_predictor_output_to_result_with_confidences(
159
+ predictor_output: DensePoseChartPredictorOutput, boxes: Boxes
160
+ ) -> DensePoseChartResultWithConfidences:
161
+ """
162
+ Convert densepose chart predictor outputs to results
163
+ Args:
164
+ predictor_output (DensePoseChartPredictorOutput): DensePose predictor
165
+ output with confidences to be converted to results, must contain only 1 output
166
+ boxes (Boxes): bounding box that corresponds to the predictor output,
167
+ must contain only 1 bounding box
168
+ Return:
169
+ DensePose chart-based result with confidences (DensePoseChartResultWithConfidences)
170
+ """
171
+ assert len(predictor_output) == 1 and len(boxes) == 1, (
172
+ f"Predictor output to result conversion can operate only single outputs"
173
+ f", got {len(predictor_output)} predictor outputs and {len(boxes)} boxes"
174
+ )
175
+
176
+ boxes_xyxy_abs = boxes.tensor.clone()
177
+ boxes_xywh_abs = BoxMode.convert(boxes_xyxy_abs, BoxMode.XYXY_ABS, BoxMode.XYWH_ABS)
178
+ box_xywh = make_int_box(boxes_xywh_abs[0])
179
+
180
+ labels = resample_fine_and_coarse_segm_to_bbox(predictor_output, box_xywh).squeeze(0)
181
+ uv = resample_uv_to_bbox(predictor_output, labels, box_xywh)
182
+ confidences = resample_confidences_to_bbox(predictor_output, labels, box_xywh)
183
+ return DensePoseChartResultWithConfidences(labels=labels, uv=uv, **confidences)