PytorchWildlife 1.2.3__tar.gz → 1.2.4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. {pytorchwildlife-1.2.3/PytorchWildlife.egg-info → pytorchwildlife-1.2.4}/PKG-INFO +37 -7
  2. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/__init__.py +4 -0
  3. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/rtdetr_apache/__init__.py +2 -0
  4. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/rtdetr_apache/megadetectorv6_apache.py +44 -0
  5. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/rtdetr_apache/rtdetr_apache_base.py +225 -0
  6. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/yolov5_base.py +0 -1
  7. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/yolo_mit/__init__.py +2 -0
  8. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/yolo_mit/megadetectorv6_mit.py +44 -0
  9. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/yolo_mit/yolo/__init__.py +15 -0
  10. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/yolo_mit/yolo/config.py +168 -0
  11. pytorchwildlife-1.2.4/PytorchWildlife/models/detection/yolo_mit/yolo_mit_base.py +220 -0
  12. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4/PytorchWildlife.egg-info}/PKG-INFO +37 -7
  13. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife.egg-info/SOURCES.txt +8 -0
  14. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/README.md +35 -5
  15. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/setup.py +2 -2
  16. pytorchwildlife-1.2.3/PytorchWildlife/models/detection/__init__.py +0 -2
  17. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/LICENSE.md +0 -0
  18. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PW_FT_classification/__init__.py +0 -0
  19. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PW_FT_classification/main.py +0 -0
  20. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/__init__.py +0 -0
  21. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/data/__init__.py +0 -0
  22. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/data/datasets.py +0 -0
  23. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/data/transforms.py +0 -0
  24. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/__init__.py +0 -0
  25. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/__init__.py +0 -0
  26. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/base_classifier.py +0 -0
  27. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/__init__.py +0 -0
  28. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/amazon.py +0 -0
  29. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/base_classifier.py +0 -0
  30. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/custom_weights.py +0 -0
  31. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/opossum.py +0 -0
  32. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/resnet_base/serengeti.py +0 -0
  33. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/timm_base/DFNE.py +0 -0
  34. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/timm_base/Deepfaune.py +0 -0
  35. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/timm_base/__init__.py +0 -0
  36. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/classification/timm_base/base_classifier.py +0 -0
  37. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/base_detector.py +0 -0
  38. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/__init__.py +0 -0
  39. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/__init__.py +0 -0
  40. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/data/__init__.py +0 -0
  41. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/data/patches.py +0 -0
  42. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/data/types.py +0 -0
  43. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/eval/__init__.py +0 -0
  44. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/eval/lmds.py +0 -0
  45. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/animaloc/eval/stitchers.py +0 -0
  46. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/dla.py +0 -0
  47. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/herdnet.py +0 -0
  48. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/herdnet/model.py +0 -0
  49. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/Deepfaune.py +0 -0
  50. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/__init__.py +0 -0
  51. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/megadetectorv5.py +0 -0
  52. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/megadetectorv6.py +0 -0
  53. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/megadetectorv6_distributed.py +0 -0
  54. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/yolov8_base.py +0 -0
  55. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/models/detection/ultralytics_based/yolov8_distributed.py +0 -0
  56. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/utils/__init__.py +0 -0
  57. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/utils/misc.py +0 -0
  58. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife/utils/post_process.py +0 -0
  59. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife.egg-info/dependency_links.txt +0 -0
  60. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife.egg-info/requires.txt +0 -0
  61. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/PytorchWildlife.egg-info/top_level.txt +0 -0
  62. {pytorchwildlife-1.2.3 → pytorchwildlife-1.2.4}/setup.cfg +0 -0
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PytorchWildlife
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: a PyTorch Collaborative Deep Learning Framework for Conservation.
5
5
  Home-page: https://github.com/microsoft/CameraTraps/
6
6
  Author: Andres Hernandez, Zhongqi Miao, Daniela Ruiz Lopez, Isai Daniel Chacon Silva
7
- Author-email: v-herandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com
7
+ Author-email: v-hernandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com
8
8
  License: MIT
9
9
  Keywords: pytorch_wildlife,pytorch,wildlife,megadetector,conservation,animal,detection,classification
10
10
  Classifier: Development Status :: 3 - Alpha
@@ -63,16 +63,46 @@ Dynamic: summary
63
63
 
64
64
  ## 📣 Announcements
65
65
 
66
- ### V 1.2.3
66
+ ### 🚀 We’re Open for Contributions!
67
67
 
68
- - We have fully recreated our [documentation page](https://microsoft.github.io/CameraTraps/) with [MKDocs](https://squidfunk.github.io/mkdocs-material/). Please take a look and let us know what you think! (Special thanks to @ss26 for creating the foundation of this documentation page!)
68
+ We’re excited to announce that **Pytorch-Wildlife** is now open to community contributions!
69
+ If you’d like to get involved and help improve the project, we’d love to have you on board.
69
70
 
70
- - We have released new MegaDetector V6 model weights. MDV6-yolov9-e and MDV6-yolov10-e are now retrained at 1280 input resolution to match the original V5 setup. In addition, we have added both compact and extra versions for [YOLOv9 MIT](https://github.com/MultimediaTechLab/YOLO?tab=readme-ov-file) and [RT-DETR Apache](https://github.com/lyuwenyu/RT-DETR/tree/main) implementations, expanding the range of V6 options for different deployment needs.
71
+ 👉 **Check out our Contribution Guidelines:**
71
72
 
72
- - Our [Model Zoo](https://microsoft.github.io/CameraTraps/model_zoo/megadetector/) now includes new performance numbers evaluated using [pycocotools](https://pypi.org/project/pycocotools/), enabling easier and more standardized comparisons with MIT and Apache models. All metrics are reported on 1280-sized input images to ensure consistency across versions. While V5 and V6 now deliver comparable performance, V6 models are still significantly smaller. Model weights for all versions, including MIT and Apache variants, are available for download, and we’ll be releasing the inference code for MIT and Apache models soon.
73
+ [📚 How to Participate](https://microsoft.github.io/CameraTraps/contribute/#how-to-participate)
73
74
 
74
- - To further improve V6 model generalization performance, our next iteration of V6 training will incorporate some new public camera trap datasets from LILA, including [Orinoquía Camera Traps](https://lila.science/datasets/orinoquia-camera-traps/) and other datasets that have bounding boxes and are currently not in V6's training pool.
75
+ You’ll find everything you need there — from how to pick an issue, to submitting your first pull request.
76
+ Let’s build this together! 🐾🌱
75
77
 
78
+ ### V 1.2.4
79
+
80
+ The inference code for the MIT YOLO and Apache RT‑DETR models is now available! To use either one, just load it like any other PyTorch‑Wildlife model:
81
+
82
+ ```python
83
+ from pw_detection import MegaDetectorV6MIT, MegaDetectorV6Apache
84
+
85
+ # MIT YOLO
86
+ detector = MegaDetectorV6MIT(
87
+ device=DEVICE,
88
+ pretrained=True,
89
+ version="MDV6-mit-yolov9-e"
90
+ )
91
+
92
+ # Apache RT‑DETR
93
+ detector = MegaDetectorV6Apache(
94
+ device=DEVICE,
95
+ pretrained=True,
96
+ version="MDV6-apa-rtdetr-e"
97
+ )
98
+ ```
99
+ Valid versions:
100
+ - MDV6-mit-yolov9-c
101
+ - MDV6-mit-yolov9-e
102
+ - MDV6-apa-rtdetr-c
103
+ - MDV6-apa-rtdetr-e
104
+
105
+ You can also try out the full pipeline using the `detection_classification_pipeline_demo.py` script in the demo folder.
76
106
 
77
107
  #### Previous versions:
78
108
  - [What's New](https://microsoft.github.io/CameraTraps/releases/release_notes/)
@@ -0,0 +1,4 @@
1
+ from .ultralytics_based import *
2
+ from .herdnet import *
3
+ from .yolo_mit import *
4
+ from .rtdetr_apache import *
@@ -0,0 +1,2 @@
1
+ from .rtdetr_apache_base import *
2
+ from .megadetectorv6_apache import *
@@ -0,0 +1,44 @@
1
+
2
+ from .rtdetr_apache_base import RTDETRApacheBase
3
+
4
+ __all__ = [
5
+ 'MegaDetectorV6Apache'
6
+ ]
7
+
8
+ class MegaDetectorV6Apache(RTDETRApacheBase):
9
+ """
10
+ MegaDetectorV6 is a specialized class derived from the RTDETRApacheBase class
11
+ that is specifically designed for detecting animals, persons, and vehicles.
12
+
13
+ Attributes:
14
+ CLASS_NAMES (dict): Mapping of class IDs to their respective names.
15
+ """
16
+
17
+ CLASS_NAMES = {
18
+ 0: "animal",
19
+ 1: "person",
20
+ 2: "vehicle"
21
+ }
22
+
23
+ def __init__(self, weights=None, device="cpu", pretrained=True, version='MDV6-rtdetr-x-apache'):
24
+ """
25
+ Initializes the MegaDetectorV6 model with the option to load pretrained weights.
26
+
27
+ Args:
28
+ weights (str, optional): Path to the weights file.
29
+ device (str, optional): Device to load the model on (e.g., "cpu" or "cuda"). Default is "cpu".
30
+ pretrained (bool, optional): Whether to load the pretrained model. Default is True.
31
+ version (str, optional): Version of the model to load. Default is 'MDV6-rtdetr-x-apache'.
32
+ """
33
+ self.IMAGE_SIZE = 640
34
+
35
+ if version == "MDV6-apa-rtdetr-c":
36
+ url = "https://zenodo.org/records/15398270/files/MDV6-apa-rtdetr-c.pth?download=1"
37
+ self.MODEL_NAME = "MDV6-apa-rtdetr-c.pth"
38
+ elif version == "MDV6-apa-rtdetr-e":
39
+ url = "https://zenodo.org/records/15398270/files/MDV6-apa-rtdetr-e.pth?download=1"
40
+ self.MODEL_NAME = "MDV6-apa-rtdetr-e.pth"
41
+ else:
42
+ raise ValueError('Select a valid model version: MDV6-apa-rtdetr-c or MDV6-apa-rtdetr-e')
43
+
44
+ super(MegaDetectorV6Apache, self).__init__(weights=weights, device=device, url=url)
@@ -0,0 +1,225 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ """ RT-DETR Apache base detector class. """
5
+
6
+ # Importing basic libraries
7
+ import os
8
+ import supervision as sv
9
+ import wget
10
+ import torch
11
+ import torch.nn as nn
12
+ import torchvision.transforms as T
13
+
14
+ from ..base_detector import BaseDetector
15
+ from ....data import datasets as pw_data
16
+ from PIL import Image
17
+
18
+ import sys
19
+ from pathlib import Path
20
+ project_root = Path(__file__).resolve().parent
21
+ sys.path.append(str(project_root))
22
+ from rtdetrv2_pytorch.src.core import YAMLConfig
23
+
24
+ class RTDETRApacheBase(BaseDetector):
25
+ """
26
+ Base detector class for RTDETRApacheBase framework. This class provides utility methods for
27
+ loading the model, generating results, and performing single and batch image detections.
28
+ """
29
+ def __init__(self, weights=None, device="cpu", url=None):
30
+ """
31
+ Initialize the RT-DETR apache detector.
32
+
33
+ Args:
34
+ weights (str, optional):
35
+ Path to the model weights. Defaults to None.
36
+ device (str, optional):
37
+ Device for model inference. Defaults to "cpu".
38
+ url (str, optional):
39
+ URL to fetch the model weights. Defaults to None.
40
+ """
41
+ self.transform = T.Compose([
42
+ T.Resize((640, 640)),
43
+ T.ToTensor(),
44
+ ])
45
+ self.weights = weights
46
+ self.device = device
47
+ self.url = url
48
+ super(RTDETRApacheBase, self).__init__(weights=self.weights, device=self.device, url=self.url)
49
+ self._load_model(weights=self.weights, device=self.device, url=self.url)
50
+
51
+ def _load_model(self, weights=None, device="cpu", url=None):
52
+ """
53
+ Load the RT-DETR apache model weights.
54
+
55
+ Args:
56
+ weights (str, optional):
57
+ Path to the model weights. Defaults to None.
58
+ device (str, optional):
59
+ Device for model inference. Defaults to "cpu".
60
+ url (str, optional):
61
+ URL to fetch the model weights. Defaults to None.
62
+ Raises:
63
+ Exception: If weights are not provided.
64
+ """
65
+ if weights:
66
+ resume = weights
67
+ elif url:
68
+ if not os.path.exists(os.path.join(torch.hub.get_dir(), "checkpoints", self.MODEL_NAME)):
69
+ os.makedirs(os.path.join(torch.hub.get_dir(), "checkpoints"), exist_ok=True)
70
+ resume = wget.download(url, out=os.path.join(torch.hub.get_dir(), "checkpoints"))
71
+ else:
72
+ resume = os.path.join(torch.hub.get_dir(), "checkpoints", self.MODEL_NAME)
73
+ else:
74
+ raise Exception("Need weights for inference.")
75
+
76
+ if self.MODEL_NAME == "MDV6-apa-rtdetr-c.pth":
77
+ config = os.path.join(project_root, "rtdetrv2_pytorch/configs/rtdetrv2/rtdetrv2_r18vd_120e_megadetector.yml")
78
+ elif self.MODEL_NAME == "MDV6-apa-rtdetr-e.pth":
79
+ config = os.path.join(project_root, "rtdetrv2_pytorch/configs/rtdetrv2/rtdetrv2_r101vd_6x_megadetector.yml")
80
+ else:
81
+ raise ValueError('Select a valid model version: MDV6-apa-rtdetr-c or MDV6-apa-rtdetr-e')
82
+
83
+ cfg = YAMLConfig(config, resume=resume)
84
+
85
+ checkpoint = torch.load(resume, map_location='cpu')
86
+ if 'ema' in checkpoint:
87
+ state = checkpoint['ema']['module']
88
+ else:
89
+ state = checkpoint['model']
90
+
91
+ cfg.model.load_state_dict(state)
92
+
93
+ class Model(nn.Module):
94
+ def __init__(self, ) -> None:
95
+ super().__init__()
96
+ self.model = cfg.model.deploy()
97
+ self.postprocessor = cfg.postprocessor.deploy()
98
+
99
+ def forward(self, images, orig_target_sizes):
100
+ outputs = self.model(images)
101
+ outputs = self.postprocessor(outputs, orig_target_sizes)
102
+ return outputs
103
+
104
+ self.model = Model().to(self.device)
105
+
106
+ def results_generation(self, preds, img_id, id_strip=None):
107
+ """
108
+ Generate results for detection based on model predictions.
109
+
110
+ Args:
111
+ preds (List[torch.Tensor]):
112
+ Model predictions.
113
+ img_id (str):
114
+ Image identifier.
115
+ id_strip (str, optional):
116
+ Strip specific characters from img_id. Defaults to None.
117
+
118
+ Returns:
119
+ dict: Dictionary containing image ID, detections, and labels.
120
+ """
121
+ class_id = preds[0].cpu().numpy().astype(int)
122
+ xyxy = preds[1].detach().cpu().numpy()
123
+ confidence = preds[2].detach().cpu().numpy()
124
+
125
+ results = {"img_id": str(img_id).strip(id_strip)}
126
+ results["detections"] = sv.Detections(
127
+ xyxy=xyxy,
128
+ confidence=confidence,
129
+ class_id=class_id
130
+ )
131
+
132
+ results["labels"] = [
133
+ f"{self.CLASS_NAMES[class_id]} {confidence:0.2f}"
134
+ for _, _, confidence, class_id, _, _ in results["detections"]
135
+ ]
136
+
137
+ return results
138
+
139
+
140
+ def single_image_detection(self, img, img_path=None, det_conf_thres=0.2, id_strip=None):
141
+ """
142
+ Perform detection on a single image.
143
+
144
+ Args:
145
+ img (str or ndarray):
146
+ Image path or ndarray of images.
147
+ img_path (str, optional):
148
+ Image path or identifier.
149
+ det_conf_thres (float, optional):
150
+ Confidence threshold for predictions. Defaults to 0.2.
151
+ id_strip (str, optional):
152
+ Characters to strip from img_id. Defaults to None.
153
+
154
+ Returns:
155
+ dict: Detection results.
156
+ """
157
+ if type(img) == str:
158
+ if img_path is None:
159
+ img_path = img
160
+ im_pil = Image.open(img_path).convert('RGB')
161
+ else:
162
+ im_pil = Image.fromarray(img)
163
+
164
+ w, h = im_pil.size
165
+ orig_size = torch.tensor([w, h])[None].to(self.device)
166
+ im_data = self.transform(im_pil)[None].to(self.device)
167
+ labels, boxes, scores = self.model(im_data, orig_size)
168
+
169
+ scr = scores[0]
170
+ lab = labels[0][scr > det_conf_thres]
171
+ box = boxes[0][scr > det_conf_thres]
172
+ scrs = scores[0][scr > det_conf_thres]
173
+
174
+ return self.results_generation([lab, box, scrs], img_path, id_strip)
175
+
176
+ def batch_image_detection(self, data_path, batch_size=16, det_conf_thres=0.2, id_strip=None):
177
+ """
178
+ Perform detection on a batch of images.
179
+
180
+ Args:
181
+ data_path (str):
182
+ Path containing all images for inference.
183
+ batch_size (int, optional):
184
+ Batch size for inference. Defaults to 16.
185
+ det_conf_thres (float, optional):
186
+ Confidence threshold for predictions. Defaults to 0.2.
187
+ id_strip (str, optional):
188
+ Characters to strip from img_id. Defaults to None.
189
+ extension (str, optional):
190
+ Image extension to search for. Defaults to "JPG"
191
+
192
+ Returns:
193
+ list: List of detection results for all images.
194
+ """
195
+ dataset = pw_data.DetectionImageFolder(
196
+ data_path,
197
+ transform=self.transform,
198
+ )
199
+
200
+ results = []
201
+ for i in range(len(dataset)):
202
+ im_pil = Image.open(dataset.images[i]).convert('RGB')
203
+ w, h = im_pil.size
204
+ orig_size = torch.tensor([w, h])[None].to(self.device)
205
+ im_data = self.transform(im_pil)[None].to(self.device)
206
+
207
+ labels, boxes, scores = self.model(im_data, orig_size)
208
+
209
+ scr = scores[0]
210
+ lab = labels[0][scr > det_conf_thres]
211
+ box = boxes[0][scr > det_conf_thres]
212
+ scrs = scores[0][scr > det_conf_thres]
213
+
214
+ res = self.results_generation([lab, box, scrs], dataset.images[i], id_strip)
215
+
216
+ # Normalize the coordinates for timelapse compatibility
217
+ size = orig_size[0].cpu().numpy()
218
+ normalized_coords = [[x1 / size[1], y1 / size[0], x2 / size[1], y2 / size[0]] for x1, y1, x2, y2 in res["detections"].xyxy]
219
+ res["normalized_coords"] = normalized_coords
220
+ results.append(res)
221
+
222
+ return results
223
+
224
+
225
+
@@ -15,7 +15,6 @@ from torch.utils.data import DataLoader
15
15
  from torch.hub import load_state_dict_from_url
16
16
 
17
17
  from yolov5.utils.general import non_max_suppression, scale_boxes
18
- # from .yolov5_utils import non_max_suppression, scale_boxes
19
18
  from ..base_detector import BaseDetector
20
19
  from ....data import transforms as pw_trans
21
20
  from ....data import datasets as pw_data
@@ -0,0 +1,2 @@
1
+ from .yolo_mit_base import *
2
+ from .megadetectorv6_mit import *
@@ -0,0 +1,44 @@
1
+
2
+ from .yolo_mit_base import YOLOMITBase
3
+
4
+ __all__ = [
5
+ 'MegaDetectorV6MIT'
6
+ ]
7
+
8
+ class MegaDetectorV6MIT(YOLOMITBase):
9
+ """
10
+ MegaDetectorV6 is a specialized class derived from the YOLOMITBase class
11
+ that is specifically designed for detecting animals, persons, and vehicles.
12
+
13
+ Attributes:
14
+ CLASS_NAMES (dict): Mapping of class IDs to their respective names.
15
+ """
16
+
17
+ CLASS_NAMES = {
18
+ 0: "animal",
19
+ 1: "person",
20
+ 2: "vehicle"
21
+ }
22
+
23
+ def __init__(self, weights=None, device="cpu", pretrained=True, version='MDV6-yolov9-c-mit'):
24
+ """
25
+ Initializes the MegaDetectorV6 model with the option to load pretrained weights.
26
+
27
+ Args:
28
+ weights (str, optional): Path to the weights file.
29
+ device (str, optional): Device to load the model on (e.g., "cpu" or "cuda"). Default is "cpu".
30
+ pretrained (bool, optional): Whether to load the pretrained model. Default is True.
31
+ version (str, optional): Version of the model to load. Default is 'MDV6-yolov9-c-mit'.
32
+ """
33
+ self.IMAGE_SIZE = 640
34
+
35
+ if version == 'MDV6-mit-yolov9-c':
36
+ url = "https://zenodo.org/records/15398270/files/MDV6-mit-yolov9-c.ckpt?download=1"
37
+ self.MODEL_NAME = "MDV6-mit-yolov9-c.ckpt"
38
+ elif version == 'MDV6-mit-yolov9-e':
39
+ url = "https://zenodo.org/records/15398270/files/MDV6-mit-yolov9-e.ckpt?download=1"
40
+ self.MODEL_NAME = "MDV6-mit-yolov9-e.ckpt"
41
+ else:
42
+ raise ValueError('Select a valid model version: MDV6-mit-yolov9-c or MDV6-mit-yolov9-e')
43
+
44
+ super(MegaDetectorV6MIT, self).__init__(weights=weights, device=device, url=url)
@@ -0,0 +1,15 @@
1
+ from yolo.model.yolo import create_model
2
+ from yolo.config import Config, NMSConfig
3
+ from yolo.tools.data_loader import AugmentationComposer, create_dataloader
4
+ from yolo.utils.model_utils import PostProcess
5
+ from yolo.utils.bounding_box_utils import create_converter
6
+
7
+ all = [
8
+ "create_model",
9
+ "Config",
10
+ "NMSConfig",
11
+ "AugmentationComposer"
12
+ "create_dataloader",
13
+ "PostProcess",
14
+ "create_converter",
15
+ ]
@@ -0,0 +1,168 @@
1
+ from dataclasses import dataclass
2
+ from typing import Any, Dict, List, Optional, Union
3
+ from torch import nn
4
+
5
+
6
+ @dataclass
7
+ class AnchorConfig:
8
+ strides: List[int]
9
+ reg_max: Optional[int]
10
+ anchor_num: Optional[int]
11
+ anchor: List[List[int]]
12
+
13
+
14
+ @dataclass
15
+ class LayerConfg:
16
+ args: Dict
17
+ source: Union[int, str, List[int]]
18
+ tags: str
19
+
20
+
21
+ @dataclass
22
+ class BlockConfig:
23
+ block: List[Dict[str, LayerConfg]]
24
+
25
+
26
+ @dataclass
27
+ class ModelConfig:
28
+ name: Optional[str]
29
+ anchor: AnchorConfig
30
+ model: Dict[str, BlockConfig]
31
+
32
+
33
+ @dataclass
34
+ class DownloadDetail:
35
+ url: str
36
+ file_size: int
37
+
38
+
39
+ @dataclass
40
+ class DownloadOptions:
41
+ details: Dict[str, DownloadDetail]
42
+
43
+
44
+ @dataclass
45
+ class DatasetConfig:
46
+ path: str
47
+ class_num: int
48
+ class_list: List[str]
49
+ auto_download: Optional[DownloadOptions]
50
+
51
+
52
+ @dataclass
53
+ class DataConfig:
54
+ shuffle: bool
55
+ batch_size: int
56
+ pin_memory: bool
57
+ cpu_num: int
58
+ image_size: List[int]
59
+ data_augment: Dict[str, int]
60
+ source: Optional[Union[str, int]]
61
+ dynamic_shape: Optional[bool]
62
+
63
+
64
+ @dataclass
65
+ class OptimizerArgs:
66
+ lr: float
67
+ weight_decay: float
68
+ momentum: float
69
+
70
+
71
+ @dataclass
72
+ class OptimizerConfig:
73
+ type: str
74
+ args: OptimizerArgs
75
+
76
+
77
+ @dataclass
78
+ class MatcherConfig:
79
+ iou: str
80
+ topk: int
81
+ factor: Dict[str, int]
82
+
83
+
84
+ @dataclass
85
+ class LossConfig:
86
+ objective: Dict[str, int]
87
+ aux: Union[bool, float]
88
+ matcher: MatcherConfig
89
+
90
+
91
+ @dataclass
92
+ class SchedulerConfig:
93
+ type: str
94
+ warmup: Dict[str, Union[int, float]]
95
+ args: Dict[str, Any]
96
+
97
+
98
+ @dataclass
99
+ class EMAConfig:
100
+ enable: bool
101
+ decay: float
102
+
103
+
104
+ @dataclass
105
+ class NMSConfig:
106
+ min_confidence: float
107
+ min_iou: float
108
+ max_bbox: int
109
+
110
+
111
+ @dataclass
112
+ class InferenceConfig:
113
+ task: str
114
+ nms: NMSConfig
115
+ data: DataConfig
116
+ fast_inference: Optional[None]
117
+ save_predict: bool
118
+
119
+
120
+ @dataclass
121
+ class ValidationConfig:
122
+ task: str
123
+ nms: NMSConfig
124
+ data: DataConfig
125
+
126
+
127
+ @dataclass
128
+ class TrainConfig:
129
+ task: str
130
+ epoch: int
131
+ data: DataConfig
132
+ optimizer: OptimizerConfig
133
+ loss: LossConfig
134
+ scheduler: SchedulerConfig
135
+ ema: EMAConfig
136
+ validation: ValidationConfig
137
+
138
+
139
+ @dataclass
140
+ class Config:
141
+ task: Union[TrainConfig, InferenceConfig, ValidationConfig]
142
+ dataset: DatasetConfig
143
+ model: ModelConfig
144
+ name: str
145
+
146
+ device: Union[str, int, List[int]]
147
+ cpu_num: int
148
+
149
+ image_size: List[int]
150
+
151
+ out_path: str
152
+ exist_ok: bool
153
+
154
+ lucky_number: 10
155
+ use_wandb: bool
156
+ use_tensorboard: bool
157
+
158
+ weight: Optional[str]
159
+
160
+
161
+ @dataclass
162
+ class YOLOLayer(nn.Module):
163
+ source: Union[int, str, List[int]]
164
+ output: bool
165
+ tags: str
166
+ layer_type: str
167
+ usable: bool
168
+ external: Optional[dict]
@@ -0,0 +1,220 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ """ Yolo mit base detector class. """
5
+
6
+ # Importing basic libraries
7
+
8
+ import os
9
+ import supervision as sv
10
+ import numpy as np
11
+ from PIL import Image
12
+ import wget
13
+ import torch
14
+
15
+ from ..base_detector import BaseDetector
16
+ from ....data import datasets as pw_data
17
+
18
+ import sys
19
+ from pathlib import Path
20
+
21
+ from lightning import Trainer
22
+ import yaml
23
+ from omegaconf import OmegaConf
24
+
25
+ project_root = Path(__file__).resolve().parent
26
+ sys.path.append(str(project_root))
27
+
28
+ from yolo import create_model, create_converter, PostProcess, AugmentationComposer
29
+
30
+ class YOLOMITBase(BaseDetector):
31
+ """
32
+ Base detector class for YOLO MIT framework. This class provides utility methods for
33
+ loading the model, generating results, and performing single and batch image detections.
34
+ """
35
+ def __init__(self, weights=None, device="cpu", url=None):
36
+ """
37
+ Initialize the YOLO MIT detector.
38
+
39
+ Args:
40
+ weights (str, optional):
41
+ Path to the model weights. Defaults to None.
42
+ device (str, optional):
43
+ Device for model inference. Defaults to "cpu".
44
+ url (str, optional):
45
+ URL to fetch the model weights. Defaults to None.
46
+ """
47
+
48
+ self.cfg = self._load_cfg()
49
+ self.transform = AugmentationComposer([], self.cfg.image_size, self.cfg.image_size[0])
50
+ self.weights = weights
51
+ self.device = device
52
+ self.url = url
53
+ super(YOLOMITBase, self).__init__(weights=self.weights, device=self.device, url=self.url)
54
+
55
+ def _load_cfg(self):
56
+ if self.MODEL_NAME == "MDV6-mit-yolov9-c.ckpt":
57
+ if not os.path.exists(os.path.join(torch.hub.get_dir(), "checkpoints", "config_v9s.yaml")):
58
+ os.makedirs(os.path.join(torch.hub.get_dir(), "checkpoints"), exist_ok=True)
59
+ url = "https://zenodo.org/records/15178680/files/config_v9s.yaml?download=1"
60
+ config_path = wget.download(url, out=os.path.join(torch.hub.get_dir(), "checkpoints"))
61
+ else:
62
+ config_path = os.path.join(torch.hub.get_dir(), "checkpoints", "config_v9s.yaml")
63
+ elif self.MODEL_NAME == "MDV6-mit-yolov9-e.ckpt":
64
+ if not os.path.exists(os.path.join(torch.hub.get_dir(), "checkpoints", "config_v9c.yaml")):
65
+ os.makedirs(os.path.join(torch.hub.get_dir(), "checkpoints"), exist_ok=True)
66
+ url = "https://zenodo.org/records/15178680/files/config_v9c.yaml?download=1"
67
+ config_path = wget.download(url, out=os.path.join(torch.hub.get_dir(), "checkpoints"))
68
+ else:
69
+ config_path = os.path.join(torch.hub.get_dir(), "checkpoints", "config_v9c.yaml")
70
+
71
+ with open(config_path, 'r') as f:
72
+ cfg_dict = yaml.safe_load(f)
73
+
74
+ return OmegaConf.create(cfg_dict)
75
+
76
+ def _load_model(self, weights=None, device="cpu", url=None):
77
+ """
78
+ Load the YOLO MIT model weights.
79
+
80
+ Args:
81
+ weights (str, optional):
82
+ Path to the model weights. Defaults to None.
83
+ device (str, optional):
84
+ Device for model inference. Defaults to "cpu".
85
+ url (str, optional):
86
+ URL to fetch the model weights. Defaults to None.
87
+ Raises:
88
+ Exception: If weights are not provided.
89
+ """
90
+ if url:
91
+ if not os.path.exists(os.path.join(torch.hub.get_dir(), "checkpoints", self.MODEL_NAME)):
92
+ os.makedirs(os.path.join(torch.hub.get_dir(), "checkpoints"), exist_ok=True)
93
+ weights = wget.download(url, out=os.path.join(torch.hub.get_dir(), "checkpoints"))
94
+ else:
95
+ weights = os.path.join(torch.hub.get_dir(), "checkpoints", self.MODEL_NAME)
96
+ else:
97
+ raise Exception("Need weights for inference.")
98
+
99
+ self.cfg.image_size = [self.IMAGE_SIZE, self.IMAGE_SIZE]
100
+ self.model = create_model(self.cfg.model, weight_path=weights, class_num=3).to(self.device)
101
+ self.converter = create_converter(self.cfg.model.name, self.model, self.cfg.model.anchor, self.cfg.image_size, self.device)
102
+ self.post_proccess = PostProcess(self.converter, self.cfg.task.nms)
103
+
104
+ def results_generation(self, preds, img_id, id_strip=None):
105
+ """
106
+ Generate results for detection based on model predictions.
107
+
108
+ Args:
109
+ preds (List[torch.Tensor]):
110
+ Model predictions.
111
+ img_id (str):
112
+ Image identifier.
113
+ id_strip (str, optional):
114
+ Strip specific characters from img_id. Defaults to None.
115
+
116
+ Returns:
117
+ dict: Dictionary containing image ID, detections, and labels.
118
+ """
119
+ #preds: [cls, x1, y1, x2, y2, conf]
120
+ class_id = preds[0][:,0].cpu().numpy().astype(int)
121
+ xyxy = preds[0][:,1:5].cpu().numpy()
122
+ confidence = preds[0][:,5].cpu().numpy()
123
+
124
+ results = {"img_id": str(img_id).strip(id_strip)}
125
+ results["detections"] = sv.Detections(
126
+ xyxy=xyxy,
127
+ confidence=confidence,
128
+ class_id=class_id
129
+ )
130
+
131
+ results["labels"] = [
132
+ f"{self.CLASS_NAMES[class_id]} {confidence:0.2f}"
133
+ for _, _, confidence, class_id, _, _ in results["detections"]
134
+ ]
135
+ results
136
+ return results
137
+
138
+
139
+ def single_image_detection(self, img, img_path=None, det_conf_thres=0.2, id_strip=None):
140
+ """
141
+ Perform detection on a single image.
142
+
143
+ Args:
144
+ img (str or ndarray):
145
+ Image path or ndarray of images.
146
+ img_path (str, optional):
147
+ Image path or identifier.
148
+ det_conf_thres (float, optional):
149
+ Confidence threshold for predictions. Defaults to 0.2.
150
+ id_strip (str, optional):
151
+ Characters to strip from img_id. Defaults to None.
152
+
153
+ Returns:
154
+ dict: Detection results.
155
+ """
156
+ self.cfg.task.data.source = img_path
157
+ self.cfg.task.nms.min_confidence = det_conf_thres
158
+ self._load_model(weights=self.weights, device=self.device, url=self.url)
159
+
160
+ if type(img) == str:
161
+ if img_path is None:
162
+ img_path = img
163
+ im_pil = Image.open(img_path).convert('RGB')
164
+ else:
165
+ im_pil = Image.fromarray(img)
166
+
167
+ image, bbox, rev_tensor = self.transform(im_pil)
168
+ image = image.to(self.device)[None]
169
+ rev_tensor = rev_tensor.to(self.device)[None]
170
+
171
+ with torch.no_grad():
172
+ predict = self.model(image)
173
+ det_results = self.post_proccess(predict, rev_tensor) #pred_box: [cls, x1, y1, x2, y2, conf]
174
+
175
+ return self.results_generation(det_results, img_path, id_strip)
176
+
177
+ def batch_image_detection(self, data_path, batch_size=16, det_conf_thres=0.2, id_strip=None):
178
+ """
179
+ Perform detection on a batch of images.
180
+
181
+ Args:
182
+ data_path (str):
183
+ Path containing all images for inference.
184
+ batch_size (int, optional):
185
+ Batch size for inference. Defaults to 16.
186
+ det_conf_thres (float, optional):
187
+ Confidence threshold for predictions. Defaults to 0.2.
188
+ id_strip (str, optional):
189
+ Characters to strip from img_id. Defaults to None.
190
+ extension (str, optional):
191
+ Image extension to search for. Defaults to "JPG"
192
+
193
+ Returns:
194
+ list: List of detection results for all images.
195
+ """
196
+ self.cfg.task.data.source = data_path
197
+ self.cfg.task.nms.min_confidence = det_conf_thres
198
+ self._load_model(weights=self.weights, device=self.device, url=self.url)
199
+
200
+ dataset = pw_data.DetectionImageFolder(
201
+ data_path,
202
+ transform=self.transform,
203
+ )
204
+
205
+ results = []
206
+ for i in range(len(dataset.images)):
207
+ res = self.single_image_detection(dataset.images[i], img_path=dataset.images[i], det_conf_thres=det_conf_thres, id_strip=id_strip)
208
+ # Upload the original image and get the size in the format (height, width)
209
+ img = Image.open(dataset.images[i])
210
+ img = np.asarray(img)
211
+ size = img.shape[:2]
212
+ # Normalize the coordinates for timelapse compatibility
213
+ normalized_coords = [[x1 / size[1], y1 / size[0], x2 / size[1], y2 / size[0]] for x1, y1, x2, y2 in res["detections"].xyxy]
214
+ res["normalized_coords"] = normalized_coords
215
+ results.append(res)
216
+
217
+ return results
218
+
219
+
220
+
@@ -1,10 +1,10 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: PytorchWildlife
3
- Version: 1.2.3
3
+ Version: 1.2.4
4
4
  Summary: a PyTorch Collaborative Deep Learning Framework for Conservation.
5
5
  Home-page: https://github.com/microsoft/CameraTraps/
6
6
  Author: Andres Hernandez, Zhongqi Miao, Daniela Ruiz Lopez, Isai Daniel Chacon Silva
7
- Author-email: v-herandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com
7
+ Author-email: v-hernandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com
8
8
  License: MIT
9
9
  Keywords: pytorch_wildlife,pytorch,wildlife,megadetector,conservation,animal,detection,classification
10
10
  Classifier: Development Status :: 3 - Alpha
@@ -63,16 +63,46 @@ Dynamic: summary
63
63
 
64
64
  ## 📣 Announcements
65
65
 
66
- ### V 1.2.3
66
+ ### 🚀 We’re Open for Contributions!
67
67
 
68
- - We have fully recreated our [documentation page](https://microsoft.github.io/CameraTraps/) with [MKDocs](https://squidfunk.github.io/mkdocs-material/). Please take a look and let us know what you think! (Special thanks to @ss26 for creating the foundation of this documentation page!)
68
+ We’re excited to announce that **Pytorch-Wildlife** is now open to community contributions!
69
+ If you’d like to get involved and help improve the project, we’d love to have you on board.
69
70
 
70
- - We have released new MegaDetector V6 model weights. MDV6-yolov9-e and MDV6-yolov10-e are now retrained at 1280 input resolution to match the original V5 setup. In addition, we have added both compact and extra versions for [YOLOv9 MIT](https://github.com/MultimediaTechLab/YOLO?tab=readme-ov-file) and [RT-DETR Apache](https://github.com/lyuwenyu/RT-DETR/tree/main) implementations, expanding the range of V6 options for different deployment needs.
71
+ 👉 **Check out our Contribution Guidelines:**
71
72
 
72
- - Our [Model Zoo](https://microsoft.github.io/CameraTraps/model_zoo/megadetector/) now includes new performance numbers evaluated using [pycocotools](https://pypi.org/project/pycocotools/), enabling easier and more standardized comparisons with MIT and Apache models. All metrics are reported on 1280-sized input images to ensure consistency across versions. While V5 and V6 now deliver comparable performance, V6 models are still significantly smaller. Model weights for all versions, including MIT and Apache variants, are available for download, and we’ll be releasing the inference code for MIT and Apache models soon.
73
+ [📚 How to Participate](https://microsoft.github.io/CameraTraps/contribute/#how-to-participate)
73
74
 
74
- - To further improve V6 model generalization performance, our next iteration of V6 training will incorporate some new public camera trap datasets from LILA, including [Orinoquía Camera Traps](https://lila.science/datasets/orinoquia-camera-traps/) and other datasets that have bounding boxes and are currently not in V6's training pool.
75
+ You’ll find everything you need there — from how to pick an issue, to submitting your first pull request.
76
+ Let’s build this together! 🐾🌱
75
77
 
78
+ ### V 1.2.4
79
+
80
+ The inference code for the MIT YOLO and Apache RT‑DETR models is now available! To use either one, just load it like any other PyTorch‑Wildlife model:
81
+
82
+ ```python
83
+ from pw_detection import MegaDetectorV6MIT, MegaDetectorV6Apache
84
+
85
+ # MIT YOLO
86
+ detector = MegaDetectorV6MIT(
87
+ device=DEVICE,
88
+ pretrained=True,
89
+ version="MDV6-mit-yolov9-e"
90
+ )
91
+
92
+ # Apache RT‑DETR
93
+ detector = MegaDetectorV6Apache(
94
+ device=DEVICE,
95
+ pretrained=True,
96
+ version="MDV6-apa-rtdetr-e"
97
+ )
98
+ ```
99
+ Valid versions:
100
+ - MDV6-mit-yolov9-c
101
+ - MDV6-mit-yolov9-e
102
+ - MDV6-apa-rtdetr-c
103
+ - MDV6-apa-rtdetr-e
104
+
105
+ You can also try out the full pipeline using the `detection_classification_pipeline_demo.py` script in the demo folder.
76
106
 
77
107
  #### Previous versions:
78
108
  - [What's New](https://microsoft.github.io/CameraTraps/releases/release_notes/)
@@ -38,6 +38,9 @@ PytorchWildlife/models/detection/herdnet/animaloc/data/types.py
38
38
  PytorchWildlife/models/detection/herdnet/animaloc/eval/__init__.py
39
39
  PytorchWildlife/models/detection/herdnet/animaloc/eval/lmds.py
40
40
  PytorchWildlife/models/detection/herdnet/animaloc/eval/stitchers.py
41
+ PytorchWildlife/models/detection/rtdetr_apache/__init__.py
42
+ PytorchWildlife/models/detection/rtdetr_apache/megadetectorv6_apache.py
43
+ PytorchWildlife/models/detection/rtdetr_apache/rtdetr_apache_base.py
41
44
  PytorchWildlife/models/detection/ultralytics_based/Deepfaune.py
42
45
  PytorchWildlife/models/detection/ultralytics_based/__init__.py
43
46
  PytorchWildlife/models/detection/ultralytics_based/megadetectorv5.py
@@ -46,6 +49,11 @@ PytorchWildlife/models/detection/ultralytics_based/megadetectorv6_distributed.py
46
49
  PytorchWildlife/models/detection/ultralytics_based/yolov5_base.py
47
50
  PytorchWildlife/models/detection/ultralytics_based/yolov8_base.py
48
51
  PytorchWildlife/models/detection/ultralytics_based/yolov8_distributed.py
52
+ PytorchWildlife/models/detection/yolo_mit/__init__.py
53
+ PytorchWildlife/models/detection/yolo_mit/megadetectorv6_mit.py
54
+ PytorchWildlife/models/detection/yolo_mit/yolo_mit_base.py
55
+ PytorchWildlife/models/detection/yolo_mit/yolo/__init__.py
56
+ PytorchWildlife/models/detection/yolo_mit/yolo/config.py
49
57
  PytorchWildlife/utils/__init__.py
50
58
  PytorchWildlife/utils/misc.py
51
59
  PytorchWildlife/utils/post_process.py
@@ -20,16 +20,46 @@
20
20
 
21
21
  ## 📣 Announcements
22
22
 
23
- ### V 1.2.3
23
+ ### 🚀 We’re Open for Contributions!
24
24
 
25
- - We have fully recreated our [documentation page](https://microsoft.github.io/CameraTraps/) with [MKDocs](https://squidfunk.github.io/mkdocs-material/). Please take a look and let us know what you think! (Special thanks to @ss26 for creating the foundation of this documentation page!)
25
+ We’re excited to announce that **Pytorch-Wildlife** is now open to community contributions!
26
+ If you’d like to get involved and help improve the project, we’d love to have you on board.
26
27
 
27
- - We have released new MegaDetector V6 model weights. MDV6-yolov9-e and MDV6-yolov10-e are now retrained at 1280 input resolution to match the original V5 setup. In addition, we have added both compact and extra versions for [YOLOv9 MIT](https://github.com/MultimediaTechLab/YOLO?tab=readme-ov-file) and [RT-DETR Apache](https://github.com/lyuwenyu/RT-DETR/tree/main) implementations, expanding the range of V6 options for different deployment needs.
28
+ 👉 **Check out our Contribution Guidelines:**
28
29
 
29
- - Our [Model Zoo](https://microsoft.github.io/CameraTraps/model_zoo/megadetector/) now includes new performance numbers evaluated using [pycocotools](https://pypi.org/project/pycocotools/), enabling easier and more standardized comparisons with MIT and Apache models. All metrics are reported on 1280-sized input images to ensure consistency across versions. While V5 and V6 now deliver comparable performance, V6 models are still significantly smaller. Model weights for all versions, including MIT and Apache variants, are available for download, and we’ll be releasing the inference code for MIT and Apache models soon.
30
+ [📚 How to Participate](https://microsoft.github.io/CameraTraps/contribute/#how-to-participate)
30
31
 
31
- - To further improve V6 model generalization performance, our next iteration of V6 training will incorporate some new public camera trap datasets from LILA, including [Orinoquía Camera Traps](https://lila.science/datasets/orinoquia-camera-traps/) and other datasets that have bounding boxes and are currently not in V6's training pool.
32
+ You’ll find everything you need there — from how to pick an issue, to submitting your first pull request.
33
+ Let’s build this together! 🐾🌱
32
34
 
35
+ ### V 1.2.4
36
+
37
+ The inference code for the MIT YOLO and Apache RT‑DETR models is now available! To use either one, just load it like any other PyTorch‑Wildlife model:
38
+
39
+ ```python
40
+ from pw_detection import MegaDetectorV6MIT, MegaDetectorV6Apache
41
+
42
+ # MIT YOLO
43
+ detector = MegaDetectorV6MIT(
44
+ device=DEVICE,
45
+ pretrained=True,
46
+ version="MDV6-mit-yolov9-e"
47
+ )
48
+
49
+ # Apache RT‑DETR
50
+ detector = MegaDetectorV6Apache(
51
+ device=DEVICE,
52
+ pretrained=True,
53
+ version="MDV6-apa-rtdetr-e"
54
+ )
55
+ ```
56
+ Valid versions:
57
+ - MDV6-mit-yolov9-c
58
+ - MDV6-mit-yolov9-e
59
+ - MDV6-apa-rtdetr-c
60
+ - MDV6-apa-rtdetr-e
61
+
62
+ You can also try out the full pipeline using the `detection_classification_pipeline_demo.py` script in the demo folder.
33
63
 
34
64
  #### Previous versions:
35
65
  - [What's New](https://microsoft.github.io/CameraTraps/releases/release_notes/)
@@ -4,12 +4,12 @@ with open('README.md', encoding="utf8") as file:
4
4
  long_description = file.read()
5
5
  setup(
6
6
  name='PytorchWildlife',
7
- version='1.2.3',
7
+ version='1.2.4',
8
8
  packages=find_packages(),
9
9
  url='https://github.com/microsoft/CameraTraps/',
10
10
  license='MIT',
11
11
  author='Andres Hernandez, Zhongqi Miao, Daniela Ruiz Lopez, Isai Daniel Chacon Silva',
12
- author_email='v-herandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com',
12
+ author_email='v-hernandres@microsoft.com, zhongqimiao@microsoft.com, v-druizlopez@microsoft.com, v-ichaconsil@microsoft.com',
13
13
  description='a PyTorch Collaborative Deep Learning Framework for Conservation.',
14
14
  long_description=long_description,
15
15
  long_description_content_type='text/markdown',
@@ -1,2 +0,0 @@
1
- from .ultralytics_based import *
2
- from .herdnet import *