Hello! I have a quick question.
I’m using pynrrd to open an existing segmented NRRD file. I’m trying to remove certain segments that are there, then re-save without those removed segments.
I have many Segments, and each apparently is named SegmentX_Property, where “X” is their respective number (e.g., 1, 2, 3…) and “Property” is a property (e.g., Color, Name, etc.). I have a list of numbers (e.g., [1, 3, 5, 7]), representing segments I wish to keep.
Can someone help me in taking this list and my existing pynrrd file to output a new Segmented NRRD file with only Segments in my list of numbers?
Thank you so much in advanced!
I’ll include my code just for reference, though its scope extends beyond what I’m asking here.
import SimpleITK as sitk
import numpy as np
import nrrd
def filter_segments_by_name(nrrd_file_path, target_substrings):
try:
image = sitk.ReadImage(nrrd_file_path)
filtered_names = []
for key in image.GetMetaDataKeys():
if key.endswith("_Name"):
segment_name = image.GetMetaData(key)
if any(substring.lower() in segment_name.lower() for substring in target_substrings):
filtered_names.append(segment_name)
return filtered_names
except Exception as e:
print(f"Error reading NRRD file: {e}")
return []
def filter_segments_properties(image, filtered_names):
filtered_segments = []
# Iterate over all metadata keys
for key in image.GetMetaDataKeys():
if key.startswith("Segment") and key.endswith("_Name"):
segment_number = int(key.split("_")[0][len("Segment"):])
segment_name = image.GetMetaData(key)
if segment_name in filtered_names:
filtered_segments.append(segment_number)
return filtered_segments
def filter_segments(segments_to_keep, filename):
"""
Filters segments from an NRRD file based on the provided list of segment numbers.
Args:
segments_to_keep (list[int]): List of segment numbers to retain.
filename (str): Path to the input .seg.nrrd file.
Returns:
None. Saves the filtered data to a new NRRD file.
"""
# Load the .seg.nrrd file
data, header = nrrd.read(filename)
# Initialize an empty dictionary to store the filtered data
filtered_data = {}
# Iterate through each segment
for segment_number in segments_to_keep:
segment_key_prefix = f"Segment{segment_number}_"
# Collect all keys associated with this segment
segment_keys = [key for key in header.keys() if key.startswith(segment_key_prefix)]
# Copy the segment data and its properties
for key in segment_keys:
filtered_data[key] = data[key]
# Write the filtered data to a new NRRD file
output_filename = 'filtered_segments.nrrd'
nrrd.write(output_filename, filtered_data, header)
print(f"Filtered data saved to {output_filename}")
# Load the NRRD file
**nrrd_file_path = [insert your .seg.nrrd file here]**
**save_path = [insert your path here for saving]**
data, header = nrrd.read(nrrd_file_path)
image = sitk.ReadImage(nrrd_file_path)
# Define your list of target substrings
target_substrings = ["rib", "vert"]
# Get the filtered segment names
filtered = filter_segments_by_name(nrrd_file_path, target_substrings)
# Filter the segments based on the names
segments_to_keep = filter_segments_properties(image, filtered)
# Create a set for efficient membership checking
segments_to_keep_set = set(segments_to_keep)
# Filter segments
for segment in list(header['labels']):
if all(item in segments_to_keep_set for item in segment):
# Segment contains all items from segments_to_keep
continue
else:
# Remove this segment
del header['labels'][segment]
del header['sizes'][segment]
del header['spacings'][segment]
# Add any other relevant fields to remove
nrrd.write(save_path, data, header)