Matlab Analyze Spectral Images
MathWorksOfficialCreated by MathWorks
- Skill
- Tool integration
- Science and research
- BSD-2-Clause
- No issues found
AutoGineer summary
Written by AutoGineer from the skill’s own files, not by the author
This skill provides a comprehensive interface for working with hyperspectral and multispectral data within the MATLAB environment. It covers the entire lifecycle of spectral imaging, including data ingestion from various formats (ENVI, NITF, TIFF, Sentinel-2, Landsat, ASTER), radiometric calibration, atmospheric correction, and advanced analytical techniques such as spectral unmixing, anomaly detection, and spectral index calculation. The skill also supports modern deep learning workflows, including pixel classification with 3D CNNs and semantic segmentation, as well as interactive labeling via the Spectral Image Labeler app.
What it does
- Reads and writes industry-standard spectral image formats like ENVI, NITF, and GeoTIFF.
- Performs radiometric calibration and atmospheric correction on raw spectral data.
- Executes advanced spectral analysis including endmember extraction, unmixing, and target detection.
- Computes standard and custom spectral indices like NDVI and EVI using optimized built-in functions.
- Facilitates spectral-aware image segmentation and clustering.
- Supports deep learning pipelines for pixel classification and semantic segmentation of spectral cubes.
When to use it
- When processing hyperspectral or multispectral satellite or airborne imagery.
- When performing quantitative analysis on spectral signatures using ECOSTRESS libraries.
- When building deep learning models for spectral image classification or unmixing.
- When needing to compute spectral indices or perform anomaly detection on hypercubes.
- When managing large-scale spectral data with block processing requirements.
Advantages
- Optimized built-in functions for spectral indices and processing, avoiding manual computation errors.
- Seamless integration with MATLAB's deep learning and image processing toolboxes.
- Native support for complex spectral data structures and metadata management.
- Includes specialized apps for interactive labeling and visualization of high-dimensional data.
Usage examples
- “Read a hyperspectral image from an ENVI file and calculate the NDVI.”
- The agent provides code to load the file using imhypercube and compute the index using the built-in ndvi function.
- “How do I perform anomaly detection on my hyperspectral cube?”
- The agent provides the syntax for anomalyRX to identify anomalous pixels within the spectral data.
- “Extract endmembers from my hyperspectral data.”
- The agent provides a workflow using countEndmembersHFC to determine the number of endmembers followed by nfindr for extraction.
- “How can I visualize my multispectral cube as a true-color image?”
- The agent provides the colorize function syntax with the appropriate method parameter for multicube visualization.
Install
Download the skill as a ZIP:
https://autogineer.com/agent-skills/matlab/matlab-analyze-spectral-images/downloadUnzip it into the cross-client skills folder of your project:
mkdir -p .agents/skills && unzip matlab-analyze-spectral-images.zip -d .agents/skills
Documentation by MathWorks
Spectral Imaging Skill
Generate MATLAB code for working with hyperspectral and multispectral data using the Hyperspectral Imaging Library for Image Processing Toolbox. Requires desktop MATLAB (not MATLAB Online or MATLAB Mobile) and the Hyperspectral Imaging Library add-on.
When to Use
Reading/writing hyperspectral or multispectral images (ENVI, NITF, GeoTIFF, TIFF, ASTER, Sentinel-2, Landsat)
Reading ECOSTRESS spectral library signatures (
readEcostressSig)Creating hypercube/multicube objects, band selection, cropping, block processing
Radiometric calibration, atmospheric correction, spectral correction
Denoising, sharpening, dimensionality reduction (PCA, MNF)
Endmember extraction, spectral unmixing, abundance estimation
Spectral matching, target detection, anomaly detection
Computing spectral indices (NDVI, EVI, custom)
Segmentation (spectral clustering, superpixels, ISODATA)
Labeling with the Spectral Image Labeler app
Creating ground truth objects for spectral labeling
Deep learning classification or unmixing of spectral images
Semantic segmentation of multispectral satellite imagery (DeepLabV3+ with multi-channel input)
When NOT to Use
General image reading/writing (use
imread/imwrite)Non-spectral 3-D volume data (use Medical Imaging or Image Processing Toolbox)
General image classification not involving spectral cubes (use Deep Learning Toolbox)
Non-spectral semantic segmentation of RGB/grayscale images (use Computer Vision Toolbox)
Point spectra or spectral libraries without spatial dimensions
Prerequisite Check
If you suspect the Hyperspectral Imaging Library might not be installed (e.g., user reports errors), verify with exist('imhypercube','file'). If not installed, suggest installing via Add-On Explorer and fall back to multibandread/imread. Do NOT run this check if you are confident the library is available.
Quick Start
% Read hyperspectral data
hcube = imhypercube("scene.hdr");
% Visualize — colorize syntax (NO name-value for basic usage):
falseColor = colorize(hcube); % false-colored image (default, 3 most informative bands)
rgb = colorize(hcube, Method="rgb"); % true RGB (hypercube ONLY — needs R/G/B wavelengths)
cir = colorize(hcube, Method="cir"); % color infrared (hypercube ONLY)
custom = colorize(hcube, [30 20 10]); % false color from specific band INDICES (not wavelengths)
imshow(falseColor)
% Radiometric pipeline
hcube = dn2radiance(hcube);
hcube = radiance2Reflectance(hcube);
hcube = fastInScene(hcube);
% Compute NDVI
ndviMap = ndvi(hcube);
% Endmember extraction and unmixing
numEM = countEndmembersHFC(hcube);
endmembers = nfindr(hcube, numEM);
abundance = estimateAbundanceLS(hcube, endmembers, Method="fcls");
% Anomaly detection
rxScore = anomalyRX(hcube);
% Segmentation
L = hyperseganchor(hcube, 8);
% Launch viewer app
hyperspectralViewer(hcube)
% Launch labeler app (Since R2026a)
spectralImageLabeler(hcube)Essential Syntax (use without reading reference files)
colorize — Visualization
% HYPERCUBE (supports Method, 2 outputs, ContrastStretching default=false)
falseColor = colorize(hcube) % false-colored (default)
rgb = colorize(hcube, Method="rgb") % true color RGB
cir = colorize(hcube, Method="cir") % color infrared
custom = colorize(hcube, [b1 b2 b3]) % 3 band indices
[img, indices] = colorize(hcube) % also get band indices used
img = colorize(hcube, ContrastStretching=true) % with CLAHE
% MULTICUBE (NO Method param, 1 output, ContrastStretching default=true)
rgb = colorize(mcube) % true RGB (auto-selects by wavelength)
custom = colorize(mcube, [b1 b2 b3]) % false color from band indices
img = colorize(mcube, ContrastStretching=false) % disable contrast stretchingI/O and Band Management
hcube = imhypercube("file.hdr"); % read ENVI/NITF/TIFF
mcube = immulticube("MTL.txt"); % read Landsat (pass *_MTL.txt file)
mcube = immulticube("manifest.safe"); % read Sentinel-2 (pass manifest.safe file, NOT .SAFE folder)
mcube = immulticube("AST_L1T.hdf"); % read ASTER HDF
cropped = cropData(hcube, 30:110, 30:110); % row indices, col indices (NOT [x y w h])
vnir = selectBands(hcube, Wavelength=[400 1000]); % by wavelength range
subset = selectBands(hcube, BandNumber=[1 10 20]); % by band index
cleaned = removeBands(hcube, Wavelength=[1350 1450]); % remove wavelength range
data = gather(hcube); % get M-by-N-by-C numeric array
% ACCESSING DIMENSIONS — NO NumRows/NumColumns/NumBands properties exist:
height = hcube.Metadata.Height; % number of rows (M)
width = hcube.Metadata.Width; % number of columns (N)
bands = hcube.Metadata.Bands; % number of spectral bands (C)
% For multicube: use mcube.BandSize(1,1) for height, mcube.BandSize(1,2) for width
% RESAMPLING vs SELECTING (multicube only):
mcubeUniform = resampleBands(mcube, 30); % RESAMPLE all bands TO 30m (keeps ALL bands, changes spatial size)
mcubeUniform = resampleBands(mcube, 30, Method="bilinear"); % interpolation: "nearest"(default),"bilinear","cubic"
mcube30m = selectBands(mcube, "DataResolution", 30); % KEEP only bands already at 30m (DISCARDS others)
% When asked to "resample" or "match resolution" → use resampleBands
% When asked to "select" or "filter" bands by resolution → use selectBandsSpectral Indices (NEVER compute manually — use built-in functions)
% NDVI — use built-in ndvi() function (supports block processing natively)
ndviMap = ndvi(spcube); % direct numeric M-by-N output, range [-1,1]
ndviMap = ndvi(spcube, BlockSize=[512 512]); % with block processing for large data
% Standard indices — use spectralIndices() (returns struct with .IndexName and .IndexImage)
indices = spectralIndices(spcube, "NDVI"); % single index → struct
indices = spectralIndices(spcube, ["NDVI","EVI"]); % multiple → struct array
indices = spectralIndices(spcube, "all"); % all 16 supported indices
indices = spectralIndices(spcube, "NDVI", BlockSize=[512 512]); % with block processing
% Supported: "NDVI","EVI","NDBI","NBR","MNDWI","MSI","GVI","OSAVI","SR","CMR","MCARI","MTVI","PRI","NDNI","NDMI","CAI"
% Custom formula — use customSpectralIndex() (3 required args: cube, wavelengths, @func)
indexImage = customSpectralIndex(spcube, [800 670], @(nir,red) (nir-red)./(nir+red));
indexImage = customSpectralIndex(spcube, [800 670 475], @(nir,red,blue) 2.5*(nir-red)./(nir+6*red-7.5*blue+1));
indexImage = customSpectralIndex(spcube, [560 1650], @(g,swir) (g-swir)./(g+swir), BlockSize=[512 512]);
% DO NOT manually extract bands and compute — always use these built-in functionsDetection, Matching, and Processing
% Target detection — method is POSITIONAL (3rd arg, not Name=Value)
target = resampleSignature(libData(1), hcube.Wavelength); % resample library spectrum to cube wavelengths
score = detectTarget(hcube, target, "ACE"); % "CEM","ACE","SignedACE","MF","GLRT","AMSD","OSP"
rxScore = anomalyRX(hcube); % higher = more anomalous
% Similarity scores — cube first, reference second (lower = better match)
score = sam(hcube, refSpectrum); % spectral angle mapper [0, pi]
score = sid(hcube, refSpectrum); % spectral information divergence
% spectralMatch — UNUSUAL ARG ORDER: library struct FIRST, then cube/spectrum
% DO NOT pass numeric vectors — first arg MUST be a struct with .Reflectance and .Wavelength fields
libData = readEcostressSig("vegetation.txt"); % returns 1-by-K struct array
score = spectralMatch(libData, hcube); % returns M-by-N-by-K (one score map per signature)
score = spectralMatch(libData, hcube, Method="sam");% "sam"(default),"sid","sidsam","jmsam","ns3"
score = spectralMatch(libData, reflectance, wavelength); % compare against single spectrum (returns K-vector)
% Lower score = stronger match. Returns NaN when bandwidth overlap < MinBandWidth (default 300nm)
% For direct numeric comparison without library: use sam(hcube, target) or sid(hcube, target)
% Spectral clustering / segmentation (use INSTEAD of kmeans for spectral data)
L = hyperseganchor(hcube, numClusters); % spectral-aware clustering (1 output)
[L, n] = hyperslic(hcube, K); % spectral superpixels (2 outputs)
% Block processing — callback receives OBJECT, must use gather()
result = apply(hcube, @(block) mean(gather(block), 3));Workflow
For functions fully documented in the Essential Syntax and Common Mistakes sections above, generate code directly — those sections provide complete API signatures and constraints.
Read a reference file ONLY when:
Using a function NOT covered in Essential Syntax (e.g.,
sharc,empiricalLine,sharpencnmf,spectralImageLabeler)Unsure about argument order or constraints for a complex workflow
The task involves the Spectral Image Labeler app or ground truth objects
Reference Files (consult only when needed):
references/spectral-io.md — I/O, band selection, cropping, block processing, colorize, enviwrite
references/spectral-calibration.md — Radiometric calibration, atmospheric correction, spectral correction, denoising, sharpening
references/spectral-analysis.md — PCA/MNF, unmixing, spectral matching, target/anomaly detection, indices, segmentation
references/spectral-deep-learning.md — Labeler app, groundTruthSpectralImage, deep learning pipelines
references/dl-classification.md — 3-D CNN, 1-D CNN, ground truth to training data workflows
references/dl-advanced.md — Unmixing autoencoder, transfer learning, DeepLabV3+ semantic segmentation
CRITICAL: Common Mistakes to Avoid
These are the most frequent errors. Violating any of these will cause runtime failures:
NEVER use
hypercube()— deprecated. Useimhypercube()orgeohypercube().cropData(hcube, 30:110, 30:110)— row/col INDEX VECTORS, not[x y w h]selectBands/removeBandsrequire Name=Value:selectBands(hcube, BandNumber=[1 10 20]),removeBands(hcube, Wavelength=[1350 1450]).removeBandserrors if range outside cube's actual wavelengths.customSpectralIndex(spcube, [800 670], @(nir,red) (nir-red)./(nir+red))— 3 args requiredapply(hcube, @(block) mean(gather(block), 3))— callback receives OBJECT, usegather()inverseProjection(pcaCube, coeff)— data first, coefficients secondspectralMatch(libData, hcube)— struct fromreadEcostressSigFIRST. For numeric: usesam(hcube, target)directly.L = hyperseganchor(hcube, 8)(1 output);[L, n] = hyperslic(hcube, 100)(2 outputs)immulticubedoes NOT support ENVI. Sentinel-2: passmanifest.safe(NOT.SAFEfolder). Landsat:*_MTL.txt. ASTER:.hdf.spectralIndices(hcube, "NDVI")→ struct with.IndexName/.IndexImage. Usendvi(hcube)for numeric.hyperslicwith 3 bands:hyperslic(data, 100, IsInputDimReduced=true). Only params:NumIterations(max 30),IsInputDimReduced. NOCompactness.detectTarget(hcube, target, "ACE")— method is POSITIONAL, not Name=ValuedenoiseNGMeet: needs spatial dims > 16. Crop large images to ≤1024x1024 first.flatField(hcube, [xmin ymin width height])— rect vector, NOT index vectors likecropDatacolorize(mcube)→ true RGB (NOMethodparam!).colorize(mcube, [b1 b2 b3])for false-color.colorize(hcube, Method="rgb")only works on hypercube.resampleBands(mcube, 30)= resizes all bands to target res.selectBands(mcube, "DataResolution", 30)= keeps only bands already at that res.NO
NumRows/NumColumns/NumBandsproperties. Usehcube.Metadata.Height/Width/Bands. Multicube:mcube.BandSize(1,1)/mcube.BandSize(1,2).NEVER manually compute indices. Use
ndvi(spcube),spectralIndices(spcube, "NDVI"), orcustomSpectralIndex(spcube, [wl1 wl2], @(b1,b2) formula).sam/sidrefSpectra must be C-element VECTOR, not matrix.assignData(hcube, rows, cols, bands, data)— 5 args with index rangesenviwrite(hcube, "output")— hypercube ONLY, not multicubegroundTruthSpectralImagelabelDefs: 6 columns required includingAttributeList. Property:LabelDefinitions(plural).
Key Rules
Pipeline: DN → radiance → reflectance → atmospheric correction. Smile correction BEFORE denoising.
L2 products already have surface reflectance — DN pipeline is for L1 only.
Research datasets (Indian Pines, PaviaU) lack calibration metadata.
hypercube ONLY:
denoiseNGMeet,hyperpca,hypermnf,inverseProjection,sharpencnmf,countEndmembersHFC,nfindr,ppi,estimateAbundanceLS,anomalyRX,sam,sid,spectralMatch,hyperslic,sharc,empiricalLine,reduceSmilehypercube + multicube:
dn2radiance,radiance2Reflectance,fastInScene,detectTarget,ndvi,spectralIndices,customSpectralIndex,hyperseganchor+ numeric array:
flatField,iarr,logResiduals,subtractDarkPixelDeep learning:
trainnet+dlnetwork(nottrainNetwork). Usehyperpcabefore CNN.Valid
spectralIndicesnames: ndvi, osavi, sr, evi, gvi, ndni, pri, cai, mcari, mtvi, msi, cmr, nbr, ndbi, ndmi, mndwi (NOT "ndwi")Labeler (R2026a+):
groundTruthSpectralImageproperties are read-only after creation
Copyright 2026 The MathWorks, Inc.
Files
- ATTRIBUTION.mdAdded by AutoGineer1.1 KiB
- LICENSELicence file added by AutoGineer1.4 KiB
- SKILL.md14.5 KiB
- manifest.yaml498 B
- references/dl-advanced.md7.3 KiB
- references/dl-classification.md7.7 KiB
- references/spectral-analysis.md14.5 KiB
- references/spectral-calibration.md10.0 KiB
- references/spectral-deep-learning.md10.9 KiB
- references/spectral-io.md17.0 KiB
references/spectral-io.md
Spectral Image I/O Reference
Reading, writing, and preparing hyperspectral/multispectral data using the Hyperspectral Imaging Library for Image Processing Toolbox.
Requirement: Desktop MATLAB only (not MATLAB Online or MATLAB Mobile). Requires the Hyperspectral Imaging Library add-on for Image Processing Toolbox.
CRITICAL: NEVER use the deprecated hypercube() constructor directly. It will be removed in a future release. Always use imhypercube, geohypercube, immulticube, or geomulticube instead.
Core Objects
Two object types: hypercube (hyperspectral, uniform bands) and multicube (multispectral, variable resolution bands).
Choosing the right creation function:
| Data Type | No Geospatial | With Geospatial (needs Mapping Toolbox) |
|---|---|---|
| Hyperspectral (many narrow bands) | imhypercube | geohypercube |
| Multispectral (few broad bands) | immulticube | geomulticube |
File format support:
| Format | imhypercube/geohypercube | immulticube/geomulticube |
|---|---|---|
| ENVI (.dat, .hdr, .bsq, .bil, .bip) | Yes | No |
| NITF (.ntf) | Yes | No |
| EO-1 Hyperion (.L1R) | Yes | No |
| Landsat/GeoTIFF MTL (.txt) | Yes | Yes |
| Multipage TIFF (.tif) | Yes | Yes |
| TIFF folder (directory of .tif files) | No | Yes |
| ASTER HDF (.hdf) | No | Yes |
| Sentinel-2 (.safe) | No | Yes |
Reading Hyperspectral Data
% WITHOUT geospatial info (returns hypercube object)
hcube = imhypercube(file) % from ENVI, NITF, Hyperion, GeoTIFF, multipage TIFF, Landsat MTL
hcube = imhypercube(file, wavelength) % specify wavelengths
hcube = imhypercube(image, wavelength) % from M-by-N-by-C numeric array
hcube = imhypercube(image, wavelength, metadata) % with metadata struct
hcube = imhypercube(image) % array without wavelengths
hcube = imhypercube(___, BlockSize=blockSize) % control memory via block size
% WITH geospatial info (requires Mapping Toolbox)
hcube = geohypercube(file)
hcube = geohypercube(file, wavelength)
hcube = geohypercube(image, wavelength)
hcube = geohypercube(image, wavelength, metadata) % metadata must have RasterReference field
hcube = geohypercube(image)
hcube = geohypercube(___, BlockSize=blockSize)Reading Multispectral Data
% WITHOUT geospatial info (returns multicube object)
mcube = immulticube(file) % from Landsat MTL .txt, multipage TIFF, ASTER .hdf, Sentinel-2 .safe, or TIFF folder path
mcube = immulticube(file, wavelength)
mcube = immulticube(image, wavelength)
mcube = immulticube(image, wavelength, metadata)
mcube = immulticube(image)
mcube = immulticube(___, BlockSize=blockSize)
% WITH geospatial info (requires Mapping Toolbox)
mcube = geomulticube(file)
mcube = geomulticube(file, wavelength)
mcube = geomulticube(image, wavelength)
mcube = geomulticube(image, wavelength, metadata) % metadata must have RasterReference field
mcube = geomulticube(image)
mcube = geomulticube(___, BlockSize=blockSize)Object Properties
hypercube properties (class: hyper.io.hypercube):
| Property | Description |
|---|---|
ImageDims | Dimensions and data type string, e.g. "[610x340x103 double]" (Since R2025a) |
Wavelength | C-element vector of center wavelengths (nm) |
Metadata | Struct with fields: Height, Width, Bands, DataType, Interleave, HeaderOffset, ByteOrder, WavelengthUnits, AcquisitionTime, RasterReference |
BlockSize | 2-element vector [rows cols] for block processing |
IMPORTANT: There are NO NumRows, NumColumns, NumBands, or DataCube properties. Access dimensions via Metadata.Height, Metadata.Width, Metadata.Bands. The DataCube property was removed in R2025a — use gather(hcube) instead.
multicube properties:
| Property | Description |
|---|---|
ImageFiles | File references |
BandSize | Dimensions of each band |
Wavelength | Center wavelengths per band |
Metadata | Associated metadata struct |
BandResolution | Resolution per band |
BlockSize | 2-element vector [rows cols] |
Writing Data
% Write to ENVI format (.dat + .hdr) — HYPERCUBE ONLY
% Use for hyperspectral data (many narrow bands). NOT for multispectral satellite data (Landsat, Sentinel-2).
% Multispectral satellite data should remain in its native format (GeoTIFF, etc.)
enviwrite(hcube, filename)
enviwrite(hcube, filename, Interleave="bsq") % "bsq" (default), "bil", or "bip"
enviwrite(hcube, filename, DataType="single") % "uint8","uint16","uint32","uint64","int16","int32","int64","single","double"
enviwrite(hcube, filename, ByteOrder="ieee-le") % "ieee-le" or "ieee-be"
enviwrite(hcube, filename, HeaderOffset=0) % bytes before data startReading ENVI Metadata
info = enviinfo(file) % file is .hdr path
% Returns struct with fields:
% Required: Height, Width, Bands, DataType, Interleave, HeaderOffset, ByteOrder
% Optional: Wavelength, FWHM, Gain, Offset, BadBands, BandNames, MapInfo
% File info: Filename, FileModDate, FileSize, Format, RasterFormat
% Supports .hdr, .dat, .bsq, .bil, .bip, .img extensionsGathering Data Into Workspace
% Read full data cube into memory (Since R2025a)
dataCube = gather(hcube) % returns M-by-N-by-C numeric array
dataCube = gather(mcube) % for multicubeROI Selection
% Assign new data to specific locations
newspcube = assignData(spcube, row, column, band, data)
% row, column, band: positive integer scalars or vectors
% data: must match dimensions of indexed region
% Crop region of interest
newspcube = cropData(spcube, row, column) % crop spatial region (all bands)
newspcube = cropData(spcube, row, column, band) % crop spatial + spectral (hypercube only)
% row, column, band: vectors of indices, e.g., 1:100Band Selection, Removal, and Resampling
% Select bands by wavelength range (hypercube only)
newhcube = selectBands(hcube, Wavelength=[minWL maxWL])
% Select bands by index (hypercube and multicube)
newspcube = selectBands(spcube, BandNumber=bands)
% Select bands by resolution (multicube only)
newmcube = selectBands(mcube, DataResolution=resolution)
% Select most informative bands for endmember discrimination (hypercube only)
[newhcube, bandIdx] = selectBands(hcube, endmembers) % endmembers: C-by-K matrix
[newhcube, bandIdx] = selectBands(hcube, endmembers, NumberOfBands=n) % specify count
% Remove bands by wavelength range (hypercube only)
newhcube = removeBands(hcube, Wavelength=[Wmin1 Wmax1; Wmin2 Wmax2]) % K-by-2 matrix
% Remove bands by index (hypercube only)
newhcube = removeBands(hcube, BandNumber=band)
% Resample multicube bands to uniform resolution (Since R2025a)
newmcube = resampleBands(mcube, resolution)
newmcube = resampleBands(mcube, resolution, Method="nearest") % "nearest" (default), "bilinear", or "cubic"Color Transformation
% For hypercube: supports Method parameter, 2 outputs, ContrastStretching defaults to FALSE
coloredImage = colorize(hcube) % default: false-colored (3 most informative bands via selectBands)
coloredImage = colorize(hcube, band) % specify 3 band indices (false color composite)
[coloredImage, indices] = colorize(hcube) % also return selected band indices (2 outputs)
coloredImage = colorize(hcube, Method="rgb") % true color (R:600-700, G:500-600, B:400-500 nm)
coloredImage = colorize(hcube, Method="cir") % color infrared (NIR:760-960, R, G)
coloredImage = colorize(hcube, Method="falsecolored") % default method
coloredImage = colorize(hcube, ContrastStretching=true) % apply CLAHE (default: false)
% For multicube: NO Method parameter, 1 output only, ContrastStretching defaults to TRUE
% WARNING: colorize(mcube, Method="rgb") will ERROR — Method is NOT supported for multicube
coloredImage = colorize(mcube) % TRUE RGB (auto-selects R,G,B bands by wavelength)
coloredImage = colorize(mcube, band) % false color composite from 3 band indices
coloredImage = colorize(mcube, ContrastStretching=false) % disable contrast stretching (default: true)
% KEY DIFFERENCES:
% | Feature | hypercube | multicube |
% |----------------------|-------------------------------|------------------------------------|
% | Default behavior | false-colored (informative) | true RGB (by wavelength) |
% | Method parameter | "rgb","cir","falsecolored" | NOT supported |
% | ContrastStretching | default FALSE (CLAHE) | default TRUE (imadjust) |
% | Number of outputs | [img, indices] | img only |
%
% For multicube RGB: colorize(mcube) already gives RGB! No need to specify band indices.
% For custom band composite: colorize(mcube, [bandR bandG bandB])
% Landsat 4-5 TM bands: Band 3=Red, Band 2=Green, Band 1=Blue
% Landsat 8 OLI bands: Band 4=Red, Band 3=Green, Band 2=BlueBlock Processing (Since R2025a)
% Apply function to each block of a large spectral image
outputCube = apply(spcube, fcn)
outputCube = apply(spcube, fcn, BlockSize=[rows cols])
% fcn: function handle that receives a hypercube/multicube block object
% Use gather(block) inside fcn to get the numeric M-by-N-by-C array
% The function is applied to each spatial block independently
% Enables out-of-memory processing for large datasets
% Example: normalize spectra block-by-block
result = apply(hcube, @(block) gather(block) ./ max(vecnorm(gather(block), 2, 3), eps));Common Workflows
Workflow 1: Load and inspect ENVI file
info = enviinfo("scene.hdr");
hcube = imhypercube("scene.hdr");
disp(hcube.ImageDims)
disp(hcube.Wavelength)
rgb = colorize(hcube, Method="rgb");
imshow(rgb)Workflow 2: Load large file with blocked processing
hcube = imhypercube("large_scene.hdr", BlockSize=[512 512]);
% Process block-by-block without loading entire cube
% fcn receives a hypercube block — use gather(block) to get numeric array
result = apply(hcube, @(block) myProcessingFcn(gather(block)));Workflow 3: Load Sentinel-2 multispectral data
mcube = immulticube("path/to/scene.SAFE/manifest.safe");
% Select specific resolution bands
mcube10m = selectBands(mcube, DataResolution=10);
rgb = colorize(mcube10m); % multicube does not support Method param
imshow(rgb)Workflow 4: Crop and export subset
hcube = imhypercube("scene.hdr");
% Crop spatial ROI and select VNIR bands
cropped = cropData(hcube, 100:500, 200:600, 1:100);
% Remove noisy bands
cropped = removeBands(cropped, Wavelength=[1350 1450; 1800 1950]);
enviwrite(cropped, "subset_scene")Workflow 5: Create hypercube from numeric array
data = rand(256, 256, 224, 'single');
wavelength = linspace(400, 2500, 224);
metadata.WavelengthUnits = "Nanometers";
hcube = imhypercube(data, wavelength, metadata);Workflow 6: Load Landsat data via MTL file and get RGB
% Landsat scenes use MTL text files that reference TIFF band files
mcube = immulticube("LC08_L1TP_MTL.txt");
% Get RGB — colorize(mcube) automatically selects R,G,B bands by wavelength
% NOTE: Do NOT use Method="rgb" — that is hypercube-only and will ERROR on multicube
rgb = colorize(mcube); % true RGB with contrast stretching (default)
imshow(rgb)
% Without contrast stretching:
rgb = colorize(mcube, ContrastStretching=false);
% Custom false-color composite using specific band indices:
% Landsat 8 OLI: Band 4=Red, Band 3=Green, Band 2=Blue
falseColor = colorize(mcube, [5 4 3]); % NIR, Red, Green false colorWorkflow 7: Resample multicube to uniform resolution
% Load multispectral data with mixed resolutions (requires SpacecraftID in metadata)
mcube = immulticube("path/to/scene.SAFE/manifest.safe");
% Resample all bands to 10m resolution
mcube10m = resampleBands(mcube, 10);
% Now all bands have uniform spatial dimensions
dataCube = gather(mcube10m);Supported Formats
| Format | Function | File Extension |
|---|---|---|
| ENVI | imhypercube / geohypercube | .hdr, .dat |
| NITF | imhypercube / geohypercube | .ntf, .nitf |
| GeoTIFF | imhypercube / immulticube | .tif, .tiff |
| Multipage TIFF | imhypercube / immulticube | .tif, .tiff |
| ASTER HDF | immulticube / geomulticube | .hdf |
| Sentinel-2 | immulticube / geomulticube | .safe |
| Landsat (MTL) | immulticube / geomulticube | *_MTL.txt |
| ECOSTRESS (spectral library) | readEcostressSig | .txt (signature files, NOT satellite images) |
| Hyperion | imhypercube | .hdr |
Blocked I/O adapters (ENVI, NITF, ASTER, HDF, TIFF, Sentinel-2, Landsat MTL) are used internally when BlockSize is specified — no user action required beyond setting the parameter.
Key Rules
Use
imhypercube/immulticubefor data without geospatial infoUse
geohypercube/geomulticubewhen geospatial referencing is needed (requires Mapping Toolbox)BlockSizecontrols memory usage — default is [1024 1024]; read-only after creation (must recreate object to change)gatherloads the full cube into memory — use only when RAM allowsapplyenables out-of-memory processing on blocked images; the function handle receives a hypercube/multicube block object — usegather(block)inside to get the numeric array (block is NOT numeric directly)enviwritesupports interleave formats: "bsq" (band sequential), "bil" (band interleaved by line), "bip" (band interleaved by pixel)enviinfoaccepts extensionless files and multiple ENVI extensions (.hdr,.dat,.bsq,.bil,.bip,.img)resampleBandsrequiresSpacecraftIDin metadata — fails on multicubes created from numeric arrays; useselectBands(mcube, DataResolution=res)as alternativeresampleBandssupports interpolation methods:"nearest"(default),"bilinear","cubic"For
geohypercube/geomulticube, theRasterReferencein metadata is automatically updated when usingcropDatacolorizewithContrastStretching=trueapplies adaptive histogram equalization (CLAHE) for enhanced visualization
Multicube Limitations
selectBands: onlyDataResolutionandBandNumber— does NOT supportWavelengthor endmember selectionremoveBands: NOT available for multicube — useselectBands(mcube, BandNumber=...)to keep desired bandscropData: spatial only (row, column) — does NOT accept band parameter; mixed-resolution bands will errorcolorize: does NOT supportMethodparameter ("rgb","cir","falsecolored"will ERROR). Defaultcolorize(mcube)gives true RGB (auto-selects R/G/B by wavelength). Use band indices for custom composites:colorize(mcube, [b1 b2 b3]). ContrastStretching defaults totrue(unlike hypercube which defaults tofalse)enviwrite: NOT available for multicube — ENVI format is for hyperspectral data only; multispectral satellite data (Landsat, Sentinel-2) should remain in native GeoTIFF formatMust unify resolution before spatial operations:
selectBands(mcube, DataResolution=res)orresampleBands
Labeling (Since R2026a)
% Create ground truth object for spectral images
gTruth = groundTruthSpectralImage(dataSource, labelDefs)
gTruth = groundTruthSpectralImage(dataSource, labelDefs, labelData)
gTruth = groundTruthSpectralImage(___, Resolution=resolution)
% dataSource: file path (string) or SpectralImageSource object
% labelDefs: table with REQUIRED columns:
% LabelName (string), LabelColor (1x3 RGB), LabelID (integer),
% LabelGroup (string), Description (string), AttributeList (cell)
% labelData: table with label mask data (optional)
% Properties: DataSource, LabelDefinitions (plural!), LabelData, Resolution
% Select labels by name or group
subGTruth = selectLabelsByName(gTruth, "Vegetation")
subGTruth = selectLabelsByGroup(gTruth, "Land")
% Merge multiple ground truth objects
mergedGTruth = merge(gTruth1, gTruth2)
% Change file paths (for relocating data — takes FOLDER paths, not file paths)
unresolvedPaths = changeFilePaths(gTruth, [oldFolder, newFolder])
% alternateFilePaths: n-by-2 string array of [oldFolder, newFolder] pairsLabeling Example
% Create label definition table (all 6 columns required)
labelDefs = table( ...
["Vegetation";"Soil";"Water"], ...
[0 1 0; 0.6 0.3 0; 0 0 1], ...
[1;2;3], ...
["Land";"Land";"Water"], ...
["Veg areas";"Soil areas";"Water bodies"], ...
{[];[];[]}, ...
VariableNames=["LabelName","LabelColor","LabelID","LabelGroup","Description","AttributeList"]);
hdrFile = which("indian_pines.hdr");
gTruth = groundTruthSpectralImage(hdrFile, labelDefs);
landLabels = selectLabelsByGroup(gTruth, "Land"); % returns 2 labelsCopyright 2026 The MathWorks, Inc.
Requirements and compatibility
Works with: Claude Code, Claude apps, OpenAI Codex, GitHub Copilot, Cursor, Gemini CLI, Kiro, OpenCode, Goose, Amp, Roo Code, JetBrains Junie, Factory Droid, Devin (ex-Windsurf), Mistral Vibe, OpenHands, Letta
“Works with” means the tool reads the open Agent Skills format; a skill written for one tool may use features others lack.
Security
No issues found by our static scan· No issues found
A static scan is not a guarantee. Skills are third-party content: review a skill before you let an agent use it.
Attribution and licence
- Created by
- MathWorks
- Publisher
- MathWorks (Official)
- Source
- matlab/matlab-agentic-toolkit · skills-catalog/image-processing-and-computer-vision/matlab-analyze-spectral-images · commit 2a7f215
- Licence
- BSD 2-Clause License (redistribution allowed)
- LICENSE (added by AutoGineer from LICENSE.md)
- ATTRIBUTION.md (written by AutoGineer)
- Synced
AutoGineer is not affiliated with or endorsed by MathWorks or MathWorks.
Download ZIP
The ZIP holds the skill’s files, its licence files and an ATTRIBUTION.md. Download matlab-analyze-spectral-images.zip