Visitar URL original
Robustness fix: Annotation file not dropping likelihood column if present from machine labels by C-Achard · Pull Request #3323 · DeepLabCut/DeepLabCut · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
35 changes: 34 additions & 1 deletion deeplabcut/generate_training_dataset/trainingsetmanipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -728,22 +728,54 @@ def to_matlab_cell(array):
outer[0, 0] = array.astype("int64")
return outer

# Keep only x/y columns if likelihood is present
if isinstance(df.columns, pd.MultiIndex):
coord_level = "coords" if "coords" in df.columns.names else df.columns.names[-1]
coord_values = df.columns.get_level_values(coord_level)

has_x = "x" in coord_values
has_y = "y" in coord_values
has_likelihood = "likelihood" in coord_values

if has_x and has_y:
if has_likelihood:
logging.info(
"Detected likelihood columns in training data; dropping them before formatting training dataset."
)
df = df.loc[:, coord_values.isin(["x", "y"])]
else:
raise ValueError(
f"Training data must contain x/y coordinates. Found coordinate labels: {list(pd.unique(coord_values))}"
)

for i in train_inds:
data = dict()
filename = df.index[i]
data["image"] = filename
img_shape = read_image_shape_fast(os.path.join(project_path, *filename))
data["size"] = img_shape
temp = df.iloc[i].values.reshape(-1, 2)

row = df.iloc[i].values

if row.size % 2 != 0:
raise ValueError(
"Training data row does not contain an even number of coordinate values "
f"after dropping non-coordinate columns. Row size={row.size}, "
f"image={filename}"
)

temp = row.reshape(-1, 2)
joints = np.c_[range(nbodyparts), temp]
joints = joints[~np.isnan(joints).any(axis=1)].astype(int)

# Check that points lie within the image
inside = np.logical_and(
np.logical_and(joints[:, 1] < img_shape[2], joints[:, 1] > 0),
np.logical_and(joints[:, 2] < img_shape[1], joints[:, 2] > 0),
)
if not all(inside):
joints = joints[inside]

if joints.size: # Exclude images without labels
data["joints"] = joints
train_data.append(data)
Expand All @@ -754,6 +786,7 @@ def to_matlab_cell(array):
to_matlab_cell(data["joints"]),
)
)

matlab_data = np.asarray(matlab_data, dtype=[("image", "O"), ("size", "O"), ("joints", "O")])
return train_data, matlab_data

Expand Down
59 changes: 59 additions & 0 deletions tests/test_trainingsetmanipulation.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,3 +108,62 @@ def test_format_multianimal_training_data(monkeypatch):
def test_parse_video_filenames(videos: list[str], expected_filenames: list[str]):
filenames = parse_video_filenames(videos)
assert filenames == expected_filenames


def test_format_training_data_ignores_likelihood_columns(monkeypatch):
fake_shape = 3, 480, 640
monkeypatch.setattr(
trainingsetmanipulation,
"read_image_shape_fast",
lambda _: fake_shape,
)

# Base single-animal dataframe (x/y only)
df = pd.read_hdf(os.path.join(TEST_DATA_DIR, "trimouse_calib.h5")).xs(
"mus1",
level="individuals",
axis=1,
)
guarantee_multiindex_rows(df)

# Add a likelihood column so the layout becomes:
# x, y, likelihood, x, y, likelihood, ...
new_cols = []
new_arrays = []

coord_level = df.columns.names.index("coords")

for col in df.columns:
new_cols.append(col)
new_arrays.append(df[col].to_numpy())

if col[coord_level] == "y":
lik_col = list(col)
lik_col[coord_level] = "likelihood"
new_cols.append(tuple(lik_col))
new_arrays.append(np.ones(len(df), dtype=float))

df_with_likelihood = pd.DataFrame(
np.column_stack(new_arrays),
index=df.index,
columns=pd.MultiIndex.from_tuples(new_cols, names=df.columns.names),
)

train_inds = list(range(10))

baseline_train_data, baseline_matlab_data = format_training_data(df, train_inds, 12, "")
train_data, matlab_data = format_training_data(df_with_likelihood, train_inds, 12, "")

# The presence of likelihood columns should not change the formatted result
assert len(train_data) == len(baseline_train_data)
assert len(matlab_data) == len(baseline_matlab_data)

for got, expected in zip(train_data, baseline_train_data, strict=False):
assert got["image"] == expected["image"]
assert got["size"] == expected["size"]
assert np.array_equal(got["joints"], expected["joints"])

for got, expected in zip(matlab_data, baseline_matlab_data, strict=False):
assert np.array_equal(got["image"], expected["image"])
assert np.array_equal(got["size"], expected["size"])
assert np.array_equal(got["joints"][0, 0], expected["joints"][0, 0])
Loading