tonhowtf/omniget · error

a saída do modelo tem

Error message

a saída do modelo tem {} valores, esperava {}

What it means

`mask_from_raw` converts raw model output floats into a grayscale mask of exactly w*h pixels. If the raw buffer has fewer values than width*height, it refuses to build a differently-shaped image and throws 'a saída do modelo tem N valores, esperava M'. This guards against model/output tensor shape mismatches.

Solutions

  1. Resize the model output mask to the image's w×h before calling (bilinear/nearest interpolation), or resize the input image to the model's expected size so output matches w*h.
  2. Slice raw per-image if the output carries a batch dimension, then pass the correct w,h per image.
  3. Verify which ONNX/model weights are loaded and their expected input/output shapes against the preprocessing code.

Example fix

// before
let mask = mask_from_raw(&raw, img.width(), img.height())?; // 640x480 img, 320x320 output
// after
let raw_mask = image_from_raw_f32(&raw, 320, 320);
let mask_resized = resize_gray(&raw_mask, img.width(), img.height());
let mask = mask_from_raw(mask_resized.as_raw(), img.width(), img.height())?;
Defensive patterns

Strategy: validation

Validate before calling

let n = (w as usize) * (h as usize);
if raw.len() < n {
    eprintln!("saída do modelo menor que w*h; redimensione a máscara antes");
}

Type guard

fn mask_shape_matches(raw: &[f32], w: u32, h: u32) -> bool {
    raw.len() >= (w as usize) * (h as usize)
}

Try / catch

match mask_from_raw(&raw, w, h) {
    Ok(mask) => use(mask),
    Err(e) if e.to_string().contains("esperava") => {
        eprintln!("formato da saída do modelo incompatível: {e}");
        // resize mask to (w, h) and retry
    }
    Err(e) => return Err(e),
}

Prevention

When it happens

Trigger: Calling `mask_from_raw(raw, w, h)` where raw.len() < w*h — e.g. the segmentation model emitted a downsampled mask (smaller resolution) or a different batch/channel layout than the input image dimensions.

Common situations: Model weights expect a fixed input size (e.g. 320x320) but the image wasn't resized; output includes batch dimension making per-image slices shorter; dynamic input shapes with a mismatched mask interpolation step.

Understand the failure class

Background: Tensor shape mismatch errors ("must have shape", "expected shape ... got ..."): when tensor dimensions disagree with what an op or layer was told to expect — this error's family across 6 libraries.

Related errors


AI-assisted analysis of tonhowtf/omniget@8600b91f42 (2026-09-12). Data as JSON: /api/errors/561687a4fd269de8. Report an issue: GitHub.

Appendix: source

Thrown at src-tauri/omniget-core/src/core/tools/img_bg.rs:193

    let mut t = Array4::<f32>::zeros((1, 3, size, size));
    for y in 0..size {
        for x in 0..size {
            let px = rgb.get_pixel(x as u32, y as u32).0;
            for c in 0..3 {
                t[[0, c, y, x]] = (px[c] as f32 * scale - p.mean[c]) / p.std[c];
            }
        }
    }
    t
}

/// Saída bruta do modelo → máscara em tons de cinza, normalizada por mín-máx.
/// Saída constante (imagem toda fundo ou toda objeto) vira máscara zerada em
/// vez de dividir por zero.
pub fn mask_from_raw(raw: &[f32], w: u32, h: u32) -> anyhow::Result<GrayImage> {
    let n = (w as usize) * (h as usize);
    if raw.len() < n {
        return Err(anyhow!(
            "a saída do modelo tem {} valores, esperava {}",
            raw.len(),
            n
        ));
    }
    let slice = &raw[..n];
    let mut mi = f32::INFINITY;
    let mut ma = f32::NEG_INFINITY;
    for v in slice {
        if v.is_finite() {
            mi = mi.min(*v);
            ma = ma.max(*v);
        }
    }
    let span = ma - mi;
    let buf: Vec<u8> = if !span.is_finite() || span <= f32::EPSILON {
        vec![0u8; n]
    } else {

View on GitHub (pinned to 8600b91f42)