Skip to content
Merged

V2.3.1 #2168

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion deeplabcut/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
visualize_paf,
extract_save_all_maps,
export_model,
video_inference_superanimal
video_inference_superanimal,
)


Expand Down
1 change: 0 additions & 1 deletion deeplabcut/benchmark/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ def calc_prediction_errors(preds, gt):
return errors



def _map(strings, substrings):
"""
Map image paths from predicted data to GT as the first are typically
Expand Down
2 changes: 1 addition & 1 deletion deeplabcut/create_project/add.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ def add_new_videos(
A list of strings containing the full paths of the videos to include in the project.

copy_videos : bool, optional
If this is set to True, the videos will be copied to your project/videos directory. If False, the symlink of the
If this is set to True, the videos will be copied to your project/videos directory. If False, the symlink of the
videos will be copied instead. The default is
``False``; if provided it must be either ``True`` or ``False``.

Expand Down
21 changes: 13 additions & 8 deletions deeplabcut/gui/tabs/modelzoo.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,11 @@ def _set_page(self):
supermodels = parse_available_supermodels()
self.model_combo.addItems(supermodels.keys())

scales_label = QtWidgets.QLabel('Scale list')
scales_label = QtWidgets.QLabel("Scale list")
self.scales_line = QtWidgets.QLineEdit("", parent=self)
self.scales_line.setPlaceholderText("Optionally input a list of integer sizes separated by commas...")
self.scales_line.setPlaceholderText(
"Optionally input a list of integer sizes separated by commas..."
)
validator = RegExpValidator(self._val_pattern, self)
validator.validationChanged.connect(self._handle_validation_change)
self.scales_line.setValidator(validator)
Expand All @@ -66,13 +68,13 @@ def _set_page(self):

def _handle_validation_change(self, state):
if state == RegExpValidator.Invalid:
color = 'red'
color = "red"
elif state == RegExpValidator.Intermediate:
color = 'gold'
color = "gold"
elif state == RegExpValidator.Acceptable:
color = 'lime'
self.scales_line.setStyleSheet(f'border: 1px solid {color}')
QTimer.singleShot(500, lambda: self.scales_line.setStyleSheet(''))
color = "lime"
self.scales_line.setStyleSheet(f"border: 1px solid {color}")
QTimer.singleShot(500, lambda: self.scales_line.setStyleSheet(""))

def run_video_adaptation(self):
videos = list(self.files)
Expand All @@ -89,7 +91,10 @@ def run_video_adaptation(self):
scales = []
scales_ = self.scales_line.text()
if scales_:
if (self.scales_line.validator().validate(scales_, 0)[0] == RegExpValidator.Acceptable):
if (
self.scales_line.validator().validate(scales_, 0)[0]
== RegExpValidator.Acceptable
):
scales = list(map(int, scales_.split(",")))
supermodel_name = self.model_combo.currentText()
videotype = self.video_selection_widget.videotype_widget.currentText()
Expand Down
18 changes: 9 additions & 9 deletions deeplabcut/modelzoo/api/spatiotemporal_adapt.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,9 @@ def __init__(
"""
supermodels = parse_available_supermodels()
if supermodel_name not in supermodels:
raise ValueError(f"`supermodel_name` should be one of: {', '.join(supermodels)}.")
raise ValueError(
f"`supermodel_name` should be one of: {', '.join(supermodels)}."
)

self.video_path = video_path
self.supermodel_name = supermodel_name
Expand All @@ -85,9 +87,7 @@ def __init__(
else:
self.customized_pose_config = customized_pose_config

def before_adapt_inference(self,
make_video=False,
**kwargs):
def before_adapt_inference(self, make_video=False, **kwargs):
if self.init_weights != "":
_ = superanimal_inference.video_inference(
[self.video_path],
Expand All @@ -114,7 +114,7 @@ def before_adapt_inference(self,
init_weights=self.init_weights,
draw_skeleton=True,
superanimal_name=self.supermodel_name,
**kwargs
**kwargs,
)

def train_without_project(self, pseudo_label_path, **kwargs):
Expand All @@ -131,7 +131,7 @@ def train_without_project(self, pseudo_label_path, **kwargs):
init_weights=self.init_weights,
pseudo_labels=pseudo_label_path,
video_path=self.video_path,
**kwargs
**kwargs,
)

def adaptation_training(self, displayiters=500, saveiters=1000, **kwargs):
Expand Down Expand Up @@ -174,7 +174,7 @@ def after_adapt_inference(self, **kwargs):

# spatial pyramid is not for adapted model

scale_list = kwargs.pop('scale_list', [])
scale_list = kwargs.pop("scale_list", [])
_, datafiles = superanimal_inference.video_inference(
[self.video_path],
self.supermodel_name,
Expand All @@ -184,7 +184,7 @@ def after_adapt_inference(self, **kwargs):
customized_test_config=self.customized_pose_config,
)

if kwargs.pop('plot_trajectories', True):
if kwargs.pop("plot_trajectories", True):
_plot_trajectories(datafiles[0])

deeplabcut.create_labeled_video(
Expand All @@ -195,5 +195,5 @@ def after_adapt_inference(self, **kwargs):
init_weights=adapt_weights,
draw_skeleton=True,
superanimal_name=self.supermodel_name,
**kwargs
**kwargs,
)
29 changes: 12 additions & 17 deletions deeplabcut/modelzoo/api/superanimal_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@

from deeplabcut.modelzoo.utils import parse_available_supermodels
from deeplabcut.pose_estimation_tensorflow.config import load_config
from deeplabcut.pose_estimation_tensorflow.core import \
predict as single_predict
from deeplabcut.pose_estimation_tensorflow.core import \
predict_multianimal as predict
from deeplabcut.pose_estimation_tensorflow.core import predict as single_predict
from deeplabcut.pose_estimation_tensorflow.core import predict_multianimal as predict
from deeplabcut.utils import auxiliaryfunctions
from deeplabcut.utils.auxfun_videos import VideoWriter
from dlclibrary.dlcmodelzoo.modelzoo_download import (
Expand Down Expand Up @@ -91,7 +89,7 @@ def _average_multiple_scale_preds(

# Compute cosine similarity
mean_vec = np.nanmedian(xy, axis=0)
dist_ = np.einsum('ijk,jk->ij', xy, mean_vec)
dist_ = np.einsum("ijk,jk->ij", xy, mean_vec)
n = np.linalg.norm(xy, axis=2) * np.linalg.norm(mean_vec, axis=1)
dist = np.nan_to_num(dist_ / n)

Expand All @@ -103,8 +101,8 @@ def _average_multiple_scale_preds(
coords = np.nanmedian(xyp[..., :2], axis=0)
conf = np.nanmedian(xyp[..., 2], axis=0)
dict_ = {
'coordinates': [list(coords[:, None])],
'confidence': list(conf[:, None].astype(np.float32)),
"coordinates": [list(coords[:, None])],
"confidence": list(conf[:, None].astype(np.float32)),
}
return dict_

Expand Down Expand Up @@ -277,39 +275,36 @@ def video_inference(
else:
test_cfg = load_config(customized_test_config)


# add a temp folder for checkpoint

weight_folder = superanimal_name + '_weights'
weight_folder = superanimal_name + "_weights"

if superanimal_name in MODELOPTIONS:
if not os.path.exists(weight_folder):
download_huggingface_model(superanimal_name, weight_folder)
else:
print (f"{weight_folder} exists, using the downloaded weights")
print(f"{weight_folder} exists, using the downloaded weights")
else:
print (f'{superanimal_name} not available. Available ones are: ', MODELOPTIONS)
print(f"{superanimal_name} not available. Available ones are: ", MODELOPTIONS)

snapshots = glob.glob(
os.path.join(weight_folder, 'snapshot-*.index')
)
snapshots = glob.glob(os.path.join(weight_folder, "snapshot-*.index"))

test_cfg["partaffinityfield_graph"] = []
test_cfg["partaffinityfield_predict"] = False

if init_weights != "":
test_cfg["init_weights"] = init_weights
else:
init_weights = os.path.abspath(snapshots[0]).replace('.index', '')
test_cfg['init_weights'] = init_weights
init_weights = os.path.abspath(snapshots[0]).replace(".index", "")
test_cfg["init_weights"] = init_weights

test_cfg["num_outputs"] = 1
test_cfg["batch_size"] = batchsize

sess, inputs, outputs = single_predict.setup_pose_prediction(
test_cfg, allow_growth=allow_growth
)
DLCscorer = "DLC_" + Path(test_cfg['init_weights']).stem
DLCscorer = "DLC_" + Path(test_cfg["init_weights"]).stem
videos = auxiliaryfunctions.get_list_of_videos(videos, videotype)

datafiles = []
Expand Down
5 changes: 2 additions & 3 deletions deeplabcut/modelzoo/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@

def parse_available_supermodels():
import deeplabcut

dlc_path = deeplabcut.utils.auxiliaryfunctions.get_deeplabcut_path()
json_path = os.path.join(
dlc_path, "modelzoo", "models.json"
)
json_path = os.path.join(dlc_path, "modelzoo", "models.json")
with open(json_path) as file:
return json.load(file)
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def make_batch(self, data_item, scale, mirror):

def compute_target_part_scoremap(self, joint_id, coords, data_item, size, scale):
dist_thresh = self.cfg["pos_dist_thresh"] * scale
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2
num_joints = self.cfg["num_joints"]
scmap = np.zeros(np.concatenate([size, np.array([num_joints])]))
locref_size = np.concatenate([size, np.array([num_joints * 2])])
Expand Down Expand Up @@ -260,7 +260,7 @@ def compute_target_part_scoremap(self, joint_id, coords, data_item, size, scale)
pt_x = i * self.stride + self.half_stride
dx = j_x - pt_x
dy = j_y - pt_y
dist = dx ** 2 + dy ** 2
dist = dx**2 + dy**2
# print(la.norm(diff))
if dist <= dist_thresh_sq:
scmap[j, i, j_id] = 1
Expand Down
8 changes: 4 additions & 4 deletions deeplabcut/pose_estimation_tensorflow/datasets/pose_imgaug.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ def gaussian_scmap(self, joint_id, coords, data_item, size, scale):
width = size[1]
height = size[0]
dist_thresh = float((width + height) / 6)
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2

std = dist_thresh / 4
# Grid of coordinates
Expand All @@ -503,7 +503,7 @@ def gaussian_scmap(self, joint_id, coords, data_item, size, scale):
map_j = grid.copy()
# Distance between the joint point and each coordinate
dist = np.linalg.norm(grid - (j_y, j_x), axis=2) ** 2
scmap_j = np.exp(-dist / (2 * (std ** 2)))
scmap_j = np.exp(-dist / (2 * (std**2)))
scmap[..., j_id] = scmap_j
locref_mask[dist <= dist_thresh_sq, j_id * 2 + 0] = 1
locref_mask[dist <= dist_thresh_sq, j_id * 2 + 1] = 1
Expand All @@ -528,7 +528,7 @@ def compute_target_part_scoremap_numpy(
self, joint_id, coords, data_item, size, scale
):
dist_thresh = float(self.cfg["pos_dist_thresh"] * scale)
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2
num_joints = self.cfg["num_joints"]

scmap = np.zeros(np.concatenate([size, np.array([num_joints])]))
Expand All @@ -555,7 +555,7 @@ def compute_target_part_scoremap_numpy(
y = grid.copy()[:, :, 0]
dx = j_x - x * self.stride - self.half_stride
dy = j_y - y * self.stride - self.half_stride
dist = dx ** 2 + dy ** 2
dist = dx**2 + dy**2
mask1 = dist <= dist_thresh_sq
mask2 = (x >= min_x) & (x <= max_x)
mask3 = (y >= min_y) & (y <= max_y)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -595,7 +595,7 @@ def compute_target_part_scoremap_numpy(
locref_size = *size, num_joints * 2
locref_map = np.zeros(locref_size)
locref_scale = 1.0 / self.cfg["locref_stdev"]
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2

partaffinityfield_shape = *size, self.cfg["num_limbs"] * 2
partaffinityfield_map = np.zeros(partaffinityfield_shape)
Expand All @@ -621,7 +621,7 @@ def compute_target_part_scoremap_numpy(
dx_ = dx * locref_scale
dy = coords[:, 1] - yy * stride - half_stride
dy_ = dy * locref_scale
dist = dx ** 2 + dy ** 2
dist = dx**2 + dy**2
mask1 = dist <= dist_thresh_sq
mask2 = (xx >= mins[:, 0]) & (xx <= maxs[:, 0])
mask3 = (yy >= mins[:, 1]) & (yy <= maxs[:, 1])
Expand Down Expand Up @@ -728,7 +728,7 @@ def gaussian_scmap(self, joint_id, coords, data_item, size, scale):
locref_map = np.zeros(locref_size)

locref_scale = 1.0 / self.cfg["locref_stdev"]
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2

partaffinityfield_shape = np.concatenate(
[size, np.array([self.cfg["num_limbs"] * 2])]
Expand Down Expand Up @@ -760,7 +760,7 @@ def gaussian_scmap(self, joint_id, coords, data_item, size, scale):
map_j = grid.copy()
# Distance between the joint point and each coordinate
dist = np.linalg.norm(grid - (j_y, j_x), axis=2) ** 2
scmap_j = np.exp(-dist / (2 * (std ** 2)))
scmap_j = np.exp(-dist / (2 * (std**2)))
scmap[..., j_id] = scmap_j
locref_mask[dist <= dist_thresh_sq, j_id * 2 + 0] = 1
locref_mask[dist <= dist_thresh_sq, j_id * 2 + 1] = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -351,7 +351,7 @@ def compute_target_part_scoremap(self, components):
locref_map = np.zeros(locref_size)

locref_scale = 1.0 / self.cfg["locref_stdev"]
dist_thresh_sq = dist_thresh ** 2
dist_thresh_sq = dist_thresh**2

width = size[1]
height = size[0]
Expand All @@ -376,7 +376,7 @@ def compute_target_part_scoremap(self, components):
pt_x = i * stride + half_stride
dx = j_x - pt_x
dy = j_y - pt_y
dist = dx ** 2 + dy ** 2
dist = dx**2 + dy**2
# print(la.norm(diff))
if dist <= dist_thresh_sq:
scmap[j, i, j_id] = 1
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,7 @@ def calc_link_probability(self, link):
ind = _conv_square_to_condensed_indices(i, j, self.n_multibodyparts)
mu = self._kde.mean[ind]
sigma = self._kde.covariance[ind, ind]
z = (link.length ** 2 - mu) / sigma
z = (link.length**2 - mu) / sigma
return 2 * (1 - 0.5 * (1 + erf(abs(z) / sqrt(2))))

@staticmethod
Expand Down
4 changes: 2 additions & 2 deletions deeplabcut/pose_estimation_tensorflow/nnets/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -86,8 +86,8 @@ def get_batch_spec(cfg):
def make_2d_gaussian_kernel(sigma, size):
sigma = tf.convert_to_tensor(sigma, dtype=tf.float32)
k = tf.range(-size // 2 + 1, size // 2 + 1)
k = tf.cast(k ** 2, sigma.dtype)
k = tf.nn.softmax(-k / (2 * (sigma ** 2)))
k = tf.cast(k**2, sigma.dtype)
k = tf.nn.softmax(-k / (2 * (sigma**2)))
return tf.einsum("i,j->ij", k, k)


Expand Down
3 changes: 2 additions & 1 deletion deeplabcut/pose_estimation_tensorflow/predict_supermodel.py
Original file line number Diff line number Diff line change
Expand Up @@ -77,5 +77,6 @@ def video_inference_superanimal(
adapter.before_adapt_inference(make_video=False)
adapter.adaptation_training()
adapter.after_adapt_inference(
pcutoff=pcutoff, plot_trajectories=plot_trajectories,
pcutoff=pcutoff,
plot_trajectories=plot_trajectories,
)
2 changes: 1 addition & 1 deletion deeplabcut/pose_estimation_tensorflow/util/visualize.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ def _npcircle(image, cx, cy, radius, color, transparency=0.0):
cx = int(cx)
cy = int(cy)
y, x = np.ogrid[-radius:radius, -radius:radius]
index = x ** 2 + y ** 2 <= radius ** 2
index = x**2 + y**2 <= radius**2
image[cy - radius : cy + radius, cx - radius : cx + radius][index] = (
image[cy - radius : cy + radius, cx - radius : cx + radius][index].astype(
"float32"
Expand Down
2 changes: 1 addition & 1 deletion deeplabcut/pose_estimation_tensorflow/visualizemaps.py
Original file line number Diff line number Diff line change
Expand Up @@ -339,7 +339,7 @@ def visualize_paf(image, paf, step=5, colors=None):
V = paf[:, :, n, 1]
X, Y = np.meshgrid(np.arange(U.shape[1]), np.arange(U.shape[0]))
M = np.zeros(U.shape, dtype=bool)
M[U ** 2 + V ** 2 < 0.5 * 0.5 ** 2] = True
M[U**2 + V**2 < 0.5 * 0.5**2] = True
U = np.ma.masked_array(U, mask=M)
V = np.ma.masked_array(V, mask=M)
ax.quiver(
Expand Down
4 changes: 2 additions & 2 deletions deeplabcut/pose_tracking_pytorch/tracking_utils/metrics.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ def eval_func(distmat, q_pids, g_pids, q_camids, g_camids, max_rank=50):
max_rank = num_g
print("Note: number of gallery samples is quite small, got {}".format(num_g))
indices = np.argsort(distmat, axis=1)
# 0 2 1 3
# 1 2 3 0
# 0, 2, 1, 3
# 1, 2, 3, 0
matches = (g_pids[indices] == q_pids[:, np.newaxis]).astype(np.int32)
# compute cmc curve for each query
all_cmc = []
Expand Down
Loading