> ## Documentation Index
> Fetch the complete documentation index at: https://docs.redbrickai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Curved Planar Reconstruction (CPR) Views

> Learn how to upload and visualize centerline data for curved planar reconstruction in RedBrick AI.

Curved Planar Reconstruction (CPR) is a visualization technique that allows you to "straighten out" curved anatomical structures like blood vessels, airways, or the spine. This makes it easier to view and measure these structures along their entire length without the distortion caused by their natural curvature.

RedBrick AI supports CPR views by allowing you to upload centerline data alongside your medical images. This page explains how to format and upload centerline data for CPR visualization.

## Centerline Data Structure

Centerlines define the path and orientation for CPR reconstruction. Each centerline consists of position coordinates and orientation matrices that describe how to unfold the curved structure.

### Basic Structure

```json theme={null}
{
  "name": "Aorta",
  "seriesIndex": 0,
  "centerline": {
    "position": [...],
    "orientation": [...]
  }
}
```

**Properties:**

* `name` (string) - Identifier for the centerline (e.g., "Aorta", "Spine", "Pulmonary Artery")
* `seriesIndex` (number) - Which image series this centerline belongs to (0-based index)
* `centerline` (object) - Contains the position and orientation data

### Position Data

The position array contains 3D coordinates that define the centerline path through the anatomical structure.

**Format:** Flattened array of coordinates `[x1, y1, z1, x2, y2, z2, x3, y3, z3, ...]`

<Warning>
  Coordinates must be in the same world/model space as your image volume. There
  is no automatic unit conversion, so ensure your centerline coordinates match
  the coordinate system of your medical images (typically millimeters for
  medical imaging).
</Warning>

**Example:**

```json theme={null}
{
  "position": [
    45.2, 123.8, 67.1, 46.1, 124.2, 68.3, 47.0, 124.8, 69.5, 47.9, 125.4, 70.7
  ]
}
```

This example defines 4 points along the centerline path.

### Orientation Data

The orientation array contains 4x4 transformation matrices that define the local coordinate system at each point along the centerline.

**Format:** Flattened array of 4x4 matrices `[m11, m12, m13, m14, m21, m22, ..., m44]` for each point

<Note>
  The number of orientation matrices should match the number of position points.
  If you have N position points (length = 3N), you should have N orientation
  matrices (length = 16N).
</Note>

**Example:**

```json theme={null}
{
  "orientation": [
    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,

    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
  ]
}
```

This example provides identity matrices for 2 points (2 × 16 = 32 values).

## Uploading Centerline Data

The RedBrick viewer requires centerline data to be provided as inline JSON objects with `position` and `orientation` arrays. You must include the complete centerline data directly in your task JSON.

### Inline Centerline Data (Required Format)

Include the centerline data directly in your task JSON with the complete `position` and `orientation` arrays:

```json theme={null}
[
  {
    "name": "CPR Task - Vessel Analysis",
    "items": ["https://example.com/ct_scan.nii.gz"],
    "centerline": [
      {
        "name": "Vessel",
        "seriesIndex": 0,
        "centerline": {
          "position": [45.2, 123.8, 67.1, 46.1, 124.2, 68.3],
          "orientation": [
            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
            0, 0, 0, 1, 0, 0, 0, 0, 1
          ]
        }
      }
    ]
  }
]
```

<Check>
  You can include multiple centerlines per task, each with a unique name. This
  is useful when visualizing multiple anatomical structures in the same scan.
</Check>

**Example with multiple centerlines:**

```json theme={null}
[
  {
    "name": "CPR Task - Multi-structure Analysis",
    "items": ["https://datasets.redbrickai.com/scan.nii.gz"],
    "centerline": [
      {
        "name": "Aorta",
        "seriesIndex": 0,
        "centerline": {
          "position": [45.2, 123.8, 67.1, 46.1, 124.2, 68.3, 47.0, 124.8, 69.5],
          "orientation": [
            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
            0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0,
            0, 1
          ]
        }
      },
      {
        "name": "Spine",
        "seriesIndex": 0,
        "centerline": {
          "position": [12.5, 98.3, 45.7, 13.1, 99.2, 46.8],
          "orientation": [
            1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
            0, 0, 0, 1, 0, 0, 0, 0, 1
          ]
        }
      }
    ]
  }
]
```

<Note>
  The RedBrick viewer expects the `centerline` field to contain a parsed JSON
  object with `position` and `orientation` arrays. URL strings in the
  `centerline` field are not automatically fetched or resolved by the viewer.
</Note>

## Uploading via CLI

Once you've prepared your task JSON file with centerline data, upload it using the RedBrick CLI.

**Step 1:** Save your task JSON to a file (e.g., `cpr_tasks.json`)

**Step 2:** Run the upload command:

```bash theme={null}
redbrick upload \
  --org-id YOUR_ORG_ID \
  --project-id YOUR_PROJECT_ID \
  --items-list cpr_tasks.json
```

<Note>
  Make sure you have the RedBrick SDK installed and configured. See
  [Installation and API Keys](/python-sdk/installation-and-api-keys) for setup
  instructions.
</Note>

## Important Considerations

### Series Index

The `seriesIndex` property indicates which image series in your task the centerline belongs to.

<Check>
  Always explicitly set `seriesIndex` in your task JSON. While the viewer may
  default missing values to `0` during study setup, uploads via API/SDK require
  this field to be specified.
</Check>

* Use `0` for the first (or only) series in your task
* Use `1`, `2`, etc. for subsequent series if you have multiple series per task
* Multiple centerlines can reference the same `seriesIndex`

**Example with multiple series:**

```json theme={null}
{
  "name": "Multi-series Task",
  "items": [
    "https://example.com/ct_baseline.nii.gz",
    "https://example.com/ct_followup.nii.gz"
  ],
  "centerline": [
    {
      "name": "Baseline Aorta",
      "seriesIndex": 0,
      "centerline": {
        "position": [45.2, 123.8, 67.1, 46.1, 124.2, 68.3],
        "orientation": [
          1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
          0, 0, 0, 1, 0, 0, 0, 0, 1
        ]
      }
    },
    {
      "name": "Followup Aorta",
      "seriesIndex": 1,
      "centerline": {
        "position": [44.8, 122.5, 66.9, 45.7, 123.1, 68.1],
        "orientation": [
          1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0,
          0, 0, 0, 1, 0, 0, 0, 0, 1
        ]
      }
    }
  ]
}
```

### Multiple Centerlines

You can include multiple centerlines for a single series, and the viewer will make them all available for CPR visualization:

* Each centerline must have a unique `name` for identification
* Common examples include: "Aorta", "Pulmonary Artery", "Spine", "Airways", "LAD", "RCA"
* You can select which centerline to visualize in the CPR view

## Data Requirements

To ensure proper CPR rendering, your centerline data should follow these guidelines:

### Position Array

The position array length should be divisible by 3 to represent complete 3D points:

**Valid:** `[1, 2, 3, 4, 5, 6]` (2 complete points)
**Invalid:** `[1, 2, 3, 4, 5]` (incomplete point - missing z coordinate)

<Note>
  Malformed position arrays may result in incorrect CPR rendering or missing
  visualizations.
</Note>

### Orientation Array

The orientation array length should be divisible by 16 to represent complete 4x4 matrices:

**Valid:** `[1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]` (1 complete matrix)
**Invalid:** `[1, 0, 0, 0, 0, 1, 0, 0]` (incomplete matrix - only 8 values)

### Matching Counts

The number of orientation matrices should match the number of position points for proper CPR reconstruction.

<Warning>
  If position length = 3N (N points), orientation length should = 16N (N
  matrices). Mismatches may cause rendering issues.
</Warning>

**Examples:**

* 5 position points → position length = 15, orientation length should = 80
* 10 position points → position length = 30, orientation length should = 160

### Numeric Values

* All values should be valid numbers (avoid `NaN` or `Infinity`)
* Position coordinates must match the world/model space of your image volume
* Orientation matrices should be valid 4x4 transformation matrices

## Troubleshooting

### Common Issues and Solutions

#### CPR view not rendering

If the CPR view doesn't appear or renders incorrectly, check the following:

**Centerline format:**

* Ensure the `centerline` field contains a JSON object with `position` and `orientation` arrays, not a URL string
* Verify arrays are properly formatted (not empty or malformed)

```json theme={null}
// ❌ Won't render - URL string instead of object
{
  "name": "Vessel",
  "seriesIndex": 0,
  "centerline": "https://example.com/centerline.json"
}

// ✅ Correct - inline object with arrays
{
  "name": "Vessel",
  "seriesIndex": 0,
  "centerline": {
    "position": [1, 2, 3, 4, 5, 6],
    "orientation": [
      1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
      1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
    ]
  }
}
```

#### Incomplete or malformed position data

**Issue:** CPR view renders incorrectly or shows artifacts

**Solution:** Verify position array has complete 3D coordinates:

```json theme={null}
// ❌ Invalid - incomplete point (5 values, missing z for 2nd point)
"position": [1, 2, 3, 4, 5]

// ✅ Valid - complete points (6 values = 2 points)
"position": [1, 2, 3, 4, 5, 6]
```

#### Mismatched array lengths

**Issue:** CPR reconstruction appears distorted or incomplete

**Solution:** Ensure you have one 4x4 orientation matrix (16 values) for each position point:

```json theme={null}
// ❌ Invalid - 2 position points but only 1 orientation matrix
{
  "position": [1, 2, 3, 4, 5, 6],
  "orientation": [1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]
}

// ✅ Valid - 2 position points with 2 orientation matrices
{
  "position": [1, 2, 3, 4, 5, 6],
  "orientation": [
    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
    1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1
  ]
}
```

#### Series index issues

**Issue:** CPR view doesn't display for the correct image series

**Solution:** Verify `seriesIndex` corresponds to an existing image series:

```json theme={null}
// ❌ Invalid - only 1 series (index 0), but referencing index 1
{
  "items": ["scan.nii.gz"],
  "centerline": [{
    "seriesIndex": 1,
    "centerline": { ... }
  }]
}

// ✅ Valid - seriesIndex matches available series
{
  "items": ["scan.nii.gz"],
  "centerline": [{
    "seriesIndex": 0,
    "centerline": { ... }
  }]
}
```

#### Coordinate space mismatch

**Issue:** CPR view shows the wrong anatomical region or appears offset

**Solution:** Ensure centerline coordinates are in the same world/model space as your image volume. Check that:

* Units match (typically millimeters for medical imaging)
* Origin and coordinate system match your image data
* There's no mismatch between RAS/LPS coordinate conventions

### Need Help?

If you encounter issues not covered here or need assistance with CPR view setup, please reach out to [support@redbrickai.com](mailto:support@redbrickai.com).
