
Research
Malicious npm Packages Impersonate Flashbots SDKs, Targeting Ethereum Wallet Credentials
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Python utilities for 3D Slicer interoperability.
The package contains utility functions for reading and writing segmentation files and convenience functions for using 3D Slicer via its web API. More functions will be added in the future.
See this page to learn more about how standard terms can be used to describe content of segmentation files.
Using pip:
pip install slicerio
import slicerio
import json
segmentation = slicerio.read_segmentation("path/to/Segmentation.seg.nrrd", skip_voxels=True)
number_of_segments = len(segmentation["segments"])
print(f"Number of segments: {number_of_segments}")
segment_names = slicerio.segment_names(segmentation)
print(f"Segment names: {', '.join(segment_names)}")
segment0 = slicerio.segment_from_name(segmentation, segment_names[0])
print("First segment info:\n" + json.dumps(segment0, sort_keys=False, indent=4))
Example for getting a 3D NRRD file that has label values assigned based on standard terminology codes.
Terminology is a dict
that must specify category
and type
codes and may optionally also specify typeModifier
, anatomicRegion
, and anatomicRegionModifier
. Each code is specifed by a triplet of "coding scheme designator", "code value", "code meaning" in a list.
Coding scheme designator is typically SCT
(SNOMED-CT) for clinical images. You can find codes in the SNOMED-CT browser. When code exists for "entire X" and "structure of X" then always use the "structure" code ("entire" code has a very strict meaning that is rarely applicable in practice).
Code meaning (third component of codes, such as "Anatomical Structure", "Ribs", "Right") is informational only, it can be used for troubleshooting or displayed to the user, but it is ignored in information processing (e.g., two codes match if their coding scheme designator and code value are the same even if code meaning is different).
import slicerio
input_filename = "path/to/Segmentation.seg.nrrd"
output_filename = "path/to/SegmentationExtracted.seg.nrrd"
segments_to_labels = [
({"category": ["SCT", "123037004", "Anatomical Structure"], "type": ["SCT", "113197003", "Ribs"]}, 1),
({"category": ["SCT", "123037004", "Anatomical Structure"], "type": ["SCT", "39607008", "Lung"], "typeModifier": ["SCT", "24028007", "Right"]}, 3)
]
segmentation = slicerio.read_segmentation(input_filename)
extracted_segmentation = slicerio.extract_segments(segmentation, segments_to_labels)
slicerio.write_segmentation(output_filename, extracted_segmentation)
It is strongly recommended to look up segments by standard terminology codes instead of segment name, as spelling errors and inconsistent use of names often causes mismatch.
import slicerio
input_filename = "path/to/Segmentation.seg.nrrd"
output_filename = "path/to/SegmentationExtracted.seg.nrrd"
segment_names_to_labels = [("ribs", 10), ("right lung", 12), ("left lung", 6)]
segmentation = slicerio.read_segmentation(input_filename)
extracted_segmentation = slicerio.extract_segments(segmentation, segment_names_to_labels)
slicerio.write_segmentation(output_filename, extracted_segmentation)
# Create segmentation with two labels (1, 3)
voxels = np.zeros([100, 120, 150])
voxels[30:50, 20:60, 70:100] = 1
voxels[70:90, 80:110, 60:110] = 3
# Image geometry
spacing = [0.5, 0.5, 0.8]
origin = [10, 30, 15]
segmentation = {
"voxels": voxels,
"encoding": "gzip",
"ijkToLPS": [[ spacing[0], 0., 0., origin[0]],
[ 0., spacing[1], 0., origin[1]],
[ 0., 0., spacing[2], origin[2]],
[ 0., 0., 0., 1. ]]
"segmentation": {
"containedRepresentationNames": ["Binary labelmap", "Closed surface"],
# "masterRepresentation": "Binary labelmap",
# "referenceImageExtentOffset": [0, 0, 0],
},
"segments": [
{
"id": "Segment_1",
"labelValue": 1,
"layer": 0,
"color": [0.9, 0.9, 0.6],
"name": "ribs",
"terminology": {
"contextName": "Segmentation category and type - 3D Slicer General Anatomy list",
"category": ["SCT", "123037004", "Anatomical Structure"],
"type": ["SCT", "113197003", "Rib"] }
},
{
"id": "Segment_2",
"labelValue": 3,
"layer": 0,
"color": [0.9, 0.9, 0.6],
"name": "spine",
"status": "inprogress",
"terminology": {
"contextName": "Segmentation category and type - 3D Slicer General Anatomy list",
"category": ["SCT", "123037004", "Anatomical Structure"],
"type": ["SCT", "122494005", "Cervical spine"] }
},
]
}
slicerio.write_segmentation(segmentation, "path/to/Segmentation.seg.nrrd")
input_nifti_filename = "path/to/Segmentation.nii.gz"
output_filename = "path/to/Segmentation.seg.nrrd"
segmentation = slicerio.read_segmentation(input_nifti_filename)
# Specify segment metadata for each label value
# (NIFTI cannot store segment metadata in the image file)
segmentation["segments"] = [
{ "labelValue": 1,
"color": [0.9, 0.9, 0.6],
"name": "ribs",
"terminology": {
"contextName": "Segmentation category and type - 3D Slicer General Anatomy list",
"category": ["SCT", "123037004", "Anatomical Structure"],
"type": ["SCT", "113197003", "Rib"] } },
{ "labelValue": 3,
"color": [0.9, 0.1, 0.2],
"name": "spine",
"terminology": {
"contextName": "Segmentation category and type - 3D Slicer General Anatomy list",
"category": ["SCT", "123037004", "Anatomical Structure"],
"type": ["SCT", "122494005", "Cervical spine"] } },
]
slicerio.write_segmentation(output_filename, segmentation)
The server
module allows using Slicer as a data viewer in any Python environment.
All files are loaded into a single Slicer instance, which eliminates the wait time for application startup
and also allows analyzing, comparing multiple data sets in one workspace. The feature is implemented by using
3D Slicer's built-in Web Server module, which offers data access via a REST API.
For example, an image file can be loaded with the command below. The command starts a new Slicer application instance with the web API enabled.
import os
import slicerio.server
# Load from remote URL
slicerio.server.file_load("https://github.com/rbumm/SlicerLungCTAnalyzer/releases/download/SampleData/LungCTAnalyzerChestCT.nrrd")
# Load from local file
# A Slicer application instance (with Web Server enabled) is automatically started, if it is not running already.
slicerio.server.file_load("path/to/SomeImage.nrrd", slicer_executable=f"{os.environ["LOCALAPPDATA"]}/NA-MIC/Slicer 5.2.0/Slicer.exe")
A segmentation file can be loaded by specifying the SegmentationFile
file type:
nodeID = slicerio.server.file_load("path/to/Segmentation.seg.nrrd", "SegmentationFile")
If the loaded file is modified then it can be reloaded from the updated file:
slicerio.server.node_reload(id=nodeID)
VolumeFile
SegmentationFile
ModelFile
MarkupsFile
TransformFile
TableFile
TextFile
SequenceFile
SceneFile
Metadata of data sets loaded into the server can be obtained using node_properties
function:
properties= slicerio.server.node_properties(name="MRHead")[0]
print(properties["ClassName"])
print(properties["ImageData"]["Extent"])
properties = slicerio.server.node_properties(id=segmentationId)[0]
segments = properties["Segmentation"]["Segments"]
for segmentId in segments:
print(f"Segment name: {segments[segmentId]['Name']} - color: {segments[segmentId]['Color']}")
List of available nodes can be retrieved using node_names
and node_ids
functions:
# Retreve node names of all images
slicerio.server.node_names(class_name="vtkMRMLVolumeNode")
# Retrieve all node IDs
slicerio.server.node_ids(class_name="vtkMRMLVolumeNode")
Nodes can be removed from the workspace:
# Remove node by name
slicerio.server.node_remove(name="MRHead")
# Clear the whole scene
slicerio.server.node_remove()
Data sets created in Slicer (e.g., segmentations, landmark point sets), which can be retrieved by writing into file.
# Save the node identified by `MRHead` node name, uncompressed, into the specified file.
slicerio.server.file_save("c:/tmp/MRHeadSaved.nrrd", name="MRHead", properties={'useCompression': False})
FAQs
Utilities for 3D Slicer
We found that slicerio demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Four npm packages disguised as cryptographic tools steal developer credentials and send them to attacker-controlled Telegram infrastructure.
Security News
Ruby maintainers from Bundler and rbenv teams are building rv to bring Python uv's speed and unified tooling approach to Ruby development.
Security News
Following last week’s supply chain attack, Nx published findings on the GitHub Actions exploit and moved npm publishing to Trusted Publishers.