Alex Chan
initial commit
999c5c9
"""
DeepLabCut Toolbox (deeplabcut.org)
© A. & M. Mathis Labs
Licensed under GNU Lesser General Public License v3.0
"""
import numpy as np
def extract_cnn_output(outputs, cfg):
"""
Extract location refinement and score map from DeepLabCut network
Parameters
-----------
outputs : list
List of outputs from DeepLabCut network.
Requires 2 entries:
index 0 is output from Sigmoid
index 1 is output from pose/locref_pred/block4/BiasAdd
cfg : dict
Dictionary read from the pose_cfg.yaml file for the network.
Returns
--------
scmap : ?
score map
locref : ?
location refinement
"""
scmap = outputs[0]
scmap = np.squeeze(scmap)
locref = None
if cfg["location_refinement"]:
locref = np.squeeze(outputs[1])
shape = locref.shape
locref = np.reshape(locref, (shape[0], shape[1], -1, 2))
locref *= cfg["locref_stdev"]
if len(scmap.shape) == 2: # for single body part!
scmap = np.expand_dims(scmap, axis=2)
return scmap, locref
def argmax_pose_predict(scmap, offmat, stride):
"""
Combines score map and offsets to the final pose
Parameters
-----------
scmap : ?
score map
offmat : ?
offsets
stride : ?
?
Returns
--------
pose :class:`numpy.ndarray`
pose as a numpy array
"""
num_joints = scmap.shape[2]
pose = []
for joint_idx in range(num_joints):
maxloc = np.unravel_index(
np.argmax(scmap[:, :, joint_idx]), scmap[:, :, joint_idx].shape
)
offset = np.array(offmat[maxloc][joint_idx])[::-1]
pos_f8 = np.array(maxloc).astype("float") * stride + 0.5 * stride + offset
pose.append(np.hstack((pos_f8[::-1], [scmap[maxloc][joint_idx]])))
return np.array(pose)
def get_top_values(scmap, n_top=5):
batchsize, ny, nx, num_joints = scmap.shape
scmap_flat = scmap.reshape(batchsize, nx * ny, num_joints)
if n_top == 1:
scmap_top = np.argmax(scmap_flat, axis=1)[None]
else:
scmap_top = np.argpartition(scmap_flat, -n_top, axis=1)[:, -n_top:]
for ix in range(batchsize):
vals = scmap_flat[ix, scmap_top[ix], np.arange(num_joints)]
arg = np.argsort(-vals, axis=0)
scmap_top[ix] = scmap_top[ix, arg, np.arange(num_joints)]
scmap_top = scmap_top.swapaxes(0, 1)
Y, X = np.unravel_index(scmap_top, (ny, nx))
return Y, X
def multi_pose_predict(scmap, locref, stride, num_outputs):
Y, X = get_top_values(scmap[None], num_outputs)
Y, X = Y[:, 0], X[:, 0]
num_joints = scmap.shape[2]
DZ = np.zeros((num_outputs, num_joints, 3))
for m in range(num_outputs):
for k in range(num_joints):
x = X[m, k]
y = Y[m, k]
DZ[m, k, :2] = locref[y, x, k, :]
DZ[m, k, 2] = scmap[y, x, k]
X = X.astype("float32") * stride + 0.5 * stride + DZ[:, :, 0]
Y = Y.astype("float32") * stride + 0.5 * stride + DZ[:, :, 1]
P = DZ[:, :, 2]
pose = np.empty((num_joints, num_outputs * 3), dtype="float32")
pose[:, 0::3] = X.T
pose[:, 1::3] = Y.T
pose[:, 2::3] = P.T
return pose