Skip to content

Note

Click here to download the full example code

Classifying Mosquito Species

This tutorial shows how to use the MosquitoClassifier from the CulicidaeLab library to perform species classification. We will cover:

  • Loading the classification model
  • Preparing an image
  • Running the model to get classification results
  • Visualizing and interpreting the results
  • Evaluating a classification prediction

Install the culicidaelab library if not already installed !pip install -q culicidaelab

1. Initialization

We start by initializing the MosquitoClassifier. The settings object will handle the configuration, and load_model=True will ensure the model is downloaded and loaded into memory right away.

import cv2
import re
import matplotlib.pyplot as plt
from pathlib import Path

from culicidaelab import MosquitoClassifier, get_settings

# Get settings instance
settings = get_settings()

# Instantiate the classifier and load the model
print("Initializing MosquitoClassifier and loading model...")
classifier = MosquitoClassifier(settings, load_model=True)
print("Model loaded successfully.")

# You can inspect the model's configuration directly from the settings object.
classifier_conf = settings.get_config("predictors.classifier")
print(f"\nLoaded model architecture: {classifier_conf.model_arch}")

Out:

Initializing MosquitoClassifier and loading model...
Model weights for 'classifier' not found. Attempting to download...
Ensuring destination directory exists: /home/runner/.local/share/culicidaelab/models/weights/classification
Downloaded weights to: /home/runner/.local/share/culicidaelab/models/weights/classification/culico-net-cls-v1-17.pkl
/opt/hostedtoolcache/Python/3.11.13/x64/lib/python3.11/site-packages/fastai/learner.py:455: UserWarning: load_learner` uses Python's insecure pickle module, which can execute malicious arbitrary code when loading. Only load files you trust.
If you only need to load model weights and optimizer state, use the safe `Learner.load` instead.
  warn("load_learner` uses Python's insecure pickle module, which can execute malicious arbitrary code when loading. Only load files you trust.\nIf you only need to load model weights and optimizer state, use the safe `Learner.load` instead.")
Model loaded successfully.

Loaded model architecture: tiny_vit_21m_224.in1k

Inspecting Model Classes

It's often useful to see which species the model was trained to recognize. The recommended way is to use the species_config.

species_map = settings.species_config.species_map
print("--- Model Classes (from settings) ---")
print(species_map)

Out:

--- Model Classes (from settings) ---
{0: 'Aedes aegypti', 1: 'Aedes albopictus', 2: 'Aedes canadensis', 3: 'Aedes dorsalis', 4: 'Aedes geniculatus', 5: 'Aedes koreicus', 6: 'Aedes triseriatus', 7: 'Aedes vexans', 8: 'Anopheles arabiensis', 9: 'Anopheles freeborni', 10: 'Anopheles sinensis', 11: 'Species not defined', 12: 'Culex inatomii', 13: 'Culex pipiens', 14: 'Culex quinquefasciatus', 15: 'Culex tritaeniorhynchus', 16: 'Culiseta annulata', 17: 'Culiseta longiareolata'}

2. Preparing an Image for Classification

Now, let's load a test image. The classifier expects an image in RGB format.

Load a test image

image_path = Path("test_imgs") / "640px-Aedes_aegypti.jpg"
image = cv2.imread(str(image_path))
if image is None:
    raise ValueError(f"Could not load image from {image_path}")

# Convert from BGR (OpenCV's default) to RGB
image_rgb = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Display the input image
plt.figure(figsize=(8, 8))
plt.imshow(image_rgb)
plt.axis("off")
plt.title("Input Image")
plt.show()

Input Image

3. Running Classification and Interpreting Results

The predict method returns a list of tuples, where each tuple contains a (species_name, confidence_score), sorted by confidence.

Run classification

predictions = classifier.predict(image_rgb)

# Let's print the top 5 predictions
print("--- Top 5 Predictions ---")
for species, prob in predictions[:5]:
    print(f"{species}: {prob:.2%}")

Out:


 |----------------------------------------| 0.00% [0/1 00:00<?]

 |████████████████████████████████████████| 100.00% [1/1 00:00<00:00]




--- Top 5 Predictions ---
Species not defined: 100.00%
Aedes geniculatus: 0.00%
Aedes canadensis: 0.00%
Culiseta longiareolata: 0.00%
Aedes albopictus: 0.00%

4. Visualizing Classification Results

CulicidaeLab provides two easy ways to visualize the results: 1. A bar plot showing the confidence for all classes. 2. An annotated image with the top predictions overlaid.

Get all species names and their predicted probabilities

species_names = [p[0] for p in predictions]
probabilities = [p[1] for p in predictions]
conf_threshold = settings.get_config("predictors.classifier.confidence")

# Create a bar plot of the probabilities
plt.figure(figsize=(12, 7))
bars = plt.barh(species_names[::-1], probabilities[::-1])  # Reverse to show highest on top

# Color bars based on confidence
for i, prob in enumerate(probabilities[::-1]):
    bars[i].set_color("teal" if prob >= conf_threshold else "lightgray")

plt.axvline(x=conf_threshold, color="r", linestyle="--", label=f"Confidence Threshold ({conf_threshold:.0%})")
plt.xlabel("Probability")
plt.title("Species Classification Probabilities")
plt.legend()
plt.tight_layout()
plt.show()

Species Classification Probabilities

The visualize method overlays the top predictions directly onto the image.

annotated_image = classifier.visualize(image_rgb, predictions)

# Display the annotated image
plt.figure(figsize=(10, 10))
plt.imshow(annotated_image)
plt.axis("off")
plt.title("Classification Result with Overlay")
plt.show()

Classification Result with Overlay

5. Evaluating a Prediction

To measure performance, you can evaluate a prediction against a known ground truth label. This returns key metrics like accuracy and top-5 correctness.

The true label for our test image is 'aedes_aegypti'

ground_truth_label = "aedes_aegypti"

# You can evaluate from a pre-computed prediction...
print(f"--- Evaluating prediction against ground truth '{ground_truth_label}' ---")
metrics_from_prediction = classifier.evaluate(ground_truth_label, prediction=predictions)
print(f"Metrics from prediction: {metrics_from_prediction}")

# ... or directly from the input image.
metrics_from_image = classifier.evaluate(ground_truth_label, input_data=image_rgb)
print(f"Metrics from image: {metrics_from_image}")

Out:

--- Evaluating prediction against ground truth 'aedes_aegypti' ---
Metrics from prediction: {'accuracy': 0.0, 'confidence': 0.9999973773956299, 'top_1_correct': 0.0, 'top_5_correct': 0.0}

 |----------------------------------------| 0.00% [0/1 00:00<?]

 |████████████████████████████████████████| 100.00% [1/1 00:00<00:00]




Metrics from image: {'accuracy': 0.0, 'confidence': 0.9999973773956299, 'top_1_correct': 0.0, 'top_5_correct': 0.0}

6. Batch Classification

Just like the detector, the classifier can process a batch of images for improved performance.

image_dir = Path("test_imgs")
pattern = re.compile(r"\.(jpg|jpeg|png)$", re.IGNORECASE)
image_paths = [path for path in image_dir.iterdir() if path.is_file() and pattern.search(str(path))]

try:
    batch = [cv2.cvtColor(cv2.imread(str(path)), cv2.COLOR_BGR2RGB) for path in image_paths]
    print(f"\n--- Classifying a batch of {len(batch)} images ---")
except Exception as e:
    print(f"An error occurred while reading images: {e}")
    batch = []

classifier_batch_result = classifier.predict_batch(batch, show_progress=True)
print("\n--- Batch Classification Results ---")
for i, single_image_preds in enumerate(classifier_batch_result):
    top_pred_species = single_image_preds[0][0]
    top_pred_conf = single_image_preds[0][1]
    print(
        f"  - Image '{image_paths[i].name}': ",
        f"Top prediction is '{top_pred_species}' with {top_pred_conf:.2%} confidence.",
    )

Out:

--- Classifying a batch of 3 images ---

 |----------------------------------------| 0.00% [0/1 00:00<?]

 |████████████████████████████████████████| 100.00% [1/1 00:02<00:00]





 |----------------------------------------| 0.00% [0/1 00:00<?]

 |████████████████████████████████████████| 100.00% [1/1 00:00<00:00]





 |----------------------------------------| 0.00% [0/1 00:00<?]

 |████████████████████████████████████████| 100.00% [1/1 00:00<00:00]




--- Batch Classification Results ---
  - Image 'aedes-aegipy.png':  Top prediction is 'Species not defined' with 100.00% confidence.
  - Image '9bd8bd325307035016959cb82376e09b.jpg':  Top prediction is 'Species not defined' with 99.53% confidence.
  - Image '640px-Aedes_aegypti.jpg':  Top prediction is 'Species not defined' with 100.00% confidence.

Total running time of the script: ( 0 minutes 5.972 seconds)

Download Python source code: tutorial_part_4_mosquito_classification.py

Download Jupyter notebook: tutorial_part_4_mosquito_classification.ipynb

Gallery generated by mkdocs-gallery