Kindwise Router Classifier (tiny)

Kindwise Docs Python SDK License: 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 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 146 MB 38 MB ~80 MB Balanced accuracy & latency
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):

  • plant โ†’ Plant.id API (35,000+ taxa, cultivars, care data ยท Live Demo)
  • unhealthy_plant โ†’ plant.health API (548 diseases, pests, abiotic disorders)
  • crop + unhealthy_plant โ†’ crop.health API (288 conditions across 23 staple crops + EPPO codes)
  • mushroom โ†’ mushroom.id API (5,000 fungi, toxicity & edibility)
  • insect โ†’ insect.id API (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

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:

          plant: 91.3%
unhealthy_plant: 53.3%
           crop: 16.2%
         insect: 0.4%
          human: 0.1%
       mushroom: 0.0%

TensorFlow Lite

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:

          plant: 91.3%
unhealthy_plant: 53.3%
           crop: 16.2%
         insect: 0.4%
          human: 0.1%
       mushroom: 0.0%
Downloads last month
78
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support