File size: 5,811 Bytes
5c0ccbd a927e75 53b0237 a927e75 5c0ccbd a927e75 5c0ccbd a927e75 5c0ccbd a927e75 75c8f1b a927e75 75c8f1b a927e75 75c8f1b a927e75 5c0ccbd a927e75 1232ce7 5c0ccbd 75c8f1b 5c0ccbd 2fd1892 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 | ---
language:
- en
license: apache-2.0
tags:
- vision
- image-classification
- edge-ai
- mobile
- plant-identification
- nature
- tflite
- torchscript
pipeline_tag: image-classification
---
# Kindwise Router Classifier (tiny)
[](https://www.kindwise.com)
[](https://admin.kindwise.com/public/docs)
[](https://pypi.org/project/kindwise-api-client/)
[](https://opensource.org/licenses/Apache-2.0)
This model classifies images based on their content, acting as an on-device router to direct requests to the appropriate [Kindwise API](https://www.kindwise.com) before uploading data to the cloud. It detects whether an image contains a **plant, unhealthy plant, crop, mushroom, insect, or human**.
Using the router as the first step in your pipeline minimizes cloud latency, optimizes bandwidth, and protects privacy by keeping non-target photos (such as people) on the device.
## Available Variants
| Variant | TFLite | Optimized | RAM Est. | Primary Focus |
| :--- | :---: | :---: | :---: | :--- |
| **`router.tiny`** (this model) | 53 MB | **14 MB** | ~40 MB | Ultra-low footprint & edge devices |
| [`router.small`](https://huggingface.co/kindwise/router.small) | 146 MB | 38 MB | ~80 MB | Balanced accuracy & latency |
| [`router.base`](https://huggingface.co/kindwise/router.base) | 375 MB | 96 MB | ~220 MB | Highest precision |
## Downstream Routing
Route predicted categories to specialized Kindwise APIs (100 free credits available at [admin.kindwise.com](https://admin.kindwise.com)):
- `plant` → **[Plant.id API](https://www.kindwise.com/plant-id)** (35,000+ taxa, cultivars, care data · [Live Demo](https://plant.id))
- `unhealthy_plant` → **[plant.health API](https://www.kindwise.com/plant-health)** (548 diseases, pests, abiotic disorders)
- `crop` + `unhealthy_plant` → **[crop.health API](https://www.kindwise.com/crop-health)** (288 conditions across 23 staple crops + EPPO codes)
- `mushroom` → **[mushroom.id API](https://www.kindwise.com/mushroom-id)** (5,000 fungi, toxicity & edibility)
- `insect` → **[insect.id API](https://www.kindwise.com/insect-id)** (14,000+ terrestrial invertebrates)
- `human` → *Handle locally (privacy filter)*
## Technical Details and Formats
Available in two deployment formats:
- **TorchScript** (`model.traced.pt`): For server-side inference and high-throughput production services.
- **TensorFlow Lite** (`model.tflite`, `model.optimized.tflite`): For mobile and embedded devices.
You can also use this model directly via Python SDK: `pip install kindwise-api-client[router]`.
## Usage
Here is how to use this model to classify an image into one of the basic classes:
### PyTorch
```python
from huggingface_hub import hf_hub_download
import cv2
import numpy as np
import PIL.Image
import torch
import torchvision
DEVICE_NAME = 'cuda:0'
MODEL_PATH = hf_hub_download('kindwise/router.tiny', 'model.traced.pt')
CLASSES_PATH = hf_hub_download('kindwise/router.tiny', 'classes.txt')
IMAGE_PATH = '/tmp/photo.jpg'
with open(CLASSES_PATH) as f:
CLASSES = [line.strip() for line in f]
MODEL = torch.jit.load(MODEL_PATH).eval().to(DEVICE_NAME)
def resize_crop(image_data: np.ndarray, target_size: int = 480) -> np.ndarray | None:
height, width, _ = image_data.shape
# Determine the size of the square crop
crop_size = min(height, width)
# Calculate coordinates for center crop
start_x = (width - crop_size) // 2
start_y = (height - crop_size) // 2
# Perform center crop
cropped_img = image_data[
start_y : start_y + crop_size,
start_x : start_x + crop_size
]
# Resize cropped image to target size
return cv2.resize(
cropped_img,
(target_size, target_size),
interpolation=cv2.INTER_AREA,
)
with torch.no_grad():
image_array = np.array(PIL.Image.open(IMAGE_PATH))
image_array_resized = resize_crop(image_array)
image_tensor = torchvision.transforms.functional.to_tensor(image_array_resized).to(DEVICE_NAME)
prediction = MODEL(image_tensor.unsqueeze(0)).squeeze(0).cpu().numpy()
for i in (-prediction).argsort():
print(f'{CLASSES[i]:>10}: {100 * prediction[i]:.1f}%')
```
Output:
```text
plant: 91.3%
unhealthy_plant: 53.3%
crop: 16.2%
insect: 0.4%
human: 0.1%
mushroom: 0.0%
```
### TensorFlow Lite
```python
from huggingface_hub import hf_hub_download
import numpy as np
import tensorflow as tf
MODEL_PATH = hf_hub_download('kindwise/router.tiny', 'model.tflite') # or model.optimized.tflite
CLASSES_PATH = hf_hub_download('kindwise/router.tiny', 'classes.txt')
with open(CLASSES_PATH) as f:
CLASSES = [line.strip() for line in f]
INTERPRETER = tf.lite.Interpreter(model_path=MODEL_PATH)
INTERPRETER.allocate_tensors()
image_array_resized = ... # see the previous example
tf_input = np.expand_dims( # add batch dimension
(image_array_resized / 255).astype(np.float32), # image values in [0..1]
0,
)
input_details = INTERPRETER.get_input_details()
output_details = INTERPRETER.get_output_details()
INTERPRETER.set_tensor(
input_details[0]['index'],
tf_input,
)
INTERPRETER.invoke()
logits = INTERPRETER.get_tensor(output_details[0]['index'])[0]
prediction = tf.nn.sigmoid(logits).numpy()
for i in (-prediction).argsort():
print(f'{CLASSES[i]:>10}: {100 * prediction[i]:.1f}%')
```
Output:
```text
plant: 91.3%
unhealthy_plant: 53.3%
crop: 16.2%
insect: 0.4%
human: 0.1%
mushroom: 0.0%
``` |