Last active
October 10, 2025 02:52
-
-
Save rmukh/a655b5ac16a37d72cb6f20747664e4af to your computer and use it in GitHub Desktop.
Script to read FreeSurfer Color LUT table in Python 3
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| #!/usr/bin/env python3 | |
| """ | |
| Read and store FreeSurfer Color Lookup Table (LUT) | |
| FreeSurfer provides a color lookup table (LUT) that maps anatomical region codes | |
| to label names and their corresponding RGB(A) colors. | |
| Reference: | |
| https://surfer.nmr.mgh.harvard.edu/fswiki/FsTutorial/AnatomicalROI/FreeSurferColorLUT | |
| or locally (if FreeSurfer is installed): | |
| $FREESURFER_HOME/FreeSurferColorLUT.txt | |
| This script: | |
| • Reads the LUT file | |
| • Extracts region codes, label names, and RGB colors | |
| • Saves the parsed data to .npy and .json files (optional) | |
| Output: | |
| - `rgb`: NumPy array of shape (N, 4) — columns: [code, R, G, B] | |
| - `label_names`: dict { code: label_name } | |
| Example usage: | |
| python read_freesurfer_lut.py --lut /usr/local/freesurfer/FreeSurferColorLUT.txt --save_dir ./output/ | |
| """ | |
| import argparse | |
| import numpy as np | |
| import re | |
| import json | |
| from pathlib import Path | |
| def parse_freesurfer_lut(lut_path: str): | |
| """ | |
| Parse the FreeSurfer LUT file into structured data. | |
| Args: | |
| lut_path (str): Path to the FreeSurferColorLUT.txt file. | |
| Returns: | |
| tuple: | |
| rgb (np.ndarray): Array of shape (N, 4) with columns [code, R, G, B]. | |
| label_names (dict): {region_code: region_label}. | |
| """ | |
| pattern = re.compile( | |
| r"^\d{1,5}\s+[A-Za-z0-9*_.-]+\s+\d{1,3}\s+\d{1,3}\s+\d{1,3}\s+\d{1,3}" | |
| ) | |
| rgb = [] | |
| label_names = {} | |
| with open(lut_path, "r") as f: | |
| for line in f: | |
| line = line.strip() | |
| if not pattern.match(line): | |
| continue # skip comments and blank lines | |
| parts = re.split(r"\s+", line) | |
| code = int(parts[0]) | |
| name = parts[1] | |
| r, g, b, _ = map(int, parts[2:6]) | |
| rgb.append([code, r, g, b]) | |
| label_names[code] = name | |
| rgb = np.array(rgb, dtype=np.int64) | |
| return rgb, label_names | |
| def save_outputs(rgb: np.ndarray, label_names: dict, save_dir: str): | |
| """ | |
| Save the parsed LUT data to disk in .npy and .json formats. | |
| Args: | |
| rgb (np.ndarray): RGB array. | |
| label_names (dict): Mapping of code → label name. | |
| save_dir (str): Directory path to save outputs. | |
| """ | |
| save_path = Path(save_dir) | |
| save_path.mkdir(parents=True, exist_ok=True) | |
| np.save(save_path / "freesurfer_rgb.npy", rgb) | |
| with open(save_path / "freesurfer_labels.json", "w") as f: | |
| json.dump(label_names, f, indent=2) | |
| print(f"Saved RGB array to: {save_path / 'freesurfer_rgb.npy'}") | |
| print(f"Saved label dictionary to: {save_path / 'freesurfer_labels.json'}") | |
| def main(): | |
| parser = argparse.ArgumentParser( | |
| description="Read and store FreeSurfer Color Lookup Table (LUT)." | |
| ) | |
| parser.add_argument( | |
| "--lut", | |
| type=str, | |
| required=True, | |
| help="Path to FreeSurferColorLUT.txt file.", | |
| ) | |
| parser.add_argument( | |
| "--save_dir", | |
| type=str, | |
| default=None, | |
| help="Optional directory to save the parsed output files.", | |
| ) | |
| args = parser.parse_args() | |
| rgb, label_names = parse_freesurfer_lut(args.lut) | |
| print(f"[INFO] Parsed {len(label_names)} regions from LUT.") | |
| print(f"[INFO] Example entry: {next(iter(label_names.items()))}") | |
| if args.save_dir: | |
| save_outputs(rgb, label_names, args.save_dir) | |
| if __name__ == "__main__": | |
| main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment