Skip to content

Annotation CSV reference

dcmview loads, edits, and exports rectangular ROI annotations in memory. It never modifies the input CSV or source DICOM files.

Column Required Meaning
anon_dicom_path yes Path of the DICOM object described by the row.
ROI_coords yes JSON array of [ymin, xmin, ymax, xmax] boxes.
num_ROI no Declared ROI count; when present, it must equal the coordinate count.
ROI_frames no JSON array with one zero-based frame-index list per ROI.

Extra input columns are ignored and are not preserved during export.

ROI_coords contains image-pixel indices:

[
[120, 340, 220, 430],
[400, 510, 480, 590]
]

For each box:

  • ymin and xmin are inclusive upper-left indices;
  • ymax must be greater than ymin;
  • xmax must be greater than xmin; and
  • all coordinates must remain inside the image rows and columns.

ROI_frames has one list for each coordinate box:

[
[0, 1, 2],
[5, 6]
]

Frame indices are zero-based and must be less than the DICOM object’s frame count. An omitted field, [], or an empty list for one ROI means that ROI applies to all frames.

JSON-valued fields must be quoted and escaped according to CSV rules.

CSV paths are resolved from the directory where dcmview started and normalized to absolute keys, including . and .. components. Loaded DICOM files also receive a best-effort canonical alias, so relative, absolute, and symlinked forms can match when they resolve to the same object.

A row with no loaded path match is ignored without parsing its ROI JSON. This makes it practical to pass a dataset-level annotation CSV while opening a subset of its DICOM files.

The CSV header is validated during startup. Matching rows are parsed after DICOM discovery in one blocking streaming pass. Annotation reads and export wait for that pass to finish, while ordinary image viewing can continue.

If a matching row is invalid, no annotations from the input CSV are committed. Viewer edits made while import is running are never overwritten by the later import.

Validation failures include:

  • missing anon_dicom_path or ROI_coords headers;
  • invalid JSON in ROI_coords or ROI_frames;
  • num_ROI differing from the coordinate count;
  • different coordinate and frame-list counts;
  • an empty, inverted, or out-of-bounds box; and
  • an out-of-range frame index.

The API uses snake-case JSON fields:

{
"num_roi": 2,
"roi_coords": [
[120, 340, 220, 430],
[400, 510, 480, 590]
],
"roi_frames": [
[0, 1, 2],
[5, 6]
]
}

PUT /api/file/:index/annotations replaces the complete in-memory payload for one file and returns a canonicalized copy. It does not merge individual rectangles.

GET /api/annotations/export.csv returns the current store as text/csv; charset=utf-8 with:

Content-Disposition: attachment; filename="dcmview-annotations.csv"

The browser’s Export ROIs action downloads that response. Export is the only built-in persistence path for edits.