@@ -1513,6 +1513,56 @@ Notes:
15131513- ` number_of_threads=0 ` uses the library default; pass a positive integer for a
15141514 fixed thread count.
15151515
1516+ ### Mapping RAG Edges to Pixel Coordinates
1517+
1518+ Nifty's ` ragCoordinates ` scans the label volume once and caches, per edge, the
1519+ pixel coordinates of the boundary between the two adjacent regions, so that
1520+ per-edge values (e.g. edge probabilities) can be painted back onto a volume.
1521+
1522+ Nifty:
1523+
1524+ ``` python
1525+ import nifty.graph.rag as nrag
1526+
1527+ rag = nrag.gridRag(labels)
1528+ rag_coords = nrag.ragCoordinates(rag)
1529+ storage = rag_coords.storageLengths()
1530+ volume = rag_coords.edgesToVolume(edge_values, edgeDirection = 0 )
1531+ ```
1532+
1533+ bioimage-cpp:
1534+
1535+ ``` python
1536+ rag = bic.graph.region_adjacency_graph(labels)
1537+ rag_coords = bic.graph.rag_coordinates(rag, labels)
1538+
1539+ storage = rag_coords.storage_lengths()
1540+ coords = rag_coords.edge_coordinates(edge_id) # (n_points, ndim)
1541+ volume = rag_coords.edges_to_volume(edge_values, edge_direction = 0 )
1542+ ```
1543+
1544+ Notes:
1545+
1546+ - ` labels ` must be the over-segmentation used to construct ` rag ` , and is passed
1547+ explicitly (nifty's RAG holds an internal reference to it; ours does not).
1548+ Supported label dtypes: ` uint32 ` , ` uint64 ` , ` int32 ` , ` int64 ` .
1549+ - A boundary "contact" is a pair of directly adjacent pixels with different
1550+ labels. Each contact contributes two coordinates to its edge: the
1551+ lower-coordinate pixel followed by its ` +axis ` neighbor. ` storage_lengths `
1552+ therefore reports ` 2 * n_contacts ` per edge, and coordinates are stored in
1553+ scan order (NumPy axis order, C-contiguous).
1554+ - ` edge_direction ` selects which side(s) to report / paint: ` 0 ` = both (default),
1555+ ` 1 ` = lower-coordinate pixel only, ` 2 ` = higher-coordinate pixel only.
1556+ - ` edges_to_volume ` returns a volume of the label shape and dtype matching
1557+ ` edge_values ` (supported: ` float32 ` , ` float64 ` , ` uint32 ` , ` uint64 ` ).
1558+ Non-boundary pixels are set to ` ignore_value ` . Painting is sequential in
1559+ ascending edge id, so where several edges' boundaries coincide on a pixel the
1560+ highest edge id wins — a deterministic, race-free rule (nifty's parallel
1561+ ` edgesToVolume ` does not guarantee a tie-break order).
1562+ - The cached object can be reused across many ` edges_to_volume ` calls without
1563+ re-scanning the labels. ` number_of_threads=0 ` (on ` rag_coordinates ` ) uses the
1564+ library default.
1565+
15161566### Accumulating Labels on a RAG
15171567
15181568Nifty's ` gridRagAccumulateLabels ` projects a second label volume onto a RAG
0 commit comments