ibbi 0.0.0__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.
ibbi-0.0.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Chris
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
ibbi-0.0.0/PKG-INFO ADDED
@@ -0,0 +1,200 @@
1
+ Metadata-Version: 2.3
2
+ Name: ibbi
3
+ Version: 0.0.0
4
+ Summary: A package for bark and ambrosia beetle identification.
5
+ License: MIT
6
+ Author: G. Christopher Marais
7
+ Requires-Python: >=3.11,<4.0
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: huggingface-hub (>=0.32.3,<0.33.0)
14
+ Requires-Dist: ipywidgets (>=8.1.7,<9.0.0)
15
+ Requires-Dist: numpy (>=2.2.6,<3.0.0)
16
+ Requires-Dist: pandas (>=2.3.0,<3.0.0)
17
+ Requires-Dist: pillow (>=11.2.1,<12.0.0)
18
+ Requires-Dist: ultralytics (==8.3.139)
19
+ Description-Content-Type: text/markdown
20
+
21
+ # Intelligent Bark Beetle Identifier (IBBI)
22
+
23
+ <!-- [![JOSS submission](https://joss.theoj.org/papers/10.21105/joss.01234/status.svg)](https://joss.theoj.org/papers/10.21105/joss.01234) -->
24
+ [![PyPI version](https://badge.fury.io/py/ibbi.svg)](https://badge.fury.io/py/ibbi)
25
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
26
+
27
+ **IBBI** is a Python package that provides a simple and unified interface for detecting and classifying bark and ambrosia beetles from images using state-of-the-art computer vision models.
28
+
29
+ This package is designed to support entomological research by automating the laborious task of beetle identification, enabling high-throughput data analysis for ecological studies, pest management, and biodiversity monitoring. The core models are built on multiple different architectures and are made easily accessible through a simple Python API.
30
+
31
+ ### Motivation
32
+
33
+ The ability to accurately identify bark and ambrosia beetles is critical for forest health and pest management. However, traditional methods face significant challenges:
34
+
35
+ * **They are slow and time-consuming.**
36
+ * **They require highly specialized expertise.**
37
+ * **They create a bottleneck for large-scale research.**
38
+
39
+ The IBBI package provides a powerful, modern solution to overcome these obstacles:
40
+
41
+ * It uses **pre-trained, open-source models** for rapid analysis.
42
+ * It **automates both detection and classification** from images.
43
+ * It **lowers the barrier to entry**, enabling faster and more extensive data collection for all researchers.
44
+
45
+ ---
46
+
47
+ ## Table of Contents
48
+
49
+ - [Intelligent Bark Beetle Identifier (IBBI)](#intelligent-bark-beetle-identifier-ibbi)
50
+ - [Motivation](#motivation)
51
+ - [Table of Contents](#table-of-contents)
52
+ - [Installation](#installation)
53
+ - [Quick Start](#quick-start)
54
+ - [Available Models](#available-models)
55
+ - [Model Training Workflow](#model-training-workflow)
56
+ - [How to Contribute](#how-to-contribute)
57
+ - [License](#license)
58
+
59
+ ---
60
+
61
+ ## Installation
62
+
63
+ This package requires PyTorch. For compatibility with your specific hardware (e.g., CUDA-enabled GPU), please install PyTorch *before* installing `ibbi`.
64
+
65
+ **1. Install PyTorch**
66
+
67
+ Follow the official instructions at **[pytorch.org](https://pytorch.org/get-started/locally/)** to install the correct version for your system (OS, package manager, and CUDA version).
68
+
69
+ **2. Install IBBI**
70
+
71
+ Once PyTorch is installed, you can install the package directly from PyPI:
72
+
73
+ ```bash
74
+ pip install ibbi
75
+ ````
76
+
77
+ -----
78
+
79
+ ## Quick Start
80
+
81
+ Using IBBI is straightforward. You can load a pre-trained model for either detection or classification and immediately use it for inference on your images.
82
+
83
+ ```python
84
+ import ibbi
85
+ from PIL import Image
86
+
87
+ # Load an image
88
+ image = Image.open("path/to/your/beetle_image.jpg")
89
+
90
+ # 1. Load a pretrained object detection model or a classification model
91
+ detector = ibbi.create_model("yolov10x_bb_detect_model", pretrained=True)
92
+ classifier = ibbi.create_model("yolov10x_bb_classify_model", pretrained=True)
93
+
94
+ # 2. Run prediction to get class probabilities and/or bounding boxes
95
+ # The results will be the detected bounding box coordinates, confidence scores, and class labels
96
+ detection_results = detector.predict(image)
97
+ classification_results = classifier.predict(image)
98
+
99
+ # 3. You can also extract deep features from all models for other tasks
100
+ # The results will be a tensor of features
101
+ features = classifier.extract_features(image)
102
+
103
+ ```
104
+
105
+ For a more detailed, hands-on demonstration, please see the example notebook located in the repository: `notebooks/example.ipynb`.
106
+
107
+ -----
108
+
109
+ ## Available Models
110
+
111
+ The package provides a factory function `create_model()` to access the following pre-trained models from Huggingface Hub:
112
+
113
+ | Model Name | Task | Pretrained Weights Repository | Model Size (Params) | mAP@0.5 | mAP@[.5:.95] |
114
+ |----------------------------|------------------|--------------------------------------------|---------------------|---------|--------------|
115
+ | yolov10x_bb_detect_model | Object Detection | ChristopherMarais/ibbi_yolov10_od_20250601 | 29.5M | N/A | N/A |
116
+ | yolov10x_bb_classify_model | Classification | ChristopherMarais/ibbi_yolov10_c_20250608 | 29.5M | N/A | N/A |
117
+
118
+ A detailed list of available models and their Hugging Face repositories can be found in the [ibbi_model_summary.csv](./docs/assets/data/ibbi_model_summary.csv) file.
119
+
120
+ -----
121
+
122
+ ## Model Training Workflow
123
+
124
+ The models included in this package were trained using a standardized data flow on a dataset of bark and ambrosia beetle images from multiple different sources to include 63 different species. A list of all the species the current set of classification models were trained on can be found in the [ibbi_species_table.csv](./docs/assets/data/ibbi_species_table.csv) file.
125
+
126
+ <p align="center">
127
+ <img src="./docs/assets/images/data_flow_ibbi.png" alt="My training workflow">
128
+ </p>
129
+
130
+ **1. Data Collection & Aggregation:**
131
+
132
+ * An initial dataset of 54,421 images was compiled from diverse sources, including field photography from [barkbeetles.info](https://www.barkbeetles.info), lab-based specimen photography, and images from iNaturalist.
133
+ * This aggregated dataset contained a mix of labeled and unlabeled images. Initially, 17,689 images had species-level labels, while 36,732 had no annotations.
134
+
135
+ **2. Annotation with Human-in-the-Loop:**
136
+
137
+ * To create high-quality localization data, a zero-shot object detection model (GroundingDINO) was first used to generate preliminary bounding boxes for the beetles in the images.
138
+ * Crucially, these automated annotations were then manually reviewed and refined by experts to ensure their accuracy and consistency, creating a reliable ground truth for training.
139
+
140
+ **3. Dataset Preparation and Splitting:**
141
+
142
+ * A dedicated test set of 2,031 images was created by selecting images only from species with at least 50 representatives. This ensures a balanced and fair evaluation.
143
+ * The remaining annotated data was split into two distinct training sets based on the task:
144
+ * Object Detection Training Set (35,274 images): All images with verified bounding boxes (excluding the test set) were used to train the general beetle detection models. This larger dataset helps the models learn to accurately localize beetles under various conditions.
145
+ * Classification Training Set (11,507 images): A filtered subset containing images with both verified bounding boxes and species-level labels was used to train the fine-grained classification models.
146
+
147
+ **4. Model Training and Fine-Tuning:**
148
+
149
+ * Pre-trained model architectures were fine-tuned for each specific task:
150
+ * Object Detection models were trained on the larger localization dataset to become expert beetle detectors.
151
+ * Classification models were trained on the fully labeled dataset to specialize in identifying different beetle species.
152
+ * Data augmentation techniques, including random rotations, scaling, color jitter, and mosaic augmentation, were used throughout training to improve model robustness and prevent over-fitting.
153
+
154
+ **5. Evaluation and Deployment:**
155
+
156
+ * The performance of all trained models was rigorously measured against the held-out test set to ensure high accuracy for both detection and classification tasks.
157
+ * The final, best-performing model weights were saved and uploaded to Hugging Face Hub, from where the `ibbi` package automatically downloads them, making them easily accessible to researchers via a simple API.
158
+
159
+ -----
160
+
161
+ ## How to Contribute
162
+
163
+ Contributions are welcome\! If you would like to improve IBBI, please follow these steps:
164
+
165
+ 1. Clone this repository.
166
+ 2. Create a Conda environment and activate it:
167
+ ```bash
168
+ conda env create -f environment.yml
169
+ conda activate IBBI
170
+ ```
171
+ 3. Install dependencies using Poetry and set up pre-commit hooks:
172
+ ```bash
173
+ pip install torch torchvision torchaudio # Ensure PyTorch is installed first
174
+ poetry config virtualenvs.create false --local
175
+ poetry install
176
+ poetry run pre-commit install
177
+ ```
178
+ 4. Create a new branch for your feature or bug fix.
179
+ 5. Commit your changes and open a pull request.
180
+
181
+ To add new dependencies, use `poetry add <package-name>` for the main package or `poetry add --group dev <package-name>` for development dependencies.
182
+
183
+ -----
184
+
185
+ <!-- ## Citing IBBI
186
+
187
+ If you use IBBI in your research, please cite the JOSS paper.
188
+
189
+ **(Placeholder) To be added upon acceptance:**
190
+
191
+ > Marais, C., et al., (2025). IBBI: Intelligent Bark Beetle Identifier. Journal of Open Source Software, X(XX), XXXX. https://www.google.com/search?q=https://doi.org/XX.XXXXX/joss.XXXXX
192
+
193
+ You can also cite the specific version of the software archive using the DOI provided by Zenodo/figshare.
194
+
195
+ ----- -->
196
+
197
+ ## License
198
+
199
+ This project is licensed under the terms of the MIT License. See the `LICENSE` file for details.
200
+
ibbi-0.0.0/README.md ADDED
@@ -0,0 +1,179 @@
1
+ # Intelligent Bark Beetle Identifier (IBBI)
2
+
3
+ <!-- [![JOSS submission](https://joss.theoj.org/papers/10.21105/joss.01234/status.svg)](https://joss.theoj.org/papers/10.21105/joss.01234) -->
4
+ [![PyPI version](https://badge.fury.io/py/ibbi.svg)](https://badge.fury.io/py/ibbi)
5
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
6
+
7
+ **IBBI** is a Python package that provides a simple and unified interface for detecting and classifying bark and ambrosia beetles from images using state-of-the-art computer vision models.
8
+
9
+ This package is designed to support entomological research by automating the laborious task of beetle identification, enabling high-throughput data analysis for ecological studies, pest management, and biodiversity monitoring. The core models are built on multiple different architectures and are made easily accessible through a simple Python API.
10
+
11
+ ### Motivation
12
+
13
+ The ability to accurately identify bark and ambrosia beetles is critical for forest health and pest management. However, traditional methods face significant challenges:
14
+
15
+ * **They are slow and time-consuming.**
16
+ * **They require highly specialized expertise.**
17
+ * **They create a bottleneck for large-scale research.**
18
+
19
+ The IBBI package provides a powerful, modern solution to overcome these obstacles:
20
+
21
+ * It uses **pre-trained, open-source models** for rapid analysis.
22
+ * It **automates both detection and classification** from images.
23
+ * It **lowers the barrier to entry**, enabling faster and more extensive data collection for all researchers.
24
+
25
+ ---
26
+
27
+ ## Table of Contents
28
+
29
+ - [Intelligent Bark Beetle Identifier (IBBI)](#intelligent-bark-beetle-identifier-ibbi)
30
+ - [Motivation](#motivation)
31
+ - [Table of Contents](#table-of-contents)
32
+ - [Installation](#installation)
33
+ - [Quick Start](#quick-start)
34
+ - [Available Models](#available-models)
35
+ - [Model Training Workflow](#model-training-workflow)
36
+ - [How to Contribute](#how-to-contribute)
37
+ - [License](#license)
38
+
39
+ ---
40
+
41
+ ## Installation
42
+
43
+ This package requires PyTorch. For compatibility with your specific hardware (e.g., CUDA-enabled GPU), please install PyTorch *before* installing `ibbi`.
44
+
45
+ **1. Install PyTorch**
46
+
47
+ Follow the official instructions at **[pytorch.org](https://pytorch.org/get-started/locally/)** to install the correct version for your system (OS, package manager, and CUDA version).
48
+
49
+ **2. Install IBBI**
50
+
51
+ Once PyTorch is installed, you can install the package directly from PyPI:
52
+
53
+ ```bash
54
+ pip install ibbi
55
+ ````
56
+
57
+ -----
58
+
59
+ ## Quick Start
60
+
61
+ Using IBBI is straightforward. You can load a pre-trained model for either detection or classification and immediately use it for inference on your images.
62
+
63
+ ```python
64
+ import ibbi
65
+ from PIL import Image
66
+
67
+ # Load an image
68
+ image = Image.open("path/to/your/beetle_image.jpg")
69
+
70
+ # 1. Load a pretrained object detection model or a classification model
71
+ detector = ibbi.create_model("yolov10x_bb_detect_model", pretrained=True)
72
+ classifier = ibbi.create_model("yolov10x_bb_classify_model", pretrained=True)
73
+
74
+ # 2. Run prediction to get class probabilities and/or bounding boxes
75
+ # The results will be the detected bounding box coordinates, confidence scores, and class labels
76
+ detection_results = detector.predict(image)
77
+ classification_results = classifier.predict(image)
78
+
79
+ # 3. You can also extract deep features from all models for other tasks
80
+ # The results will be a tensor of features
81
+ features = classifier.extract_features(image)
82
+
83
+ ```
84
+
85
+ For a more detailed, hands-on demonstration, please see the example notebook located in the repository: `notebooks/example.ipynb`.
86
+
87
+ -----
88
+
89
+ ## Available Models
90
+
91
+ The package provides a factory function `create_model()` to access the following pre-trained models from Huggingface Hub:
92
+
93
+ | Model Name | Task | Pretrained Weights Repository | Model Size (Params) | mAP@0.5 | mAP@[.5:.95] |
94
+ |----------------------------|------------------|--------------------------------------------|---------------------|---------|--------------|
95
+ | yolov10x_bb_detect_model | Object Detection | ChristopherMarais/ibbi_yolov10_od_20250601 | 29.5M | N/A | N/A |
96
+ | yolov10x_bb_classify_model | Classification | ChristopherMarais/ibbi_yolov10_c_20250608 | 29.5M | N/A | N/A |
97
+
98
+ A detailed list of available models and their Hugging Face repositories can be found in the [ibbi_model_summary.csv](./docs/assets/data/ibbi_model_summary.csv) file.
99
+
100
+ -----
101
+
102
+ ## Model Training Workflow
103
+
104
+ The models included in this package were trained using a standardized data flow on a dataset of bark and ambrosia beetle images from multiple different sources to include 63 different species. A list of all the species the current set of classification models were trained on can be found in the [ibbi_species_table.csv](./docs/assets/data/ibbi_species_table.csv) file.
105
+
106
+ <p align="center">
107
+ <img src="./docs/assets/images/data_flow_ibbi.png" alt="My training workflow">
108
+ </p>
109
+
110
+ **1. Data Collection & Aggregation:**
111
+
112
+ * An initial dataset of 54,421 images was compiled from diverse sources, including field photography from [barkbeetles.info](https://www.barkbeetles.info), lab-based specimen photography, and images from iNaturalist.
113
+ * This aggregated dataset contained a mix of labeled and unlabeled images. Initially, 17,689 images had species-level labels, while 36,732 had no annotations.
114
+
115
+ **2. Annotation with Human-in-the-Loop:**
116
+
117
+ * To create high-quality localization data, a zero-shot object detection model (GroundingDINO) was first used to generate preliminary bounding boxes for the beetles in the images.
118
+ * Crucially, these automated annotations were then manually reviewed and refined by experts to ensure their accuracy and consistency, creating a reliable ground truth for training.
119
+
120
+ **3. Dataset Preparation and Splitting:**
121
+
122
+ * A dedicated test set of 2,031 images was created by selecting images only from species with at least 50 representatives. This ensures a balanced and fair evaluation.
123
+ * The remaining annotated data was split into two distinct training sets based on the task:
124
+ * Object Detection Training Set (35,274 images): All images with verified bounding boxes (excluding the test set) were used to train the general beetle detection models. This larger dataset helps the models learn to accurately localize beetles under various conditions.
125
+ * Classification Training Set (11,507 images): A filtered subset containing images with both verified bounding boxes and species-level labels was used to train the fine-grained classification models.
126
+
127
+ **4. Model Training and Fine-Tuning:**
128
+
129
+ * Pre-trained model architectures were fine-tuned for each specific task:
130
+ * Object Detection models were trained on the larger localization dataset to become expert beetle detectors.
131
+ * Classification models were trained on the fully labeled dataset to specialize in identifying different beetle species.
132
+ * Data augmentation techniques, including random rotations, scaling, color jitter, and mosaic augmentation, were used throughout training to improve model robustness and prevent over-fitting.
133
+
134
+ **5. Evaluation and Deployment:**
135
+
136
+ * The performance of all trained models was rigorously measured against the held-out test set to ensure high accuracy for both detection and classification tasks.
137
+ * The final, best-performing model weights were saved and uploaded to Hugging Face Hub, from where the `ibbi` package automatically downloads them, making them easily accessible to researchers via a simple API.
138
+
139
+ -----
140
+
141
+ ## How to Contribute
142
+
143
+ Contributions are welcome\! If you would like to improve IBBI, please follow these steps:
144
+
145
+ 1. Clone this repository.
146
+ 2. Create a Conda environment and activate it:
147
+ ```bash
148
+ conda env create -f environment.yml
149
+ conda activate IBBI
150
+ ```
151
+ 3. Install dependencies using Poetry and set up pre-commit hooks:
152
+ ```bash
153
+ pip install torch torchvision torchaudio # Ensure PyTorch is installed first
154
+ poetry config virtualenvs.create false --local
155
+ poetry install
156
+ poetry run pre-commit install
157
+ ```
158
+ 4. Create a new branch for your feature or bug fix.
159
+ 5. Commit your changes and open a pull request.
160
+
161
+ To add new dependencies, use `poetry add <package-name>` for the main package or `poetry add --group dev <package-name>` for development dependencies.
162
+
163
+ -----
164
+
165
+ <!-- ## Citing IBBI
166
+
167
+ If you use IBBI in your research, please cite the JOSS paper.
168
+
169
+ **(Placeholder) To be added upon acceptance:**
170
+
171
+ > Marais, C., et al., (2025). IBBI: Intelligent Bark Beetle Identifier. Journal of Open Source Software, X(XX), XXXX. https://www.google.com/search?q=https://doi.org/XX.XXXXX/joss.XXXXX
172
+
173
+ You can also cite the specific version of the software archive using the DOI provided by Zenodo/figshare.
174
+
175
+ ----- -->
176
+
177
+ ## License
178
+
179
+ This project is licensed under the terms of the MIT License. See the `LICENSE` file for details.
@@ -0,0 +1,84 @@
1
+ [tool.poetry]
2
+ name = "ibbi"
3
+ version = "0.0.0"
4
+ description = "A package for bark and ambrosia beetle identification."
5
+ authors = ["G. Christopher Marais"]
6
+ license = "MIT"
7
+ readme = "README.md"
8
+ packages = [{ include = "ibbi", from = "src" }]
9
+
10
+ [tool.poetry.dependencies]
11
+ python = ">=3.11,<4.0"
12
+ huggingface-hub = ">=0.32.3,<0.33.0"
13
+ ultralytics = "8.3.139"
14
+ pandas = "^2.3.0"
15
+ numpy = "^2.2.6"
16
+ pillow = "^11.2.1"
17
+ ipywidgets = "^8.1.7"
18
+
19
+ [tool.poetry.group.dev.dependencies]
20
+ ruff = "^0.11.10"
21
+ pyright = "^1.1.401"
22
+ pytest = "^8.3.5"
23
+ pre-commit = "^4.2.0"
24
+ mkdocs = "^1.6.1"
25
+ mkdocs-material = "^9.6.14"
26
+ jupyterlab = "^4.4.2"
27
+ isort = "^6.0.1"
28
+ black = "^25.1.0"
29
+ notebook = "^7.4.2"
30
+ ipykernel = "^6.29.5"
31
+ ipywidgets = "^8.1.7"
32
+ mkdocstrings = "^0.29.1"
33
+ mkdocstrings-python = "^1.16.12"
34
+ poetry-dynamic-versioning = "^1.8.2"
35
+
36
+ [build-system]
37
+ requires = ["poetry-core>=1.0.0", "poetry-dynamic-versioning"]
38
+ build-backend = "poetry.core.masonry.api"
39
+
40
+
41
+ # --- Tool Configurations ---
42
+
43
+ [tool.ruff]
44
+ line-length = 120
45
+
46
+ [tool.ruff.lint]
47
+ select = ["A", "B", "C4", "E", "W", "F", "I", "UP", "RUF"]
48
+ ignore = [
49
+ "B007",
50
+ "E721",
51
+ "RUF015",
52
+ "UP038",
53
+ "C401",
54
+ "C408",
55
+ "C409",
56
+ ]
57
+
58
+ [tool.ruff.format]
59
+ quote-style = "double"
60
+
61
+ [tool.ruff.lint.isort]
62
+ known-first-party = ["ibbi"]
63
+
64
+
65
+ [tool.pyright]
66
+ include = ["src/ibbi", "tests"]
67
+ exclude = ["**/node_modules", "**/__pycache__"]
68
+ stubPath = "src/stubs"
69
+ reportMissingImports = true
70
+ pythonVersion = "3.11"
71
+
72
+
73
+ [tool.pytest.ini_options]
74
+ minversion = "6.0"
75
+ addopts = "-ra -q"
76
+ testpaths = [
77
+ "tests",
78
+ ]
79
+
80
+ [tool.poetry-dynamic-versioning]
81
+ enable = true
82
+ vcs = "git"
83
+ style = "pep440"
84
+ format-latest = "{base}.dev{distance}"
@@ -0,0 +1,68 @@
1
+ # src/ibbi/__init__.py
2
+
3
+ """
4
+ Main initialization file for the ibbi package.
5
+
6
+ This file exposes the primary user-facing function, `create_model`, which acts as a
7
+ factory for instantiating various beetle detection and classification models.
8
+ """
9
+
10
+ from typing import Any, Union
11
+
12
+ # --- IMPORTANT ---
13
+ # Import the model definition files first.
14
+ # This ensures that the @register_model decorator runs and populates
15
+ # the model_registry before we try to use it.
16
+ from .models import classification, detection # noqa: F401
17
+
18
+ # Now, import the registry that has been populated.
19
+ from .models._registry import model_registry
20
+ from .models.classification import YOLOv10BeetleClassifier
21
+ from .models.detection import YOLOv10BeetleDetector
22
+
23
+ # Define a type hint for the models that can be returned
24
+ ModelType = Union[YOLOv10BeetleDetector, YOLOv10BeetleClassifier]
25
+
26
+
27
+ def create_model(model_name: str, pretrained: bool = False, **kwargs: Any) -> ModelType:
28
+ """
29
+ Creates a model from a name.
30
+
31
+ This factory function is the main entry point for users of the package.
32
+ It looks up the requested model in the registry, downloads pretrained
33
+ weights from the Hugging Face Hub if requested, and returns an
34
+ instantiated model object.
35
+
36
+ Args:
37
+ model_name (str): Name of the model to create.
38
+ pretrained (bool): Whether to load pretrained weights from the Hugging Face Hub.
39
+ Defaults to False.
40
+ **kwargs (Any): Extra arguments to pass to the model-creating function.
41
+
42
+ Returns:
43
+ ModelType: An instance of the requested model (e.g., YOLOv10BeetleDetector or
44
+ YOLOv10BeetleClassifier).
45
+
46
+ Raises:
47
+ KeyError: If the requested `model_name` is not found in the model registry.
48
+
49
+ Example:
50
+ ```python
51
+ import ibbi
52
+
53
+ # Create a pretrained detection model
54
+ detector = ibbi.create_model("yolov10x_bb_detect_model", pretrained=True)
55
+
56
+ # Create a pretrained classification model
57
+ classifier = ibbi.create_model("yolov10x_bb_classify_model", pretrained=True)
58
+ ```
59
+ """
60
+ if model_name not in model_registry:
61
+ available = ", ".join(model_registry.keys())
62
+ raise KeyError(f"Model '{model_name}' not found. Available models: [{available}]")
63
+
64
+ # Look up the factory function in the registry and call it
65
+ model_factory = model_registry[model_name]
66
+ model = model_factory(pretrained=pretrained, **kwargs)
67
+
68
+ return model
File without changes
File without changes
File without changes
@@ -0,0 +1,6 @@
1
+ # src/ibbi/models/__init__.py
2
+
3
+ from .classification import yolov10x_bb_classify_model
4
+ from .detection import yolov10x_bb_detect_model
5
+
6
+ __all__ = ["yolov10x_bb_detect_model", "yolov10x_bb_classify_model"]
File without changes
File without changes
@@ -0,0 +1,24 @@
1
+ # 1. The registry itself: a dictionary to hold your models.
2
+ model_registry = {}
3
+
4
+
5
+ def register_model(fn):
6
+ """
7
+ # 2. A decorator function to easily add models to the registry.
8
+
9
+ This function takes a model-creating function (like your
10
+ `yolov10x_bb_detect_model` function) and adds it to the
11
+ `model_registry` dictionary. The function's name becomes the key.
12
+
13
+ Args:
14
+ fn: The model-creating function to register.
15
+
16
+ Returns:
17
+ The original function, after it has been registered.
18
+ """
19
+ model_name = fn.__name__
20
+ if model_name in model_registry:
21
+ raise ValueError(f"Model {model_name} is already registered.")
22
+
23
+ model_registry[model_name] = fn
24
+ return fn
@@ -0,0 +1,102 @@
1
+ # src/ibbi/models/classification.py
2
+
3
+ """
4
+ Beetle classification models.
5
+ """
6
+
7
+ import torch
8
+ from ultralytics import YOLO
9
+
10
+ from ..utils.hub import download_from_hf_hub
11
+ from ._registry import register_model
12
+
13
+
14
+ class YOLOv10BeetleClassifier:
15
+ """
16
+ A wrapper class for the YOLOv10 beetle classifier model.
17
+
18
+ Provides a clean interface for image classification and feature extraction.
19
+
20
+ Attributes:
21
+ model (YOLO): The underlying `ultralytics.YOLO` model instance.
22
+ device (str): The compute device ('cuda' or 'cpu') the model is loaded on.
23
+ """
24
+
25
+ def __init__(self, model_path: str):
26
+ """
27
+ Initializes the YOLOv10BeetleClassifier.
28
+
29
+ Args:
30
+ model_path (str): The local path to the .pt model file.
31
+ """
32
+ self.model = YOLO(model_path)
33
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
34
+ self.model.to(self.device)
35
+ print(f"Model loaded on device: {self.device}")
36
+
37
+ def predict(self, image, **kwargs):
38
+ """
39
+ Performs image classification on an image.
40
+
41
+ This method takes an image and returns the predicted class probabilities.
42
+ Accepts any arguments that the `ultralytics.YOLO.predict` method accepts.
43
+
44
+ Args:
45
+ image: The input image(s). Can be a path, URL, numpy array, PIL image, etc.
46
+ **kwargs: Additional keyword arguments to pass to the underlying
47
+ `predict` method of the YOLO model.
48
+
49
+ Returns:
50
+ A list of `ultralytics.engine.results.Results` objects containing the
51
+ predicted class probabilities.
52
+ """
53
+ print("Running image classification (predict)...")
54
+ return self.model.predict(image, **kwargs)
55
+
56
+ def extract_features(self, image, **kwargs):
57
+ """
58
+ Extracts deep features from the backbone of the model for an image.
59
+
60
+ This is useful for downstream tasks like clustering or similarity search.
61
+
62
+ Args:
63
+ image: The input image(s).
64
+ **kwargs: Additional keyword arguments to pass to the underlying
65
+ `embed` method of the YOLO model.
66
+
67
+ Returns:
68
+ A tensor of features if successful, otherwise None.
69
+ """
70
+ print("Extracting features (embed)...")
71
+ features = self.model.embed(image, **kwargs)
72
+ if features:
73
+ return features[0]
74
+ return None
75
+
76
+
77
+ @register_model
78
+ def yolov10x_bb_classify_model(pretrained: bool = False, **kwargs):
79
+ """
80
+ Factory function for the YOLOv10 beetle classifier.
81
+
82
+ Instantiates a `YOLOv10BeetleClassifier` model. If `pretrained` is True,
83
+ it downloads the official weights from the Hugging Face Hub.
84
+
85
+ Args:
86
+ pretrained (bool): If True, downloads pretrained weights.
87
+ Defaults to False.
88
+ **kwargs: Additional arguments (not currently used).
89
+
90
+ Returns:
91
+ YOLOv10BeetleClassifier: An instance of the classifier class.
92
+ """
93
+ if pretrained:
94
+ repo_id = "ChristopherMarais/ibbi_yolov10_c_20250608"
95
+ filename = "model.pt"
96
+ local_weights_path = download_from_hf_hub(repo_id=repo_id, filename=filename)
97
+ else:
98
+ # Note: A non-pretrained YOLOv10x model is not meaningful for this task,
99
+ # but this path is kept for API consistency.
100
+ local_weights_path = "yolov10x.pt"
101
+
102
+ return YOLOv10BeetleClassifier(model_path=local_weights_path)
@@ -0,0 +1,103 @@
1
+ # src/ibbi/models/detection.py
2
+
3
+ """
4
+ Beetle detection models.
5
+ """
6
+
7
+ import torch
8
+ from ultralytics import YOLO
9
+
10
+ from ..utils.hub import download_from_hf_hub
11
+ from ._registry import register_model
12
+
13
+
14
+ class YOLOv10BeetleDetector:
15
+ """
16
+ A wrapper class for YOLOv10 beetle detection models.
17
+
18
+ This class provides a clean interface for performing object detection inference
19
+ and extracting deep features from images.
20
+
21
+ Attributes:
22
+ model (YOLO): The underlying `ultralytics.YOLO` model instance.
23
+ device (str): The compute device ('cuda' or 'cpu') the model is loaded on.
24
+ """
25
+
26
+ def __init__(self, model_path: str):
27
+ """
28
+ Initializes the YOLOv10BeetleDetector.
29
+
30
+ Args:
31
+ model_path (str): The local path to the pretrained `.pt` model file.
32
+ """
33
+ self.model = YOLO(model_path)
34
+ self.device = "cuda" if torch.cuda.is_available() else "cpu"
35
+ self.model.to(self.device)
36
+ print(f"Model loaded on device: {self.device}")
37
+
38
+ def predict(self, image, **kwargs):
39
+ """
40
+ Performs object detection inference on an image.
41
+
42
+ This method takes an image and returns the bounding box predictions.
43
+ Accepts any arguments that the `ultralytics.YOLO.predict` method accepts.
44
+
45
+ Args:
46
+ image: The input image(s). Can be a path, URL, numpy array, PIL image, etc.
47
+ **kwargs: Additional keyword arguments to pass to the underlying
48
+ `predict` method of the YOLO model.
49
+
50
+ Returns:
51
+ A list of `ultralytics.engine.results.Results` objects containing the
52
+ detected bounding boxes, confidence scores, and class labels.
53
+ """
54
+ print("Running object detection (predict)...")
55
+ return self.model.predict(image, **kwargs)
56
+
57
+ def extract_features(self, image, **kwargs):
58
+ """
59
+ Extracts deep features from the backbone of the model for an image.
60
+
61
+ This is useful for downstream tasks like clustering or similarity search.
62
+
63
+ Args:
64
+ image: The input image(s).
65
+ **kwargs: Additional keyword arguments to pass to the underlying
66
+ `embed` method of the YOLO model.
67
+
68
+ Returns:
69
+ A tensor of features if successful, otherwise None.
70
+ """
71
+ print("Extracting features (embed)...")
72
+ features = self.model.embed(image, **kwargs)
73
+ if features:
74
+ return features[0]
75
+ return None
76
+
77
+
78
+ @register_model
79
+ def yolov10x_bb_detect_model(pretrained: bool = False, **kwargs):
80
+ """
81
+ Factory function for the YOLOv10 beetle detector.
82
+
83
+ Instantiates a `YOLOv10BeetleDetector` model. If `pretrained` is True,
84
+ it downloads the official weights from the Hugging Face Hub.
85
+
86
+ Args:
87
+ pretrained (bool): If True, downloads pretrained weights.
88
+ Defaults to False.
89
+ **kwargs: Additional arguments (not currently used).
90
+
91
+ Returns:
92
+ YOLOv10BeetleDetector: An instance of the detector class.
93
+ """
94
+ if pretrained:
95
+ repo_id = "ChristopherMarais/ibbi_yolov10_od_20250601"
96
+ filename = "model.pt"
97
+ local_weights_path = download_from_hf_hub(repo_id=repo_id, filename=filename)
98
+ else:
99
+ # Note: A non-pretrained YOLOv10x model is not meaningful for this task,
100
+ # but this path is kept for API consistency.
101
+ local_weights_path = "yolov10x.pt"
102
+
103
+ return YOLOv10BeetleDetector(model_path=local_weights_path)
File without changes
@@ -0,0 +1,18 @@
1
+ from huggingface_hub import hf_hub_download
2
+
3
+
4
+ def download_from_hf_hub(repo_id: str, filename: str) -> str:
5
+ """
6
+ Downloads a model file from a Hugging Face Hub repository.
7
+
8
+ Args:
9
+ repo_id (str): The ID of the repository (e.g., "your-username/my-model").
10
+ filename (str): The name of the file to download from the repo.
11
+
12
+ Returns:
13
+ str: The local path to the downloaded file.
14
+ """
15
+ print(f"Downloading {filename} from Hugging Face hub repository '{repo_id}'...")
16
+ local_model_path = hf_hub_download(repo_id=repo_id, filename=filename)
17
+ print("Download complete. Model cached at:", local_model_path)
18
+ return local_model_path
File without changes