Skip to content

madoo.mask-measurements/v1

Madoo mask measurements — Where the subject of an image is and how big it is, per region: box, area, coverage, centroid, edges touched, bands and profile (Measure Subject).

Reference madoo.mask-measurements/v1
Schema id urn:madoo:schema:mask-measurements:v1
Version 1.0.0
Served at GET /api/v1/json-schemas/madoo.mask-measurements/v1 · MCP get_json_schema

No node port declares it.

Field Type Required Rules Description
schema "madoo.mask-measurements/v1" yes
image object yes
image.width integer yes ≥ 1
image.height integer yes ≥ 1
source one of "alpha", "luminance" yes The channel actually read.
threshold integer yes ≥ 0; ≤ 254 A pixel is subject when its value is greater than this.
invert boolean yes
axis one of "rows", "columns" yes
length_mode one of "count", "span", "longest_run" What a line’s length is for bands and profile. Absent in documents written before the parameter existed: read it as count.
min_line_pixels integer yes ≥ 0
grid object or null The grid, or null when explicit regions were measured.
grid.rows integer
grid.cols integer
regions array of objects yes
regions[].index integer yes ≥ 1
regions[].row integer ≥ 0 Grid row; absent for explicit regions.
regions[].col integer ≥ 0
regions[].cell object yes The measured region.
regions[].cell.x integer yes
regions[].cell.y integer yes
regions[].cell.width integer yes
regions[].cell.height integer yes
regions[].empty boolean yes True when no line has more than min_line_pixels subject pixels; then only area and coverage (0) and touches (all false) are present.
regions[].first_line integer First line of the subject along the axis (a y on rows, an x on columns).
regions[].last_line integer Last line of the subject, included.
regions[].extent integer ≥ 1 last_line - first_line + 1: lines occupied, the bounding box side along the axis.
regions[].bbox object
regions[].bbox.x integer yes
regions[].bbox.y integer yes
regions[].bbox.width integer yes
regions[].bbox.height integer yes
regions[].bbox_normalized object The bbox divided by the image width and height.
regions[].bbox_normalized.x number yes
regions[].bbox_normalized.y number yes
regions[].bbox_normalized.width number yes
regions[].bbox_normalized.height number yes
regions[].area integer ≥ 0 Subject pixels on lines first_line..last_line.
regions[].coverage number ≥ 0; ≤ 1 area / cell area.
regions[].centroid object
regions[].centroid.x number yes
regions[].centroid.y number yes
regions[].centroid_normalized object
regions[].centroid_normalized.x number yes
regions[].centroid_normalized.y number yes
regions[].touches object Whether the subject reaches each edge of the region: cut off, or spilling in from a neighbouring cell.
regions[].touches.left boolean yes
regions[].touches.right boolean yes
regions[].touches.top boolean yes
regions[].touches.bottom boolean yes
regions[].bands array of objects
regions[].bands[].start number yes
regions[].bands[].end number yes
regions[].bands[].first_line integer yes first_line + floor(extent x start), included.
regions[].bands[].end_line integer yes first_line + floor(extent x end), excluded.
regions[].bands[].pixels integer yes Sum of the band lines’ lengths: the band’s subject pixels with length_mode count, the pixels the spans or longest runs cover otherwise.
regions[].bands[].mean_length number or null pixels / band lines: a mean width on rows, a mean height on columns, per length_mode.
regions[].bands[].relative_length number or null mean_length / extent: independent of zoom and distance.
regions[].bands[].center number or null Mean position across the axis of what was measured (subject pixels, spans or longest runs per length_mode): an x on rows, a y on columns.
regions[].profile array of objects
regions[].profile[].at number yes ≥ 0; ≤ 1
regions[].profile[].line integer yes
regions[].profile[].length integer yes The line’s length per length_mode.
regions[].profile[].relative_length number yes
madoo.mask-measurements/v1 (JSON Schema)
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "urn:madoo:schema:mask-measurements:v1",
"title": "Madoo mask measurements",
"description": "What Measure Subject (image/mask_measure) measured: the image, the settings that matter to read the numbers, and one entry per region (the whole image, each grid cell in reading order, or each requested rectangle). Coordinates are pixels of the whole image, origin top left. A line is a row on axis rows and a column on axis columns. Its length, for bands and profile, follows length_mode: count = every subject pixel on it, span = from the first to the last subject pixel (gaps included), longest_run = the longest unbroken run of subject pixels. Area, coverage, bbox, centroid, first_line and last_line always count subject pixels. An empty region carries its index, cell, empty: true, area and coverage 0 and touches all false; no shape measurement.",
"type": "object",
"required": [
"schema",
"image",
"source",
"threshold",
"invert",
"axis",
"min_line_pixels",
"regions"
],
"properties": {
"schema": {
"const": "madoo.mask-measurements/v1"
},
"image": {
"type": "object",
"required": [
"width",
"height"
],
"properties": {
"width": {
"type": "integer",
"minimum": 1
},
"height": {
"type": "integer",
"minimum": 1
}
}
},
"source": {
"enum": [
"alpha",
"luminance"
],
"description": "The channel actually read."
},
"threshold": {
"type": "integer",
"minimum": 0,
"maximum": 254,
"description": "A pixel is subject when its value is greater than this."
},
"invert": {
"type": "boolean"
},
"axis": {
"enum": [
"rows",
"columns"
]
},
"length_mode": {
"enum": [
"count",
"span",
"longest_run"
],
"description": "What a line's length is for bands and profile. Absent in documents written before the parameter existed: read it as count."
},
"min_line_pixels": {
"type": "integer",
"minimum": 0
},
"grid": {
"type": [
"object",
"null"
],
"properties": {
"rows": {
"type": "integer"
},
"cols": {
"type": "integer"
}
},
"description": "The grid, or null when explicit regions were measured."
},
"regions": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"cell",
"empty"
],
"properties": {
"index": {
"type": "integer",
"minimum": 1
},
"row": {
"type": "integer",
"minimum": 0,
"description": "Grid row; absent for explicit regions."
},
"col": {
"type": "integer",
"minimum": 0
},
"cell": {
"$ref": "#/$defs/rect",
"description": "The measured region."
},
"empty": {
"type": "boolean",
"description": "True when no line has more than min_line_pixels subject pixels; then only area and coverage (0) and touches (all false) are present."
},
"first_line": {
"type": "integer",
"description": "First line of the subject along the axis (a y on rows, an x on columns)."
},
"last_line": {
"type": "integer",
"description": "Last line of the subject, included."
},
"extent": {
"type": "integer",
"minimum": 1,
"description": "last_line - first_line + 1: lines occupied, the bounding box side along the axis."
},
"bbox": {
"$ref": "#/$defs/rect"
},
"bbox_normalized": {
"$ref": "#/$defs/rectNormalized",
"description": "The bbox divided by the image width and height."
},
"area": {
"type": "integer",
"minimum": 0,
"description": "Subject pixels on lines first_line..last_line."
},
"coverage": {
"type": "number",
"minimum": 0,
"maximum": 1,
"description": "area / cell area."
},
"centroid": {
"$ref": "#/$defs/point"
},
"centroid_normalized": {
"$ref": "#/$defs/point"
},
"touches": {
"type": "object",
"required": [
"left",
"right",
"top",
"bottom"
],
"properties": {
"left": {
"type": "boolean"
},
"right": {
"type": "boolean"
},
"top": {
"type": "boolean"
},
"bottom": {
"type": "boolean"
}
},
"description": "Whether the subject reaches each edge of the region: cut off, or spilling in from a neighbouring cell."
},
"bands": {
"type": "array",
"items": {
"type": "object",
"required": [
"start",
"end",
"first_line",
"end_line",
"pixels"
],
"properties": {
"start": {
"type": "number"
},
"end": {
"type": "number"
},
"first_line": {
"type": "integer",
"description": "first_line + floor(extent x start), included."
},
"end_line": {
"type": "integer",
"description": "first_line + floor(extent x end), excluded."
},
"pixels": {
"type": "integer",
"description": "Sum of the band lines' lengths: the band's subject pixels with length_mode count, the pixels the spans or longest runs cover otherwise."
},
"mean_length": {
"type": [
"number",
"null"
],
"description": "pixels / band lines: a mean width on rows, a mean height on columns, per length_mode."
},
"relative_length": {
"type": [
"number",
"null"
],
"description": "mean_length / extent: independent of zoom and distance."
},
"center": {
"type": [
"number",
"null"
],
"description": "Mean position across the axis of what was measured (subject pixels, spans or longest runs per length_mode): an x on rows, a y on columns."
}
}
}
},
"profile": {
"type": "array",
"items": {
"type": "object",
"required": [
"at",
"line",
"length",
"relative_length"
],
"properties": {
"at": {
"type": "number",
"minimum": 0,
"maximum": 1
},
"line": {
"type": "integer"
},
"length": {
"type": "integer",
"description": "The line's length per length_mode."
},
"relative_length": {
"type": "number"
}
}
}
}
}
}
}
},
"$defs": {
"rect": {
"type": "object",
"required": [
"x",
"y",
"width",
"height"
],
"properties": {
"x": {
"type": "integer"
},
"y": {
"type": "integer"
},
"width": {
"type": "integer"
},
"height": {
"type": "integer"
}
}
},
"rectNormalized": {
"type": "object",
"required": [
"x",
"y",
"width",
"height"
],
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
},
"width": {
"type": "number"
},
"height": {
"type": "number"
}
}
},
"point": {
"type": "object",
"required": [
"x",
"y"
],
"properties": {
"x": {
"type": "number"
},
"y": {
"type": "number"
}
}
}
},
"examples": [
{
"schema": "madoo.mask-measurements/v1",
"image": {
"width": 1536,
"height": 2048
},
"source": "alpha",
"threshold": 128,
"invert": false,
"axis": "rows",
"length_mode": "count",
"min_line_pixels": 3,
"grid": {
"rows": 2,
"cols": 4
},
"regions": [
{
"index": 1,
"row": 0,
"col": 0,
"cell": {
"x": 0,
"y": 0,
"width": 384,
"height": 1024
},
"empty": false,
"first_line": 37,
"last_line": 989,
"extent": 953,
"bbox": {
"x": 24,
"y": 37,
"width": 344,
"height": 953
},
"bbox_normalized": {
"x": 0.015625,
"y": 0.018066,
"width": 0.223958,
"height": 0.465332
},
"area": 213674,
"coverage": 0.543401,
"centroid": {
"x": 196.4,
"y": 541.2
},
"centroid_normalized": {
"x": 0.127865,
"y": 0.264258
},
"touches": {
"left": false,
"right": false,
"top": false,
"bottom": false
},
"bands": [
{
"start": 0.35,
"end": 0.6,
"first_line": 370,
"end_line": 608,
"pixels": 77090,
"mean_length": 323.9076,
"relative_length": 0.339882,
"center": 196.157
}
]
},
{
"index": 4,
"row": 0,
"col": 3,
"cell": {
"x": 1152,
"y": 0,
"width": 384,
"height": 1024
},
"empty": true,
"area": 0,
"coverage": 0,
"touches": {
"left": false,
"right": false,
"top": false,
"bottom": false
}
}
]
}
]
}