|
|
|
import numpy as np
|
|
from typing import Optional, Tuple
|
|
import cv2
|
|
|
|
from densepose.structures import DensePoseDataRelative
|
|
|
|
from ..structures import DensePoseChartPredictorOutput
|
|
from .base import Boxes, Image, MatrixVisualizer
|
|
|
|
|
|
class DensePoseOutputsVisualizer:
|
|
def __init__(
|
|
self, inplace=True, cmap=cv2.COLORMAP_PARULA, alpha=0.7, to_visualize=None, **kwargs
|
|
):
|
|
assert to_visualize in "IUV", "can only visualize IUV"
|
|
self.to_visualize = to_visualize
|
|
|
|
if self.to_visualize == "I":
|
|
val_scale = 255.0 / DensePoseDataRelative.N_PART_LABELS
|
|
else:
|
|
val_scale = 1.0
|
|
self.mask_visualizer = MatrixVisualizer(
|
|
inplace=inplace, cmap=cmap, val_scale=val_scale, alpha=alpha
|
|
)
|
|
|
|
def visualize(
|
|
self,
|
|
image_bgr: Image,
|
|
dp_output_with_bboxes: Tuple[Optional[DensePoseChartPredictorOutput], Optional[Boxes]],
|
|
) -> Image:
|
|
densepose_output, bboxes_xywh = dp_output_with_bboxes
|
|
if densepose_output is None or bboxes_xywh is None:
|
|
return image_bgr
|
|
|
|
assert isinstance(
|
|
densepose_output, DensePoseChartPredictorOutput
|
|
), "DensePoseChartPredictorOutput expected, {} encountered".format(type(densepose_output))
|
|
|
|
S = densepose_output.coarse_segm
|
|
I = densepose_output.fine_segm
|
|
U = densepose_output.u
|
|
V = densepose_output.v
|
|
N = S.size(0)
|
|
assert N == I.size(
|
|
0
|
|
), "densepose outputs S {} and I {}" " should have equal first dim size".format(
|
|
S.size(), I.size()
|
|
)
|
|
assert N == U.size(
|
|
0
|
|
), "densepose outputs S {} and U {}" " should have equal first dim size".format(
|
|
S.size(), U.size()
|
|
)
|
|
assert N == V.size(
|
|
0
|
|
), "densepose outputs S {} and V {}" " should have equal first dim size".format(
|
|
S.size(), V.size()
|
|
)
|
|
assert N == len(
|
|
bboxes_xywh
|
|
), "number of bounding boxes {}" " should be equal to first dim size of outputs {}".format(
|
|
len(bboxes_xywh), N
|
|
)
|
|
for n in range(N):
|
|
Sn = S[n].argmax(dim=0)
|
|
In = I[n].argmax(dim=0) * (Sn > 0).long()
|
|
segmentation = In.cpu().numpy().astype(np.uint8)
|
|
mask = np.zeros(segmentation.shape, dtype=np.uint8)
|
|
mask[segmentation > 0] = 1
|
|
bbox_xywh = bboxes_xywh[n]
|
|
|
|
if self.to_visualize == "I":
|
|
vis = segmentation
|
|
elif self.to_visualize in "UV":
|
|
U_or_Vn = {"U": U, "V": V}[self.to_visualize][n].cpu().numpy().astype(np.float32)
|
|
vis = np.zeros(segmentation.shape, dtype=np.float32)
|
|
for partId in range(U_or_Vn.shape[0]):
|
|
vis[segmentation == partId] = (
|
|
U_or_Vn[partId][segmentation == partId].clip(0, 1) * 255
|
|
)
|
|
|
|
|
|
image_bgr = self.mask_visualizer.visualize(image_bgr, mask, vis, bbox_xywh)
|
|
|
|
return image_bgr
|
|
|
|
|
|
class DensePoseOutputsUVisualizer(DensePoseOutputsVisualizer):
|
|
def __init__(self, inplace=True, cmap=cv2.COLORMAP_PARULA, alpha=0.7, **kwargs):
|
|
super().__init__(inplace=inplace, cmap=cmap, alpha=alpha, to_visualize="U", **kwargs)
|
|
|
|
|
|
class DensePoseOutputsVVisualizer(DensePoseOutputsVisualizer):
|
|
def __init__(self, inplace=True, cmap=cv2.COLORMAP_PARULA, alpha=0.7, **kwargs):
|
|
super().__init__(inplace=inplace, cmap=cmap, alpha=alpha, to_visualize="V", **kwargs)
|
|
|
|
|
|
class DensePoseOutputsFineSegmentationVisualizer(DensePoseOutputsVisualizer):
|
|
def __init__(self, inplace=True, cmap=cv2.COLORMAP_PARULA, alpha=0.7, **kwargs):
|
|
super().__init__(inplace=inplace, cmap=cmap, alpha=alpha, to_visualize="I", **kwargs)
|
|
|