Skip to content
imaged

Image classification

Run an image model and read its highest-scoring classes.

Use your own .slab model and a runtime license. Model files carry their input sizes, preprocessing, labels, and backend preferences.

classify.cplus

C+ setup →
// Classify an image and print the five most likely classes.
//
// The model file carries its own preprocessing (input size, color order,
// normalization) and labels, so the app only passes an image.

import "stdlib/io" as io;
import "stdlib/env" as env;
import "stdlib/fs" as fs;
import "stdlib/result" as result;
import "stdlib/option" as option;
import "ffi/api" as slab;

fn main() -> i32 {
    var cfg = slab::Config::new();
    cfg.set_models_dir("models");
    cfg.set_cache_dir("/tmp/slab_cache");

    // Every model needs a runtime license. An app ships or downloads its
    // token; this example reads it from a file named by an environment variable.
    guard let option::Option::Some(path) = env::var("SLAB_RUNTIME_LICENSE_FILE") else {
        io::eprintln("Set SLAB_RUNTIME_LICENSE_FILE to your license file");
        return 1;
    };
    guard let result::Result::Ok(token) = fs::read_to_string(path.view()) else {
        io::eprintln("Cannot read the license file");
        return 1;
    };
    if !cfg.set_runtime_license(token.view()) {
        io::eprintln("License rejected: ${cfg.runtime_license_error_message()}");
        return 1;
    }

    var session = slab::Session::new(cfg);
    session.set_warmup(true);
    if !session.open("classifier.slab") {
        io::eprintln("Cannot open the model: ${session.error_message()}");
        return 1;
    }

    var frame = slab::Frame::new();
    if !frame.load_file("images/photo.jpg") {
        io::eprintln("Cannot load the image: ${frame.error_message()}");
        return 1;
    }

    var inp = slab::Input::new();
    var out = slab::Output::new();
    inp.set_frame(frame);
    if !session.run(inp, out) {
        io::eprintln("Run failed: ${session.error_message()}");
        return 1;
    }

    let k = out.compute_top_k(0, 5, true);
    io::println("${slab::backend_name(out.backend_used())}, ${out.latency_ms()} ms");
    for r in 0..k {
        let id = out.top_class_id(r);
        let score = out.top_score(r);
        // Labels come from the model file; a model without labels returns "".
        // The label borrows `out`, so read it last.
        let label = out.top_label(r);
        if label.is_empty() {
            io::println("  class ${id}: ${score}");
        } else {
            io::println("  ${label}: ${score}");
        }
    }
    return 0;
}