Visitar URL original
`InferenceRunner` + `analyze_videos`: Fix top-down analysis crashing for zero-detections and unreadable video handling by deruyter92 · Pull Request #3488 · DeepLabCut/DeepLabCut · GitHub
Skip to content
Merged
Changes from 1 commit
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
64a2f4e
fix _generate_output_data crash on empty predictions
deruyter92 Sep 8, 2026
510090e
Allow create_df_from_prediction() to handle an empty predictions list.
deruyter92 Sep 8, 2026
4b45fb9
Treat zero predictions as a distinct warning case in `video_inference()`
deruyter92 Sep 8, 2026
c78f439
Don't write dataframe for empty predictions
deruyter92 Sep 9, 2026
16a2977
update test_videos: pop `"PAFinds"` before comparison
deruyter92 Sep 9, 2026
f534de6
update test_videos: assert no DF is written for empty predictions
deruyter92 Sep 9, 2026
624b1b1
Return empty-detection inference results
C-Achard Sep 9, 2026
c57dd35
Use CTD predictions for video output
C-Achard Sep 9, 2026
4e4dab7
Handle empty prediction outputs gracefully
C-Achard Sep 9, 2026
42098ac
Reuse shared frame key width helper
C-Achard Sep 9, 2026
292d068
Clarify video inference warnings
C-Achard Sep 9, 2026
d5ba290
Go back to ValueError for empty predictions
C-Achard Sep 9, 2026
bff4fea
Remove NaN fallback for empty video predictions
C-Achard Sep 9, 2026
06486de
Fix CTD export guard for empty predictions
C-Achard Sep 9, 2026
e456aeb
Clarify empty CTD prediction handling
C-Achard Sep 9, 2026
a162439
Centralize test fakes
C-Achard Sep 9, 2026
11ff4fd
Add test for async with no images
C-Achard Sep 9, 2026
a210b69
Clarify async inference test comment
C-Achard Sep 9, 2026
c7a8c34
Use shared frame key width helper
C-Achard Sep 9, 2026
8248a10
Merge branch 'dev' into jaap/fix-empty-video-predictions
C-Achard Sep 17, 2026
90849a5
Don't write pickle for unreadable video
deruyter92 Oct 22, 2026
4b8c0ca
Video inference: update warning for empty predictions
deruyter92 Oct 22, 2026
44918dd
InferenceRunner: don't emit results for producer exceptions
deruyter92 Oct 22, 2026
0e40ba8
update code comment
deruyter92 Oct 22, 2026
b0fbd36
fix ShelfWriter: report zero framens when empty
deruyter92 Oct 22, 2026
ce627ae
Skip unreadable videos with shelf writer + improve docstring and log …
deruyter92 Oct 22, 2026
4867b92
Merge branch 'dev' into jaap/fix-empty-video-predictions
deruyter92 Oct 22, 2026
89d06d0
Fix warning typo + update tests
deruyter92 Oct 22, 2026
a67e257
Remove unreachable CTD empty-export branch and reword FMPose error
deruyter92 Oct 22, 2026
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
Prev Previous commit
Next Next commit
Add test for async with no images
  • Loading branch information
C-Achard committed Sep 9, 2026
commit 11ff4fd6d052be66b4f73bb2b2676412c9cfafe4
33 changes: 33 additions & 0 deletions tests/pose_estimation_pytorch/runners/test_runners_inference.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,39 @@ def test_mock_top_down(batch_size, detections_per_image):
assert i_det[0, 0, 0] == p_det["mock"]["index"]


@pytest.mark.parametrize(
"detections_per_image",
[
[0, 0, 0, 0], # issue #3485: no detections anywhere
[1, 1, 0, 0],
[1, 0],
[2, 0, 1, 0],
],
)
def test_async_inference_emits_images_without_detections(detections_per_image):
"""An image without detections adds nothing to the batch, so it never produces a
queue item. The async consumer therefore only emits it if results are drained
once more after the producer signals completion; without that final drain the
trailing undetected images are dropped, and with no detections at all the whole
result set comes back empty (issue #3485). Pinned against the sequential path,
which has always handled this because it extracts after every image.
"""
images = _top_down_images(detections_per_image, h=8, w=8)

async_runner = MockInferenceRunner(batch_size=2)
assert async_runner.inference_cfg.multithreading.enabled, "async is the default path"

sequential_runner = MockInferenceRunner(batch_size=2)
sequential_runner.inference_cfg.multithreading.enabled = False

async_predictions = async_runner.inference(images)
sequential_predictions = sequential_runner.inference(images)

assert len(async_predictions) == len(images)
assert [len(p) for p in async_predictions] == detections_per_image
assert [len(p) for p in async_predictions] == [len(p) for p in sequential_predictions]


def test_dynamic_pose_inference_calls_dynamic():
pose_batch = torch.zeros((1, 1, 1, 3))
pose_batch_updated = torch.ones((1, 1, 1, 3))
Expand Down