Loads and processes 3D medical images in MATLAB Medical Imaging Toolbox: DICOM/NIfTI/NRRD I/O, volume visualization, registration, radiomics features, MedSAM segmentation, PACS queries.
How this skill is triggered — by the user, by Claude, or both
Slash command
/matlab-toolbox-skills:matlab-medical-imaging-toolbox-v2The summary Claude sees in its skill listing — used to decide when to auto-load this skill
Expert skill for 3D medical image analysis using MATLAB's Medical Imaging Toolbox (MIT R2025b+).
knowledge/INDEX.mdknowledge/cards/coordinate-systems.mdknowledge/cards/cross-toolbox-ipt.mdknowledge/cards/file-io-dicom.mdknowledge/cards/file-io-nifti-nrrd.mdknowledge/cards/labeling-workflow.mdknowledge/cards/medical-volume.mdknowledge/cards/pacs-integration.mdknowledge/cards/radiomics-features.mdknowledge/cards/registration-deformable.mdknowledge/cards/registration-rigid.mdknowledge/cards/segmentation-cellpose.mdknowledge/cards/segmentation-medsam.mdknowledge/cards/visualization-3d.mdscripts/template_cellpose_segmentation.mscripts/template_coordinate_transform.mscripts/template_deformable_registration.mscripts/template_dicom_series_loader.mscripts/template_labeling_workflow.mscripts/template_medsam_segmentation.mExpert skill for 3D medical image analysis using MATLAB's Medical Imaging Toolbox (MIT R2025b+).
Cross-Toolbox Note: For filtering, segmentation, and morphology, use Image Processing Toolbox functions (imgaussfilt, imbinarize, strel, watershed, regionprops). MIT handles I/O, spatial referencing, registration, and medical-specific workflows.
medicalVolume objects with spatial referencingvolshow, sliceViewer)| Task | Knowledge Card | Key Functions |
|---|---|---|
| Read DICOM series | file-io-dicom.md | medicalVolume, dicomread, dicomCollection |
| Load NIfTI/NRRD | file-io-nifti-nrrd.md | niftiread, nrrdread, niftiinfo |
| Create medical volume | medical-volume.md | medicalVolume, medicalImage, medicalref3d |
| Coordinate conversion | coordinate-systems.md | intrinsicToWorld, worldToIntrinsic |
| 3D visualization | visualization-3d.md | volshow, sliceViewer |
| Rigid registration | registration-rigid.md | imregmoment, imregicp, fitgeotform3d |
| Deformable registration | registration-deformable.md | imregdeform, imreggroupwise |
| Extract radiomics | radiomics-features.md | radiomics object, then intensityFeatures(R) |
| Segment with MedSAM | segmentation-medsam.md | medicalSegmentAnythingModel |
| Cell segmentation | segmentation-cellpose.md | Watershed, MedSAM, or Python Cellpose |
| Label ground truth | labeling-workflow.md | groundTruthMedical, Medical Image Labeler |
| PACS server access | pacs-integration.md | dicomConnection, dicomquery, dicomget |
| Apply filtering | cross-toolbox-ipt.md | -> See IPT skill |
| Threshold/segment | cross-toolbox-ipt.md | -> See IPT skill |
Ready-to-use template scripts in scripts/ -- copy, rename, and adapt for your task:
| Script | Task |
|---|---|
template_dicom_series_loader.m | Load DICOM series with dicomCollection |
template_nifti_volume_processing.m | Load, process, and save NIfTI volumes |
template_coordinate_transform.m | Coordinate system conversions |
template_volume_visualization.m | 3D rendering and slice browsing |
template_rigid_registration.m | Rigid/affine registration workflow |
template_deformable_registration.m | Non-rigid deformable registration |
template_radiomics_extraction.m | Radiomics feature extraction pipeline |
template_medsam_segmentation.m | MedSAM interactive segmentation |
template_cellpose_segmentation.m | Cell/nuclei instance segmentation |
template_labeling_workflow.m | Ground truth labeling setup |
template_pacs_query_retrieve.m | PACS server query and retrieval |
template_multimodal_fusion.m | PET/CT or multimodal overlay |
Medical images have TWO coordinate systems:
| System | Units | Origin | Use Case |
|---|---|---|---|
| Intrinsic | Voxel indices (i,j,k) | Corner of first voxel | Array indexing, IPT functions |
| Patient/World | Physical units (mm) | DICOM-defined patient origin | Clinical measurements, registration |
% WRONG: Mixing coordinate systems
pixel = V.Voxels(100, 200, 50); % Intrinsic indexing
world_point = [100, 200, 50]; % Treating indices as world coords!
% CORRECT: Explicit conversion (separate coordinate arrays)
V = medicalVolume('scan.nii');
i = 100; j = 200; k = 50; % Voxel indices
[x, y, z] = intrinsicToWorld(V.VolumeGeometry, i, j, k);
% x, y, z are now in mm, in patient coordinate system
world_point = [x, y, z];
% Convert back (also requires separate arrays)
[row, col, slice] = worldToSubscript(V.VolumeGeometry, x, y, z);
Never read raw voxels without spatial information:
% WRONG: Loses spatial referencing
data = niftiread('brain.nii'); % Just a 3D array, no spatial info
% CORRECT: Preserves geometry
V = medicalVolume('brain.nii');
% V.VolumeGeometry contains transformation matrix
% V.VoxelSpacing is in mm
% V.SpatialUnits documents the units
Slice orientation depends on acquisition, not array dimension:
V = medicalVolume('scan.dcm');
% Check orientation
disp(V.Orientation); % 'transverse', 'sagittal', or 'coronal'
disp(V.PlaneMapping); % Maps dimensions to anatomical planes
% Extract slices in patient coordinates (not array indices!)
slice = extractSlice(V, 50, 'transverse'); % 50th transverse slice
% For axial browsing regardless of acquisition:
sliceViewer(V); % Automatically handles orientation
Always inspect metadata before processing:
% Get collection info for DICOM series
collection = dicomCollection('DICOM_folder');
disp(collection.Properties.VariableNames);
% Check modality, series description
info = dicominfo('slice001.dcm');
fprintf('Modality: %s\n', info.Modality);
fprintf('Series: %s\n', info.SeriesDescription);
fprintf('Spacing: %.2f x %.2f x %.2f mm\n', ...
info.PixelSpacing(1), info.PixelSpacing(2), info.SliceThickness);
Large volumes (512×512×500+) require careful memory handling:
% Check volume size before loading
info = niftiinfo('large_scan.nii');
voxels = prod(info.ImageSize);
bytes_needed = voxels * info.BitsPerPixel / 8;
fprintf('Size: %.2f GB\n', bytes_needed / 1e9);
% Process slice-by-slice for huge volumes
for k = 1:V.NumTransverseSlices
slice = extractSlice(V, k, 'transverse');
% Process slice using IPT functions
processed = imgaussfilt(slice, 1.5); % IPT
V = replaceSlice(V, processed, k, 'transverse');
end
MIT handles I/O and spatial referencing; IPT handles pixel-level processing:
% Load with MIT (preserves spatial info)
V = medicalVolume('scan.nii');
% Process with Image Processing Toolbox functions
voxels = im2double(V.Voxels);
voxels = imgaussfilt3(voxels, 1.5); % Gaussian smoothing
voxels = adapthisteq(voxels, 'NumTiles', [4 4 4]); % CLAHE
% Segment with IPT
level = graythresh(voxels(:));
mask = voxels > level;
mask = imopen(mask, strel('sphere', 3)); % Morphological cleanup
% Create labeled volume with MIT (preserves spatial context)
labelVol = medicalVolume(uint8(mask), V.VolumeGeometry);
labelVol.Modality = 'SEG';
write(labelVol, 'segmentation.nii');
% From directory of DICOM files
V = medicalVolume('path/to/dicom_folder');
% From dicomCollection for multi-series
coll = dicomCollection('patient_folder', 'IncludeSubfolders', true);
disp(coll); % Shows all series
% Load specific series
V = medicalVolume(coll, 'Rows', 2); % 2nd series in collection
V = medicalVolume('brain.nii');
% Get middle slices in each plane
midT = round(V.NumTransverseSlices / 2);
midC = round(V.NumCoronalSlices / 2);
midS = round(V.NumSagittalSlices / 2);
transverse = extractSlice(V, midT, 'transverse');
coronal = extractSlice(V, midC, 'coronal');
sagittal = extractSlice(V, midS, 'sagittal');
% Display
figure;
subplot(1,3,1); imshow(transverse, []); title('Transverse');
subplot(1,3,2); imshow(coronal, []); title('Coronal');
subplot(1,3,3); imshow(sagittal, []); title('Sagittal');
fixed = medicalVolume('pre_contrast.nii');
moving = medicalVolume('post_contrast.nii');
% Rigid registration (fast, for same-modality)
[registered, tform] = imregmoment(moving, fixed);
% Affine registration with optimization
[optimizer, metric] = imregconfig('monomodal');
tform = imregtform(moving.Voxels, moving.VolumeGeometry, ...
fixed.Voxels, fixed.VolumeGeometry, ...
'affine', optimizer, metric);
% Apply transformation
registered = imwarp(moving.Voxels, tform, 'OutputView', ...
imref3d(size(fixed.Voxels)));
Object-Oriented API: Always create a
radiomics(data, roi)object first, then callintensityFeatures(R),shapeFeatures(R),textureFeatures(R)on the object. Do NOT pass data/mask directly to feature functions.
V = medicalVolume('tumor_scan.nii');
mask = medicalVolume('tumor_mask.nii');
% Resample to isotropic (required for some features)
V_iso = resample(V, [1 1 1]); % 1mm isotropic
mask_iso = resample(mask, [1 1 1]);
% STEP 1: Create radiomics object (REQUIRED)
R = radiomics(V_iso.Voxels, mask_iso.Voxels > 0);
% STEP 2: Extract features as methods of the object
intensity = intensityFeatures(R); % NOT intensityFeatures(data, mask)
shape = shapeFeatures(R); % NOT shapeFeatures(mask, spacing)
texture = textureFeatures(R); % NOT textureFeatures(data, mask)
% Combine into table
features = [intensity, shape, texture];
% Load model (requires support package)
model = medicalSegmentAnythingModel;
% Load image and extract embeddings
V = medicalVolume('liver_ct.nii');
slice = extractSlice(V, 50, 'transverse');
embeddings = extractEmbeddings(model, slice);
% Get image size (required parameter)
imageSize = size(slice);
% Segment with bounding box prompt (imageSize is required)
bbox = [100, 100, 200, 150]; % [x, y, width, height]
[mask, score] = segmentObjectsFromEmbeddings(model, embeddings, imageSize, ...
BoundingBox=bbox);
| Function | Purpose | Example |
|---|---|---|
medicalVolume | Load 3D medical image | V = medicalVolume('scan.nii') |
medicalImage | Load 2D medical image series | I = medicalImage('us_video.dcm') |
dicomread | Read single DICOM file | img = dicomread('slice.dcm') |
dicominfo | Read DICOM metadata | info = dicominfo('slice.dcm') |
dicomCollection | Catalog DICOM folders | coll = dicomCollection(folder) |
niftiread | Read NIfTI file | data = niftiread('brain.nii') |
nrrdread | Read NRRD file | data = nrrdread('scan.nrrd') |
write | Write medicalVolume to NIfTI | write(V, 'output.nii') |
| Function | Purpose | Example |
|---|---|---|
medicalref3d | Create spatial reference | R = medicalref3d(volumeSize, voxelSpacing) |
intrinsicToWorld | Voxel to patient coords | [X,Y,Z] = intrinsicToWorld(R, I, J, K) |
worldToIntrinsic | Patient to voxel coords | [I,J,K] = worldToIntrinsic(R, X, Y, Z) |
worldToSubscript | Patient coords to indices | [row,col,slice] = worldToSubscript(R, X, Y, Z) |
extractSlice | Get slice in patient space | s = extractSlice(V, n, 'transverse') |
resample | Resample to new resolution | V2 = resample(V, [1 1 1]) |
| Function | Purpose | Example |
|---|---|---|
volshow | 3D volume rendering + overlay | volshow(V) or volshow(V, OverlayData=L) |
sliceViewer | Orthogonal slice browser | sliceViewer(V) |
montage | 2D slice montage | montage(V.Voxels) |
implay | Video playback (2D series) | implay(I) |
Note:
labelvolshowwas removed in R2025b. Usevolshow(V, OverlayData=labels)for segmentation overlay.
| Function | Purpose | Example |
|---|---|---|
imregmoment | Fast moment-based rigid | [tform, reg] = imregmoment(moving, fixed) |
imregicp | Iterative closest point | [regSurf, tform] = imregicp(surf1, surf2) |
imregdeform | Deformable registration | D = imregdeform(moving, fixed) |
imreggroupwise | Groupwise registration | tforms = imreggroupwise(volumes) |
fitgeotform3d | Landmark-based transform | tform = fitgeotform3d(pts1, pts2, 'affine') |
| Step | Function | Example |
|---|---|---|
| 1. Create object | radiomics | R = radiomics(data, roi) |
| 2a. Intensity | intensityFeatures(R) | F = intensityFeatures(R) |
| 2b. Shape | shapeFeatures(R) | F = shapeFeatures(R) |
| 2c. Texture | textureFeatures(R) | F = textureFeatures(R) |
Always call feature functions on the
radiomicsobjectR, never on raw data.
| Function | Purpose | Example |
|---|---|---|
medicalSegmentAnythingModel | Load MedSAM | model = medicalSegmentAnythingModel |
extractEmbeddings | Compute image embeddings | emb = extractEmbeddings(model, img) |
segmentObjectsFromEmbeddings | Segment with prompts | mask = segmentObjectsFromEmbeddings(...) |
Cell segmentation: MATLAB R2025b does not include built-in Cellpose functions. Use watershed-based instance segmentation (IPT), MedSAM interactive segmentation, or Python Cellpose via
pyrunfile. Seesegmentation-cellpose.mdknowledge card for all approaches.
| Function | Purpose | Example |
|---|---|---|
dicomConnection | Connect to PACS | conn = dicomConnection(ip, port) |
dicomquery | Query PACS for studies | results = dicomquery(conn, 'Study') |
dicomget | Retrieve images | dicomget(conn, results, folder) |
dicomstore | Send images to PACS | dicomstore(conn, folder) |
Detailed documentation organized by topic:
File I/O:
knowledge/cards/file-io-dicom.md - DICOM reading, metadata, series handlingknowledge/cards/file-io-nifti-nrrd.md - NIfTI and NRRD formatsCore Concepts:
knowledge/cards/medical-volume.md - medicalVolume class and propertiesknowledge/cards/coordinate-systems.md - Patient vs Intrinsic coordinates (CRITICAL)knowledge/cards/visualization-3d.md - volshow, sliceViewer, rendering optionsRegistration:
knowledge/cards/registration-rigid.md - Rigid/affine registration methodsknowledge/cards/registration-deformable.md - Deformable and groupwise registrationAnalysis:
knowledge/cards/radiomics-features.md - IBSI-compliant radiomics (object-oriented API: radiomics -> methods)knowledge/cards/segmentation-medsam.md - Medical Segment Anything Modelknowledge/cards/segmentation-cellpose.md - Cell/nuclei segmentation strategiesWorkflows:
knowledge/cards/labeling-workflow.md - Medical Image Labeler appknowledge/cards/pacs-integration.md - PACS server communicationknowledge/cards/cross-toolbox-ipt.md - Using IPT functions with MITFor filtering, segmentation, and morphology, use Image Processing Toolbox functions (imgaussfilt, imbinarize, strel, watershed, regionprops)
| MIT Task | IPT Function | IPT Knowledge Card |
|---|---|---|
| Denoise volume slices | imgaussfilt, medfilt2, wiener2 | filtering-denoising.md |
| Enhance contrast | adapthisteq, imadjust | filtering-denoising.md |
| Threshold volume | graythresh, imbinarize | segmentation-thresholding.md |
| Clean binary masks | imopen, imclose, imfill, bwareaopen | morphology-binary.md |
| Measure regions | regionprops3, bwconncomp | feature-regions.md |
| Detect edges | edge, imgradient | feature-edges.md |
| Data type conversion | im2double, im2uint8 | data-types.md |
For wavelet-based denoising, use Wavelet Toolbox functions (wdenoise2)
% Combined workflow: MIT + IPT + Wavelet
V = medicalVolume('noisy_mri.nii'); % MIT: Load with spatial info
% Process each slice (IPT + Wavelet)
for k = 1:size(V.Voxels, 3)
slice = im2double(V.Voxels(:,:,k)); % IPT: Convert type
slice = wdenoise2(slice); % Wavelet: Denoise
slice = adapthisteq(slice); % IPT: Enhance
V.Voxels(:,:,k) = slice;
end
write(V, 'enhanced_mri.nii'); % MIT: Write with spatial info
Verified against MATLAB R2025b
npx claudepluginhub rrmaram2000/matlab-toolbox-skills --plugin matlab-toolbox-skillsReads/writes DICOM medical images (CT, MRI, X-ray, ultrasound). Extracts pixels as NumPy arrays, edits tags, applies VOI LUT windowing, anonymizes PHI, builds 3D volumes from series.
Reads, writes, and manipulates DICOM medical imaging files using the pydicom Python library. Useful for extracting pixel data, anonymizing files, working with metadata/tags, converting formats, and handling compressed DICOM for PACS and radiology workflows.
Reads, writes, and manipulates DICOM medical imaging files using Python. Extracts pixel data (CT, MRI, X-ray), handles metadata/tags, anonymization, and format conversion.