Skip to content

Commit a9ce371

Browse files
committed
Release 2.0.4 - Add img_size to inference, rename detector module
1 parent cc6dda3 commit a9ce371

File tree

6 files changed

+27
-7
lines changed

6 files changed

+27
-7
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,17 @@ All notable changes to this project will be documented in this file.
44
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
55
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
66

7+
## [2.0.4] - 2025-02-02
8+
9+
### Added
10+
- **Configurable inference image size**: New `img_size` parameter in `inference()` to match training size (default: 60)
11+
12+
### Changed
13+
- Renamed `insect_detector.py` to `detector.py` for cleaner module naming
14+
15+
### Fixed
16+
- **Critical**: Inference now uses correct image size for classification. Previously hardcoded to 768x768 → 640, which caused poor accuracy when training with smaller sizes (e.g., 60px)
17+
718
## [2.0.3] - 2025-01-28
819

920
### Added

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,7 @@ results = bplusplus.inference(
153153
fps=None, # None = process all frames
154154
backbone="resnet50", # Must match training
155155
save_video=True, # Set to False to skip video rendering (only CSV output)
156+
img_size=60, # Must match training
156157
)
157158
158159
print(f"Detected {results['tracks']} tracks ({results['confirmed_tracks']} confirmed)")

notebooks/full_pipeline.ipynb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -304,6 +304,7 @@
304304
" fps=None, # None = all frames\n",
305305
" backbone=\"resnet50\", # Must match training\n",
306306
" save_video=True, # Set to False to skip video rendering (only CSV output)\n",
307+
" img_size=60, # Must match training\n",
307308
")\n",
308309
"\n",
309310
"print(f\"Detected {results['tracks']} tracks ({results['confirmed_tracks']} confirmed)\")"

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "bplusplus"
3-
version = "2.0.3"
3+
version = "2.0.4"
44
description = "A simple method to create AI models for biodiversity, with collect and prepare pipeline"
55
authors = ["Titus Venverloo <tvenver@mit.edu>", "Deniz Aydemir <deniz@aydemir.us>", "Orlando Closs <orlandocloss@pm.me>", "Ase Hatveit <aase@mit.edu>"]
66
license = "MIT"
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
2-
Insect Detection Backend Module
3-
===============================
2+
Detection Backend Module
3+
========================
44
55
This module provides motion-based insect detection utilities used by the inference pipeline.
66
It is NOT meant to be run directly - use inference.py instead.

src/bplusplus/inference.py

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
import logging
1919

2020
from .tracker import InsectTracker
21-
from .insect_detector import (
21+
from .detector import (
2222
DEFAULT_DETECTION_CONFIG,
2323
get_default_config,
2424
build_detection_params,
@@ -307,7 +307,7 @@ class VideoInferenceProcessor:
307307
and track-based prediction aggregation.
308308
"""
309309

310-
def __init__(self, species_list, hierarchical_model_path, params, backbone="resnet50"):
310+
def __init__(self, species_list, hierarchical_model_path, params, backbone="resnet50", img_size=60):
311311
"""
312312
Initialize the processor.
313313
@@ -316,7 +316,9 @@ def __init__(self, species_list, hierarchical_model_path, params, backbone="resn
316316
hierarchical_model_path: Path to trained model weights
317317
params: Detection parameters dict
318318
backbone: ResNet backbone ('resnet18', 'resnet50', 'resnet101')
319+
img_size: Image size for classification (should match training)
319320
"""
321+
self.img_size = img_size
320322
self.device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
321323
self.species_list = species_list
322324
self.params = params
@@ -354,8 +356,7 @@ def __init__(self, species_list, hierarchical_model_path, params, backbone="resn
354356
self.model.eval()
355357

356358
self.transform = transforms.Compose([
357-
transforms.Resize((768, 768)),
358-
transforms.CenterCrop(640),
359+
transforms.Resize((self.img_size, self.img_size)),
359360
transforms.ToTensor(),
360361
transforms.Normalize(mean=[0.485, 0.456, 0.406], std=[0.229, 0.224, 0.225])
361362
])
@@ -1080,6 +1081,7 @@ def inference(
10801081
backbone="resnet50",
10811082
crops=False,
10821083
save_video=True,
1084+
img_size=60,
10831085
):
10841086
"""
10851087
Run inference on a video file.
@@ -1098,6 +1100,7 @@ def inference(
10981100
If model checkpoint contains backbone info, it will be used instead.
10991101
crops: If True, save cropped frames for each classified track
11001102
save_video: If True, save annotated and debug videos. Defaults to True.
1103+
img_size: Image size for classification (should match training). Default: 60.
11011104
11021105
Returns:
11031106
dict: Processing results with output file paths
@@ -1166,6 +1169,7 @@ def inference(
11661169
hierarchical_model_path=hierarchical_model_path,
11671170
params=params,
11681171
backbone=backbone,
1172+
img_size=img_size,
11691173
)
11701174

11711175
try:
@@ -1238,6 +1242,8 @@ def main():
12381242
help='Save cropped frames for each classified track')
12391243
parser.add_argument('--no-video', action='store_true',
12401244
help='Skip saving annotated and debug videos')
1245+
parser.add_argument('--img-size', type=int, default=60,
1246+
help='Image size for classification (should match training, default: 60)')
12411247

12421248
# Detection parameters (override config)
12431249
defaults = DEFAULT_DETECTION_CONFIG
@@ -1315,6 +1321,7 @@ def main():
13151321
backbone=args.backbone,
13161322
crops=args.crops,
13171323
save_video=not args.no_video,
1324+
img_size=args.img_size,
13181325
)
13191326

13201327
if result.get("success"):

0 commit comments

Comments
 (0)