MibImage

class core.MibImage

Bases: matlab.mixin.Copyable

MIBIMAGE - a base image class of MIB3.

Constructor Summary
MibImage(data, meta)

MIBIMAGE - obj = MibImage(data, meta).

Syntax:
obj = MibImage(data, meta)

MibImage class constructor

Creates a new MibImage for raw pixel data. The constructor calls initialize() which derives all dimension properties (height, width, depth, colors, time, dim_yxzct, maxInt, dataClass) from the actual data size.

Input Arguments:
  • data - (optional) 2-D to 5-D numeric array, any class. Accepted input shapes and how they are interpreted:

    • [] or omitted - empty placeholder; obj.exists = false

    • [H, W] - single grayscale slice

    • [H, W, C] - C-channel 2-D image (C < 4); dim 3 is permuted to dim 4 so storage becomes [H,W,1,C]

    • [H, W, C] - 3-D stack when C >= 4 (no permute)

    • [H, W, Z, C] - multi-channel 3-D stack

    • [H, W, Z, C, T] - full 5-D dataset

    Note - the [H,W,C] → [H,W,1,C] permute applies to MibImage only. MibLabels and MibLabels63 store depth in dim 3 and are never permuted.

  • meta - (optional) metadata dictionary from core.MibImage.initializeImgInfo(). Pass [] to use defaults.

Usage:

Example 1 - 1. Grayscale 3-D stack (512×512×10, uint8)

% 1. Grayscale 3-D stack (512×512×10, uint8)
data = uint8(zeros(512, 512, 10));
meta = core.MibImage.initializeImgInfo('pixSize', pixSize);
img  = core.MibImage(data, meta);
% img.depth == 10, img.colors == 1

% 2. RGB 2-D image stored as [H,W,3]  (C < 4 → permuted to [H,W,1,3])
rgb  = uint8(rand(256, 256, 3) * 255);
img  = core.MibImage(rgb);          % meta defaults OK
% img.depth == 1, img.colors == 3

% 3. Empty placeholder (no pixel data yet)
img  = core.MibImage();
% img.exists == false
Property Summary
actionLog

a char with image class, ‘uint8’, ‘uint16’, ‘uint32’;

boundingBox

Cell array of per-operation log strings. Each entry is a timestamped record of a processing step, e.g.:

‘MIB(2601041823): MIB demo dataset, Huh7 SBEM’ ‘MIB(2603131934): ImFilter: Gaussian, HSize:3 3, Sigma:0.6’

Populated from the pipe-separated tail of the ImageDescription tag when a file is loaded. Appended to by model operations via updateActionLog(), which prepends the timestamp automatically:

img.updateActionLog(‘ImFilter: Gaussian, HSize:3 3, Sigma:0.6’);

MibDataset.actionLog is a Dependent property that forwards here.

colorType

colormap for indexed images

colormap

number of color channels

colors
customMeta

a structure with viewing parameters:

  • .min - a vector with minimal value for intensity stretching for each color channel

  • .max - a vector with maximal value for intensity stretching for each color channel

  • .gamma - a vector with gamma factor for contrast adjustment for each color channel

data

image height, px

dataClass

numeric array [height × width × depth × colors × time] holding the pixel data. Note: The ‘Image’ layer dimensions: [1:height, 1:width, 1:depth, 1:colors, 1:time]

depth

grayscale, multichannel, hsvcolor, indexed

Type:

a char with type of colors

dim_yxzct

number of stacks in the dataset

exists

a matrix with dimensions of the dataset [height, width, depth, colors, time] equal to size obj.data

filename

logical switch indicating whether the obj.data exists or it is empty/dummy place maker

height

the full filename of the dataset

lutColors

Physical voxel dimensions. A struct with fields:

  • .x - physical width of a pixel in .units

  • .y - physical height of a pixel in .units

  • .z - physical thickness of a slice in .units

  • .t - time between frames (for movies)

  • .units - spatial units: ‘m’ | ‘cm’ | ‘mm’ | ‘um’ | ‘nm’

  • .tunits - time units string

IMPORTANT - always write via MibDataset.setPixSize():

ds.setPixSize(newPixSize) % updates image + labels + mask + selection

Read directly from the layer that owns the data:

pixSize = ds.image.pixSize; % the authoritative copy

maskFilename

colorChannel, R G B], (0-1)

Type:

a matrix with LUT colors [1

maxInt

default filename for the mask, when MibLabels63 is used both mask and model are within the same class, thus additional property is needed

pixSize

Physical extent of the dataset as [xmin xmax ymin ymax zmin zmax] in the units stored in pixSize.units (default: µm). Populated from the ‘BoundingBox’ prefix of the ImageDescription tag when a file is loaded; falls back to a default computed from the image dimensions × voxel size when no BoundingBox tag is present.

pyramid

maximal value that is available in the dataset

sliceName

a structure with specifications of the image pyramid downsampling levels, order of dimensions as in MIB pyramid = struct(); % structure to keep pyramid organization of data, convert axes to MIB order pyramid.levelNames = meta.levelNames; pyramid.levelImageSizes = meta.levelImageSizes(:, [2, 3, 1]); pyramid.levelImageTranslations = meta.levelImageTranslations(:, [2, 3, 1]); pyramid.levelScaleFactors = meta.levelScaleFactors(:, [2, 3, 1]); pyramid.levelVoxelSizes = meta.levelVoxelSizes(:, [2, 3, 1]); pyramid.chunkSizes = meta.chunkSizes(:, [4, 5, 2, 3, 1]); pyramid.shardSizes = meta.shardSizes(:, [4, 5, 2, 3, 1]);

sliceSize

a cell array of slice filenames that composing the dataset

time

an [N×2] double matrix of original [height, width] per slice; empty [] when all slices share the same size

type

number of time points in the dataset

viewPort

image width, px

width

image (MibImage), labels (MibLabels), labels63 (MibLabels63), virtual (MibVirtualImage)

Type:

type of the dataset

Method Summary
addColorChannel(img, channelId, lutColors, options)

ADDCOLORCHANNEL - Add or replace a color channel in the existing dataset.

Syntax:
output = obj.addColorChannel(img, channelId, lutColors, options)
Input Arguments:
  • img - image stack [height, width, depth, colors, time] to add/replace

  • channelId - (optional) 1-based channel index to replace; NaN (default) - append img as new color channel(s)

  • lutColors - (optional) matrix [nNewChannels x 3] with LUT colors in the range 0-1. Pass NaN (default) to auto-assign random colors.

  • options - (optional) struct with fields:

    • .ParentFigure - handle to parent figure for dialogs (default [])

    • .showWaitbar - logical; show progress bar (default true)

Output Arguments:
  • output - 1 - success; 0 - cancelled or failed

Usage:

Example 1

obj.image.addColorChannel(img, NaN, lutColors, opts);

Example 2

obj.image.addColorChannel(img, 2);    % replace channel 2
buildImageDescription(bb, actionLog)

BUILDIMAGEDESCRIPTION - Reconstruct a full ImageDescription string from a bounding box vector and an action log cell array.

Syntax:
str = buildImageDescription(bb, actionLog)

This is the inverse of core.MibImage.splitImageDescription. It produces the canonical string written into the ImageDescription tag of TIFF files and equivalent metadata fields in other formats (HDF5, NRRD, AmiraMesh…).

FORMAT The reconstructed string has the form:

‘BoundingBox x1 x2 y1 y2 z1 z2|LogEntry1|LogEntry2|…’

where the six floating-point numbers are the physical extents of the dataset in the order [xmin xmax ymin ymax zmin zmax] (units: µm by default, matching MibDataset.pixSize.units).

When actionLog is empty, no pipe or log entries are appended. When bb is empty or invalid, the BoundingBox prefix is omitted and the result contains only the joined log entries (or ‘’ if both are empty).

Input Arguments:
  • bb - (1×6 double) bounding box [xmin xmax ymin ymax zmin zmax]. Pass [] to omit the BoundingBox prefix.

  • actionLog - (1×N cell of char) per-operation log strings. Pass {} or [] to produce a string with no log section.

Output Arguments:
  • str - (char) the reconstructed ImageDescription string, ready to be written to a file or stored in a metadata struct.

Usage:

Example 1 - Full round-trip: split then rebuild

raw = ['BoundingBox 0.000000 6.760000 0.000000 4.823000 0.000000 2.220000 ' ...
       '|MIB(2601041823): MIB demo dataset, Huh7 SBEM' ...
       '|MIB(2603131934): ImFilter: Gaussian, HSize:3  3, Sigma: 0.6'];

[imgDesc, log] = core.MibImage.splitImageDescription(raw);
bb = sscanf(imgDesc, 'BoundingBox %f %f %f %f %f %f')';

rebuilt = core.MibImage.buildImageDescription(bb, log);
% rebuilt -> 'BoundingBox 0.000000 6.760000 0.000000 4.823000 0.000000 2.220000 |MIB...'

Example 2 - From a MibImage object in MibImage.save()

metadata.imageDescription = core.MibImage.buildImageDescription( ...
    obj.boundingBox, obj.actionLog);
metadata.boundingBox = obj.boundingBox;

Example 3 - Mask save in MibDataset.saveImage()

metadata.imageDescription = core.MibImage.buildImageDescription( ...
    obj.image.boundingBox, obj.image.actionLog);

Example 4 - BoundingBox only, no log

bb  = [0, 511.5, 0, 511.5, 0, 49.5];
str = core.MibImage.buildImageDescription(bb, {});
% str -> 'BoundingBox 0.000000 511.500000 0.000000 511.500000 0.000000 49.500000'

Example 5 - Log only, no spatial calibration

str = core.MibImage.buildImageDescription([], {'ImageJ=1.52p', 'unit=um'});
% str -> 'ImageJ=1.52p|unit=um'

Example 6 - Append a new log entry to a MibImage in-place

img.updateActionLog('ImFilter: Median, HSize:3 3, Orient:4');
% The timestamp is added automatically; the next call to img.save()
% will include the new entry automatically.

See also

core.MibImage.splitImageDescription, core.MibImage.save, core.MibDataset.saveImage

clearLayer(layerName, y, x, z, t, magFactor)

CLEARLAYER - Clear the layer using numeric coordinate ranges.

Syntax:
obj.clearLayer(layerName, y, x, z, t)

String mode resolution (‘2D’, ‘3D’, ‘4D’) and block-mode coordinate clamping are handled upstream in MibDataset.clearLayer, which has access to obj.slices and obj.orientation. This function only accepts numeric coordinate ranges or [] for full extent.

Input Arguments:
  • layerName - char with the target layer name; default 'selection':

    • 'selection' - clear the selection layer

    • 'mask' - clear the mask layer

    • 'labels' - clear the labels layer

    • 'everything' - clear selection, mask, and labels layers (core.MibLabels63 only)

    • 'image' - clear the image layer

  • y - (optional) numeric [minY, maxY] or [] for full height extent

  • x - (optional) numeric [minX, maxX] or [] for full width extent

  • z - (optional) numeric [minZ, maxZ] or [] for full depth extent

  • t - (optional) numeric [minT, maxT] or [] for full time extent

  • blockModeSwitch - (optional) unused; block mode is resolved in MibDataset.clearLayer

Output Arguments:

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.selection.clearLayer();% call from mibController, clear the Selection layer completely

Example 2

obj.mibModel.I{obj.mibModel.id}.selection.clearLayer([], 1:imageData.y, 1:imageData.x, 1:3);% call from mibController, clear the Selection layer only in 3 first slices
convertImage(format, options)

CONVERTIMAGE - Convert pixel data to a new color type or bit depth.

Syntax:
status = obj.convertImage(format, options)

Converts the image in obj.data to the requested color type or bit depth. All color-space paths from MIB2 are preserved. The data array has layout [H, W, Z, C, T].

Input Arguments:
  • format - char, target format:

    • 'grayscale' - single channel

    • 'multichannel' - 2-or-3-channel RGB

    • 'hsvcolor' - 3 channels HSV

    • 'indexed' - indexed color; colormap stored in obj.colormap

    • 'uint8' - cast to 8-bit [0 - 255]

    • 'uint16' - cast to 16-bit [0 - 65535]

    • 'uint32' - cast to 32-bit [0 - 4294967295]

  • options - (optional) struct with fields:

    • .showWaitbar - logical, show or not the progress dialog; default true

    • .parentFigure - matlab.ui.Figure, parent for dialogs; pass [] when unavailable

    • .selectedColorChannels - vector of color indices used for LUT blending when converting multichannel (>3 ch) to grayscale or indexed; default 1:obj.colors

Output Arguments:
  • status - 1 on success, 0 on failure or user cancel

Example 1 - convert to grayscale

opt.parentFigure = obj.mibGUI;
status = img.convertImage('grayscale', opt);

Example 2 - cast to 8-bit using current viewport stretch

opt.showWaitbar = false;
status = img.convertImage('uint8', opt);
copyColorChannel(channel1, channel2, options)

COPYCOLORCHANNEL - Copy channel1 intensity to channel2 position.

Syntax:
obj.copyColorChannel(channel1, channel2, options)

If channel2 > obj.colors a new channel is appended; otherwise the existing channel is overwritten.

Input Arguments:
  • channel1 - 1-based index of the source channel

  • channel2 - 1-based index of the destination channel; pass obj.colors + 1 to append as a new channel

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - copy channel 1 intensities to channel 3

obj.image.copyColorChannel(1, 3);
copySlice(sliceFrom, sliceTo, orient)

COPYSLICE - Copy specified slice(s) from one position to another within the same array.

Syntax:
result = obj.copySlice(sliceFrom, sliceTo, orient)

Pure data-manipulation layer: operates only on obj.data. No dialogs, no waitbars, no annotation handling. Caller (core.MibDataset.copySlice) is responsible for auxiliary-layer operations and action-log updates.

Input Arguments:
  • sliceFrom - index or index vector of source slices

  • sliceTo - index or index vector of destination slices; must be the same length as sliceFrom

  • orient - (optional) dimension to operate on: 1 = height (y), 2 = width (x), 3 = depth (z, default), 5 = time (t)

Output Arguments:
  • result - 1 on success, 0 on failure

Usage:

Example 1

result = obj.image.copySlice(3, 10);  % copy z-slice 3 to z-slice 10

Example 2

result = obj.image.copySlice(3, 10, 5);  % copy time-frame 3 to frame 10
crop(cropF)

CROP - Crop obj.data in-place and update all scalar dimension properties.

Syntax:
obj.crop(cropF)

Crops the stored 5-D array along X, Y, Z and T according to the supplied crop parameters. Scalar dimension properties (height, width, depth, time, dim_yxzct) and the sliceName list are updated to reflect the new extents. The bounding box and pixSize are not updated here - the caller (core.MibDataset.cropDataset) is responsible for that.

Because core.MibLabels and core.MibLabels63 both inherit from core.MibImage and share the same [h, w, d, c, t] layout for their data{1} array (with c = 1 for label layers), this method works unchanged for all layer types.

Input Arguments:
  • cropF - a vector [x1, y1, dx, dy, z1, dz, t1, dt] in pixels where x1, y1 are the top-left corner, dx, dy are width and height of the crop region, z1, dz are the first slice and depth, and t1, dt are the first frame and number of frames.

Usage:

Example 1

obj.mibModel.I{obj.mibModel.id}.image.crop([10 20 100 200 1 5 1 1]);% call from controller; crop to x=10..109, y=20..219, z=1..5, t=1

Example 2

obj.mibModel.I{obj.mibModel.id}.labels.crop(cropF);% crop the labels layer with the same cropF vector
deleteColorChannel(channel1, options)

DELETECOLORCHANNEL - Delete one or more color channels from obj.data.

Syntax:
obj.deleteColorChannel(channel1, options)
Input Arguments:
  • channel1 - vector of 1-based channel indices to delete

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - delete channel 3

obj.image.deleteColorChannel(3);
deleteSlice(sliceNumbers, orient)

DELETESLICE - Delete specified slice(s) from the image array.

Syntax:
result = obj.deleteSlice(sliceNumbers, orient)

Pure data-manipulation layer: removes indexed slices from obj.data and updates obj.height, obj.width, obj.depth, obj.time, obj.dim_yxzct, and obj.sliceName (for depth operations). No dialogs, no waitbars. Annotation bookkeeping and view-range updates are handled by the caller (core.MibDataset.deleteSlice).

Input Arguments:
  • sliceNumbers - index or index vector of slices to delete

  • orient - dimension to operate on: 1 = height (y), 2 = width (x), 3 = depth (z), 5 = time (t)

Output Arguments:
  • result - 1 on success, 0 on failure

Usage:

Example 1

result = obj.image.deleteSlice(5, 3);  % delete z-slice 5

Example 2

result = obj.image.deleteSlice([2, 5, 8], 3);  % delete z-slices 2, 5, and 8

Example 3

result = obj.image.deleteSlice(1, 5);  % delete time-frame 1
getData(layerType, orient, colChannel, options)

get complete 5D dataset GETDATA - Get dataset from MibImage class.

Syntax:
dataset = obj.getData(layerType, orient, colChannel, options) % get complete 5D dataset
Input Arguments:
  • layerType - char with the type of layer to obtain, used for MibLabels63 class, otherwise can be empty. Values are ‘labels’, ‘mask’, ‘selection’, or ‘everything’ to get all layers at once, default = ‘image’

  • orient - (optional), can be []; when [] orient defaults to 3:

    • 1 - returns transposed dataset in ZX configuration: [y,x,z,c,t] → [z,x,y,c,t] (rows = Z, columns = X, so X stays horizontal as in the YX view)

    • 2 - returns transposed dataset in ZY configuration: [y,x,z,c,t] → [y,z,x,c,t]

    • 3 - returns original dataset in YX configuration: [y,x,z,c,t]

  • colChannel - (optional), can be []; when [] returns all color channels or materials:

    • for type = 'image': vector of color channel indices; [] = all channels

    • for type = 'labels': integer material index (returned as binary 0/1); [] = all materials

  • options - (optional), a structure with extra parameters

    • .y (optional), [ymin, ymax] coordinates of the dataset to take after transpose, can be a single number

    • .x (optional), [xmin, xmax] coordinates of the dataset to take after transpose, can be a single number

    • .z (optional), [zmin, zmax] coordinates of the dataset to take after transpose, can be a single number

    • .t (optional), [tmin, tmax] coordinates of the dataset to take after transpose, can be a single number

Output Arguments:
  • dataset - 5D stack, [1:height, 1:width, 1:depth, 1:colors, 1:time]

Usage:

Example 1

dataset = obj.getData(3, []);% get the complete dataset in the YX orientation

Example 2

options.x = [100 200];
options.y = [100 200];
options.z = 100;
options.t = 1;
colChannel = 2;
dataset = obj.getData([], [], colChannel, options);% get subvolume = [100:200, 100:200] at slice 100, color channel 2
dataset = obj.(type).getData([], [], colChannel, options);% get subvolume from MibDataset, where type='image', 'label', 'mask', 'selection'
dataset = obj.mibModel.I{obj.mibModel.id}.(type).getData([], [], colChannel, options);% get subvolume from MibController, where type='image', 'label', 'mask', 'selection'
getDatasetDimensions(orient, splitDims, blockModeSwitch)

GETDATASETDIMENSIONS - Get dimensions of the dataset as [height, width, depth, colors, time] or a combined vector.

Syntax:
varargout = obj.getDatasetDimensions(orient, splitDims, blockModeSwitch)
Input Arguments:
  • orient - (optional), can be []; default 3:

    • 1 - returns dimensions in ZX configuration: [y,x,z,c,t] → [z,x,y,c,t]

    • 2 - returns dimensions in ZY configuration: [y,x,z,c,t] → [y,z,x,c,t]

    • 3 - returns dimensions of the original YX dataset: [y,x,z,c,t]

  • splitDims - (optional) logical; default true:

    • true - return individual outputs: height, width, depth, colors, time

    • false - return a single array [height, width, depth, colors, time]

  • blockModeSwitch - (optional) logical; default false. Must be false: an image does not know which part of itself is on screen, since the shown block is MibDataset.slices. Passing true raises MibImage:getDatasetDimensions:blockModeUnsupported; use core.MibDataset.getDatasetDimensions() for block-mode dimensions.

Output Arguments:
  • when splitDims = true: [height, width, depth, colors, time] as separate outputs

  • when splitDims = false: single numeric array [height, width, depth, colors, time]

Usage:

Example 1

[height, width, depth, colors, time] = obj.getDatasetDimensions();

Example 2

dims = obj.getDatasetDimensions(3, false);   % dims = [height, width, depth, colors, time]
getDefaultViewPort()

GETDEFAULTVIEWPORT - Get default viewport for image intensity stretching and visualization.

Syntax:
viewPort = obj.getDefaultViewPort()

Returns a viewport structure with default intensity stretching parameters for each color channel. For standard data types, min/max are initialized to 0 and obj.maxInt. For uint32 images, actual data min/max are computed from the first slice.

Input Arguments:

(none)

Output Arguments:
  • viewPort - [struct] viewport with fields:

    • .min - [numeric] minimum intensity value per channel [colors × 1]

    • .max - [numeric] maximum intensity value per channel [colors × 1]

    • .gamma - [numeric] gamma correction factor per channel [colors × 1] (default: 1.0)

Example - Get and display default viewport:

vp = img.getDefaultViewPort();
disp(vp.min);    % minimum intensity per channel
disp(vp.max);    % maximum intensity per channel
disp(vp.gamma);  % gamma factors per channel
getImAdjustStretchCoef(channels)

GETIMADJUSTSTRETCHCOEF - Return image stretching coefficients to be used for imadjust function to.

Syntax:
[lowIn, highIn, lowOut, highOut] = obj.getImAdjustStretchCoef(channels)

stretch contrast of the image

Input Arguments:
  • channels - (optional) color channel or vector of color channels to get coefficients; when skipped return coefficients for all color channels

Output Arguments:
  • lowIn - values matching low_in parameter of imadjust

  • highIn - values matching high_in parameter of imadjust

  • lowOut - values matching low_out parameter of imadjust

  • highOut - values matching high_in parameter of imadjust

Usage:

Example 1

[lowIn, highIn, lowOut, highOut] = obj.mibModel.I{obj.mibModel.id}.getImAdjustStretchCoef(channel);% call from mibController; get coefficients
getMeta()

GETMETA - Collect MibImage properties into a metadata dictionary.

Syntax:
meta = obj.getMeta()

Builds a dictionary matching the schema of MibImage.initializeImgInfo() from the current state of the object’s properties. This is the inverse of initialize() - it packs the scattered properties back into the canonical dictionary format used throughout MIB3 for metadata transport.

Input Arguments:

Output Arguments:
  • meta - dictionary with all standard MibImage metadata fields

Usage:

Example 1

meta = obj.mibModel.I{obj.mibModel.id}.image.getMeta();% get metadata dictionary
getPixelIdxList(type, PixelIdxList)

GETPIXELIDXLIST - Get pixel values at a list of linear indices from MibImage or a subclass.

Syntax:
dataset = obj.getPixelIdxList(type, PixelIdxList)

For standard MibImage and MibLabels the raw data are read directly from obj.data. For MibLabels63 (bit-packed) the values are unpacked according to the layer type: - ‘labels’ - lower 6 bits (bitand with 63) - ‘mask’ - bit 7 (bitget position 7) - ‘selection’ - bit 8 (bitget position 8) - ‘everything’- raw byte (no unpacking)

Input Arguments:
  • type - char, layer type to read:

    • 'image' - pixel values from an image layer (MibImage)

    • 'labels' - material indices from labels layer

    • 'mask' - mask layer values (0/1)

    • 'selection' - selection layer values (0/1)

    • 'everything' - raw packed byte (MibLabels63 only)

  • PixelIdxList - numeric vector of linear pixel indices into obj.data in the XY orientation (standard MATLAB column-major order)

Output Arguments:
  • dataset - numeric column vector of values at the requested indices; [] when the layer does not exist (e.g. modelExist == 0)

Usage:

Example 1

CC = bwconncomp(mask3D, 26);
vals = obj.labels.getPixelIdxList('selection', CC.PixelIdxList{1});

Example 2 - Reading from the image layer

% Reading from the image layer:
pixVals = obj.image.getPixelIdxList('image', idx);
initialize(data, meta)

INITIALIZE - initialize the class using default or provided values.

Syntax:
obj.initialize(data, meta)
Input Arguments:
  • data - matrix with the image to initialize the class, can be empty

  • meta - a dictionary with default settings for the class, can be empty; the following fields are used, .filename full path to the dataset .SliceName cell array with slice names, can be empty .lutColors matrix with LUT colors to use (colChannel, R G B) in range 0-1 .pixSize structure with

    • .x - physical width of a pixel

    • .y - physical height of a pixel

    • .z - physical thickness of a pixel

    • .t - time between the frames for 2D movies

    • .tunits - time units

    • .units - physical units for x, y, z. Possible values: [m, cm, mm, um, nm] .viewPort structure with viewing parameters:

    • .min - a vector with minimal value for intensity stretching for each color channel

    • .max - a vector with maximal value for intensity stretching for each color channel

    • .gamma a vector with gamma factor for contrast adjustment for each color channel

initializeImgInfo(varargin)

INITIALIZEIMGINFO - Create the standard MibImage metadata dictionary, optionally overriding defaults via Name-Value pairs.

Syntax:
imginfo = initializeImgInfo(varargin)

This is the CANONICAL factory for the imginfo dictionary used throughout MIB3 to carry image metadata between loaders, core data classes, and savers. Ownership of the schema lives here because MibImage is the class that ultimately consumes every field. All other components - loaders, MibDataset, savers - must call this method rather than constructing the dictionary by hand. This guarantees that every key is always present with a well-defined default, regardless of which component creates the dict.

IMAGEDESCRPTION / ACTIONLOG SPLIT The full ImageDescription string stored in TIFF and other formats has the structure:

‘BoundingBox x1 x2 y1 y2 z1 z2|LogEntry1|LogEntry2|…’

MIB3 stores the two parts separately inside the dictionary: - “ImageDescription” BoundingBox string only (before first ‘|’) - “ActionLog” cell array of log entries (after first ‘|’)

When a loader reads the raw combined string from a file it should call core.MibImage.splitImageDescription() and pass the two parts as separate Name-Value pairs to this function.

Input Arguments:
  • varargin - optional Name-Value pairs overriding any subset of the default keys. Unrecognised keys are stored in the dictionary unchanged, allowing format-specific metadata (e.g. TIFF tags) to be carried through without special-casing.

    Supported keys (with defaults):

    • 'Filename' - (char) full path to the source file; default 'none.tif'

    • 'Height' - (double) image height in pixels; default 512

    • 'Width' - (double) image width in pixels; default 512

    • 'Colors' - (double) number of colour channels; default 1

    • 'Colormap' - (double[]) colormap for indexed images; default []

    • 'Depth' - (double) number of z-slices; default 1

    • 'Time' - (double) number of time points; default 1

    • 'imgClass' - (char) MATLAB image class; default 'uint8'

    • 'ColorType' - (char) 'grayscale' | 'multichannel' | 'hsvcolor' | 'indexed'; default 'grayscale'

    • 'ImageDescription' - (char) BoundingBox string (part before the first '|'); default ''

    • 'ActionLog' - (cell) per-operation log entries (parts after the first '|'); default {}

    • 'MaxInt' - (double) maximum representable intensity; default 255

    • 'SliceName' - (cell) per-slice source filenames; default {}

    • 'SliceSize' - (double[N×2]) per-slice original [height, width] as rows; default []

    • 'pixSize' - (struct) voxel/time-step sizes from utils.defaults.initializePixSize():

      • .x - pixel width [µm]; default 1

      • .y - pixel height [µm]; default 1

      • .z - slice thickness [µm]; default 1

      • .t - time step [s]; default 1

      • .units - spatial units; default 'um'

      • .tunits - time units; default 's'

    • 'viewPort' - (struct) display stretch parameters:

      • .min - default 0

      • .max - default 255

      • .gamma - default 1

    • 'lutColors' - (double Nx3) LUT colours, values 0..1, one row per colour channel

Output Arguments:
  • imginfo - dictionary with all standard MibImage metadata fields. Caller-supplied Name-Value pairs override the defaults.

Usage:

Example 1 - Empty dictionary with all defaults

imginfo = core.MibImage.initializeImgInfo();

Example 2 - Provide filename and physical voxel size only

pixSz = struct('x',0.013,'y',0.013,'z',0.025,'t',1,'units','um','tunits','s');
imginfo = core.MibImage.initializeImgInfo( ...
    'Filename', '/data/em_volume.tif', ...
    'pixSize',  pixSz);

Example 3 - Loader workflow: split the raw ImageDescription tag first

rawDesc = 'BoundingBox 0 511.5 0 511.5 0 49.5|MIB(2601041823): opened|MIB(2603131934): filtered';
[imgDesc, actionLog] = core.MibImage.splitImageDescription(rawDesc);

imginfo = core.MibImage.initializeImgInfo( ...
    'Filename',         '/data/stack.tif', ...
    'ImageDescription', imgDesc, ...
    'ActionLog',        actionLog, ...
    'pixSize',          struct('x',0.013,'y',0.013,'z',0.025, ...
                              't',1,'units','um','tunits','s'));

Example 4 - Full dimension metadata (useful in custom loaders)

imginfo = core.MibImage.initializeImgInfo( ...
    'Filename',   '/data/multichannel.tif', ...
    'Height',     1024, ...
    'Width',      1024, ...
    'Depth',      50,   ...
    'Colors',     3,    ...
    'ColorType',  'multichannel', ...
    'imgClass',   'uint16', ...
    'MaxInt',     65535);

Example 5 - Add a format-specific tag (stored as-is, no error)

imginfo = core.MibImage.initializeImgInfo( ...
    'Filename',          '/data/scan.tif', ...
    'TiffBitsPerSample', 16);

See also

core.MibImage.splitImageDescription, core.MibImage.buildImageDescription, utils.defaults.initializePixSize, core.MibDataset.initialize, core.MibImage.initialize

insertEmptyColorChannel(channel1, options)

INSERTEMPTYCOLORCHANNEL - Insert a zero-filled color channel at the given position.

Syntax:
obj.insertEmptyColorChannel(channel1, options)
Input Arguments:
  • channel1 - 1-based index of the position to insert the new channel. Use obj.colors + 1 to append at the end.

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - insert empty channel before channel 2

obj.image.insertEmptyColorChannel(2, struct('showWaitbar', false));
insertSlice(img, insertPosition, dim, options)

INSERTSLICE - Low-level insert of img into obj.data along the depth (z) or time (t) dimension.

Syntax:
obj.insertSlice(img, insertPosition, dim, options)

This is the pure data-manipulation layer: no dialogs, no waitbars, no annotation handling. All validation and user interaction is done by the caller (core.MibDataset.insertSlice).

Input Arguments:
  • img - 5D array [height, width, depth, colors, time] to insert; must already be the correct class. Use the same conventions as obj.data.

  • insertPosition - 1-based insertion index (already clamped to a valid range by the caller). 0 or NaN means append to the end.

  • dim - ‘depth’ (default) inserts along dimension 3 (z); ‘time’ inserts along dimension 5 (t)

  • options - (optional) struct with fields:

    • .BackgroundColorIntensity - scalar fill value for dimension mismatches (default 0)

    • .sliceNames - cell array of names for the inserted depth slices (default {})

    • .sliceSizes - [N×2] double matrix of [height, width] for the inserted slices (default [])

Output Arguments:

none

After the call the following properties are updated: obj.data, obj.height, obj.width, obj.depth, obj.colors, obj.time, obj.dim_yxzct, obj.sliceName, obj.sliceSize (when applicable)

Usage:

Example 1

obj.image.insertSlice(img5D, 5, 'depth');

Example 2

obj.labels.insertSlice(zeros([H W D 1 T],'uint8'), 5, 'depth');

Example 3

opts.BackgroundColorIntensity = 255; opts.sliceNames = {'slice1','slice2'};

Example 4

obj.image.insertSlice(img5D, 5, 'depth', opts);
invertColorChannel(channel1, options)

INVERTCOLORCHANNEL - Invert pixel values in one or more color channels.

Syntax:
obj.invertColorChannel(channel1)
obj.invertColorChannel(channel1, options)

Each pixel value v is replaced by maxInt - v. Operates directly on obj.data (no ROI support; use MibModel.invertImage for ROI-aware 2D inversion).

Input Arguments:
  • channel1 - channel index (scalar), vector of indices, or 0 = all channels

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

    • .tRange - [t1, t2] time-point range; default = all time points

    • .zRange - [z1, z2] z-slice range (physical Z, dim 3 of data{1}); default = all z-slices

Usage:

Example 1 - invert channel 2 across the full dataset

obj.image.invertColorChannel(2);

Example 2 - invert channels 1 and 3, time points 2-4 only

opts.tRange = [2, 4];
obj.image.invertColorChannel([1, 3], opts);

Example 3 - invert all channels

obj.image.invertColorChannel(0);
replaceMaskedArea(maskVolume, colorValues, colorChannels, options)

REPLACEMASKEDAREA - Replace pixels where maskVolume==1 with colorValues directly in obj.data.

Syntax:
obj.replaceMaskedArea(maskVolume, colorValues, colorChannels, options)

Modifies obj.data in-place for the z-slice range and time point given in options. Called per time point by MibModel.replaceMaskedArea.

Input Arguments:
  • maskVolume - [numeric | logical] [h, w, numZ] binary mask for one time point; numZ must equal options.zRange(2) - options.zRange(1) + 1

  • colorValues - [numeric] scalar or vector with one replacement intensity per entry in colorChannels; a scalar is broadcast to every channel

  • colorChannels - [numeric] vector of 1-based channel indices to modify

  • options - (optional) struct with fields:

    • .zRange - [z1, z2] indices into obj.data (default = all z)

    • .timePoint - scalar time index into obj.data (default = 1)

Output Arguments:

(none) - modifies obj.data in place

Usage:

Example 1 - set all channels to black inside the mask for time point 3, z 10-20

opts.zRange    = [10, 20];
opts.timePoint = 3;
obj.image.replaceMaskedArea(maskVol, 0, 1:obj.image.colors, opts);
resliceDataset(sliceNumbers, orient)

RESLICEDATASET - Keep only the specified slice(s), removing all others.

Syntax:
result = obj.resliceDataset(sliceNumbers, orient)

Pure data-manipulation layer: retains indexed slices in obj.data and updates obj.height, obj.width, obj.depth, obj.time, obj.dim_yxzct, and obj.sliceName (for depth operations). No dialogs, no waitbars. View-range and bounding-box updates are handled by the caller (core.MibDataset.resliceDataset).

Input Arguments:
  • sliceNumbers - index or index vector of slices to keep; all other slices are removed

  • orient - dimension to operate on: 1 = height (y), 2 = width (x), 3 = depth (z), 5 = time (t)

Output Arguments:
  • result - 1 on success, 0 on failure

Usage:

Example 1

result = obj.image.resliceDataset(1:2:50, 3);  % keep every other z-slice

Example 2

result = obj.image.resliceDataset([1, 5, 10, 20], 3);  % keep 4 specific slices
rotateColorChannel(channel1, angle, options)

ROTATECOLORCHANNEL - Rotate a color channel by 90, 180, or -90 degrees.

Syntax:
obj.rotateColorChannel(channel1, angle, options)

Only square images are supported (obj.width == obj.height).

Input Arguments:
  • channel1 - 1-based index of the channel to rotate

  • angle - rotation angle in degrees; must be a multiple of 90

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - rotate channel 1 by 90 degrees

obj.image.rotateColorChannel(1, 90);
save(filename, options)

SAVE - Save image data from a MibImage object to a file.

Syntax:
fnOut = obj.save(filename, options)

This is the LOWEST-LEVEL save entry point. It works completely standalone: no MibDataset or MibModel is required. Useful for scripted pipelines that create or modify a MibImage object directly without loading it through the full MIB application.

The method:

  1. Derives the output format from options.Format (or from the file extension if options.Format is absent)

  2. Assembles a metadata struct from the object’s own properties

  3. Calls io.SaverFactory.create(format) to get the right saver

  4. Delegates the actual I/O to saver.save(data, metadata, filename, options)

NOTE ON pixSize: MibImage does NOT store pixel/voxel size - that information lives at the MibDataset level. If you need physically correct metadata in the output file (e.g. for Amira, NRRD, or OME-TIFF), supply options.pixSize explicitly: opts.pixSize = struct(‘x’,0.065,’y’,0.065,’z’,0.2,’units’,’um’,’t’,1,’tunits’,’s’); When options.pixSize is absent a default of 1×1×1 µm is used.

Input Arguments:
  • obj - MibImage instance

  • filename - (char) full output path including extension, e.g. '/data/out/myStack.tif' or 'C:\data\output.h5'. The directory must already exist. When filename has no path component the current directory is used.

  • options - (optional) struct with saving options:

    • .Format - (char) format descriptor as listed in io.SaverFactory.getFormats('image'), e.g. 'TIF format uncompressed (*.tif)'. When absent the format is inferred from the file extension.

    • .Saving3DPolicy - (char) '3D stack' | '2D sequence', default '3D stack'

    • .showWaitbar - (logical) display progress bar, default true

    • .silent - (logical) suppress all dialogs, default false

    • .overwrite - (logical) silently overwrite existing files, default true

    • .Compression - (char) 'none' | 'lzw' | 'packbits' (for TIF); 'lossy' | 'lossless' (for JPG)

    • .Quality - (double 0-100) JPEG quality, default 90

    • .FilenameGenerator - (char) 'Use original filename' | 'Use sequential filename'

    • .pixSize - (struct) voxel size {.x .y .z .t .units .tunits}; injected by MibDataset.save() automatically when calling through that layer

    • .ParentFigure - handle to the main MIB application window; passed to io.SaverFactory.create() so the saver and any helper functions can create uiprogressdlg dialogs properly parented to the GUI. Injected by MibModel.saveImage(); omit for standalone use.

    • .mibPath - (char) path to MIB installation directory; forwarded to the saver for resource/icon lookup. Injected by MibModel.saveImage(); omit for standalone use.

Output Arguments:
  • fnOut - (char or cell of char) path(s) of saved file(s). Returns [] on failure or cancellation.

Usage:

Example 1 - Simplest case: save existing MibImage to TIF

img = core.MibImage(uint8(rand(256,256,50,1,1)*255));
img.filename = '/data/input.tif';

% get the list of possible formats for images: "formats = io.SaverFactory.getFormats('image')"
opts.Format         = 'TIF format uncompressed (*.tif)';
opts.Saving3DPolicy = '3D stack';
opts.showWaitbar    = false;
opts.silent         = true;
opts.overwrite      = true;
opts.pixSize        = struct('x',0.065,'y',0.065,'z',0.2,'units','um','t',1,'tunits','s');

fnOut = img.save('/output/stack.tif', opts);
fprintf('Saved to: %s\n', fnOut);

Example 2 - Save as LZW-compressed TIF, 2D sequence

opts.Format            = 'TIF format LZW compression (*.tif)';
opts.Saving3DPolicy    = '2D sequence';
opts.FilenameGenerator = 'Use sequential filename';
opts.showWaitbar       = true;
opts.silent            = true;
opts.overwrite         = true;
opts.pixSize           = struct('x',0.1,'y',0.1,'z',0.5,'units','um','t',1,'tunits','s');

fnOut = img.save('/output/slice.tif', opts);
% Produces: /output/slice_001.tif, /output/slice_002.tif, ...

Example 3 - Save as PNG without explicit Format (inferred from extension)

opts.showWaitbar = false;
opts.silent      = true;
opts.overwrite   = true;
fnOut = img.save('/output/slice.png', opts);

Example 4 - Save 16-bit EM data as HDF5 with voxel metadata

imgEM = core.MibImage(uint16(rand(1024,1024,200,1,1)*65535));
imgEM.filename = 'em_volume.h5';

opts.Format      = 'Hierarchical Data Format (*.h5)';
opts.showWaitbar = true;
opts.silent      = true;
opts.overwrite   = true;
opts.pixSize     = struct('x',0.004,'y',0.004,'z',0.03,'units','um','t',1,'tunits','s');

fnOut = imgEM.save('/output/em_volume.h5', opts);

Example 5 - Save from inside a controller with access to the MIB GUI

opts.Format         = 'Amira Mesh binary (*.am)';
opts.Saving3DPolicy = '3D stack';
opts.showWaitbar    = true;
opts.silent         = true;
opts.overwrite      = true;
opts.pixSize        = struct('x',0.065,'y',0.065,'z',0.2,'units','um','t',1,'tunits','s');
opts.ParentFigure   = obj.mibModel.mibGUI;   % enables uiprogressdlg
opts.mibPath        = obj.mibModel.mibPath;  % enables icon lookup

fnOut = img.save('/output/stack.am', opts);

See also

core.MibLabels.save, core.MibDataset.saveImage, models.MibModel.saveImage, io.SaverFactory, io.savers.BaseSaver

setData(dataset, layerType, orient, colChannel, options)

SETDATA - Set dataset to MibBaseImage class.

Syntax:
result = obj.setData(dataset, layerType, orient, colChannel, options)
Input Arguments:
  • dataset - matrix with the dataset to update MibBaseImage.data

  • layerType - char with the type of layer to obtain, used for MibLabels63 class, otherwise can be empty. Values are ‘labels’, ‘mask’, ‘selection’, or ‘everything’ to get all layers at once, default = ‘image’

  • orient - (optional), can be []; default 3:

    • 1 - updates transposed dataset from ZX configuration: [z,x,y,c,t] → [y,x,z,c,t] (rows = Z, columns = X)

    • 2 - updates transposed dataset from ZY configuration: [y,z,x,c,t] → [y,x,z,c,t]

    • 3 - updates original dataset from YX configuration: [y,x,z,c,t]

  • colChannel - (optional), can be []; when [] sets all color channels or materials:

    • for type = 'image': vector of color channel indices; [] = all channels

    • for type = 'labels': integer material index (returned as binary 0/1); [] = all materials

  • options - (optional), a structure with extra parameters

    • .y (optional), [ymin, ymax] coordinates of the dataset to set after transpose, can be a single number

    • .x (optional), [xmin, xmax] coordinates of the dataset to set after transpose, can be a single number

    • .z (optional), [zmin, zmax] coordinates of the dataset to set after transpose, can be a single number

    • .t (optional), [tmin, tmax] coordinates of the dataset to set after transpose, can be a single number

Output Arguments:
  • result - 1 - success, 0 - error

Usage:

Example 1

obj.setData(dataset, [], 3, []);% set the complete dataset in the YX orientation

Example 2

options.x = [100 200];
options.y = [100 200];
options.z = 100;
options.t = 1;
colChannel = 2;
obj.setData(dataset, [], [], colChannel, options);% set subvolume = [100:200, 100:200] at slice 100, color channel 1
setDataFast(dataset, z, colChannel, t)

SETDATAFAST - In-place slice/volume write used by the MibDataset fast paths.

Syntax:
obj.setDataFast(dataset, z, colChannel, t)

Keeps the indexed assignment inside MibImage (a single handle hop) so that MATLAB mutates obj.data in place instead of copy-on-writing the whole 5-D array. Writing through MibDataset.(layer).data(...) = dataset (two handle hops) defeats MATLAB’s in-place optimization and copies the entire array on every call - the source of the per-slice setData2D/setData3D slowdown.

When the write spans the entire array (all z, all channels, all time points), the element-wise indexed assignment is skipped altogether and obj.data is replaced by reference (obj.data = reshape(dataset, …)) - an O(1) copy-on-write swap instead of touching every element.

Input Arguments:
  • dataset - [numeric] 2D slice [height, width] (when z is a scalar), 3D volume [height, width, depth] (when z is []), or 4D series [height, width, depth, time] (when both z and t are [])

  • z - [numeric or []] slice index for a 2D write, or [] to write the full depth (3D volume / 4D series write)

  • colChannel - [numeric] color channel / material index(es) to write

  • t - [numeric or []] time point to write, or [] to write all time points

Note

Only the simple full-channel case is routed here by the fast paths; the material-index labels case is handled by the slow path. The literal colons are kept inside this method so the assignment stays in-place.

setMeta(meta)

SETMETA - Apply a metadata dictionary to MibImage properties.

Syntax:
obj.setMeta(meta)

Updates the object’s properties from a dictionary matching the schema of MibImage.initializeImgInfo(). Does NOT touch obj.data - only updates metadata properties. This is the inverse of getMeta().

Input Arguments:
  • meta - dictionary with MibImage metadata fields (as returned by getMeta or initializeImgInfo)

Output Arguments:

Usage:

Example 1

meta = obj.mibModel.I{obj.mibModel.id}.image.getMeta();
meta{'Width'} = 1024;
obj.mibModel.I{obj.mibModel.id}.image.setMeta(meta);% apply modified metadata
setPixelIdxList(type, dataset, PixelIdxList)

SETPIXELIDXLIST - Write pixel values at a list of linear indices into MibImage or a subclass.

Syntax:
result = obj.setPixelIdxList(type, dataset, PixelIdxList)

For standard MibImage and MibLabels the raw data are written directly to obj.data. For MibLabels63 (bit-packed) the values are packed into the appropriate bits: - ‘labels’ - bits 1-6: clear old label (bitand 192) then bitor new value - ‘mask’ - bit 7: bitset position 7 - ‘selection’ - bit 8: bitset position 8 - ‘everything’- overwrite raw byte without any masking

Input Arguments:
  • type - char, layer type to write:

    • 'image' - pixel values of an image layer (MibImage)

    • 'labels' - material indices into labels layer

    • 'mask' - mask layer values (0/1)

    • 'selection' - selection layer values (0/1)

    • 'everything' - raw packed byte (MibLabels63 only)

  • dataset - numeric vector of values to write; must match numel(PixelIdxList)

  • PixelIdxList - numeric vector of linear pixel indices into obj.data in the XY orientation (standard MATLAB column-major order)

Output Arguments:
  • result - logical true on success, false on error

Usage:

Example 1

CC = bwconncomp(mask3D, 26);
val = zeros(numel(CC.PixelIdxList{1}), 1, 'uint8') + 1;
obj.labels.setPixelIdxList('selection', val, CC.PixelIdxList{1});

Example 2 - Clearing the selection layer at specific pixels

% Clearing the selection layer at specific pixels:
obj.labels.setPixelIdxList('selection', zeros(numel(idx),1,'uint8'), idx);
shiftColorChannel(channel1, dx, dy, fillValue, options)

SHIFTCOLORCHANNEL - Shift a color channel by dx/dy pixels.

Syntax:
obj.shiftColorChannel(channel1, dx, dy, fillValue, options)

Pixels that shift out of the frame are discarded; the vacated border region is filled with fillValue.

Input Arguments:
  • channel1 - 1-based index of the channel to shift

  • dx - shift in X (columns), in pixels; positive = shift right

  • dy - shift in Y (rows), in pixels; positive = shift down

  • fillValue - (optional) intensity used to fill the vacated border; default 0

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - shift channel 1 by +10 px in X and -5 px in Y

obj.image.shiftColorChannel(1, 10, -5, 0);
splitImageDescription(fullStr)

SPLITIMAGEDESCRIPTION - Split a full ImageDescription string into the BoundingBox part and a cell array of per-operation log entries.

Syntax:
[imageDescription, actionLog] = splitImageDescription(fullStr)

BACKGROUND MIB stores two conceptually distinct pieces of information inside the single ImageDescription tag that is written to TIFF (and other) files:

1. Physical extent (BoundingBox) - a compact string describing the real-world coordinates of the dataset in micrometres:

‘BoundingBox xmin xmax ymin ymax zmin zmax’

2. Operation log - a pipe-separated list of timestamped records that document every processing step applied to the dataset since it was first opened in MIB:

‘MIB(2601041823): MIB demo dataset, Huh7 SBEM’ ‘MIB(2603131934): ImFilter: Gaussian, HSize:3 3, Sigma:0.6, …’

The two parts are concatenated with ‘|’ as delimiter:

‘BoundingBox x1 x2 y1 y2 z1 z2|LogEntry1|LogEntry2|…’

This function separates them so that: - imageDescription carries the BoundingBox string; parsed by MibImage.initialize into obj.boundingBox (a 1×6 double). - actionLog carries the per-operation records; stored in obj.actionLog of the MibImage (and its subclasses MibLabels, MibVirtualImage); appended to when operations are performed.

Input Arguments:
  • fullStr - (char) the raw ImageDescription string as read from a file or stored in an imginfo dictionary. May be empty, contain only a BoundingBox with no log entries, or only log entries with no BoundingBox. All combinations are handled gracefully.

Output Arguments:
  • imageDescription - (char) the substring preceding the first '|', trimmed of whitespace. Contains the BoundingBox tag when present, or is empty when the input starts immediately with '|'.

  • actionLog - (1×N cell of char) each element is one log entry, trimmed of whitespace. Empty entries (consecutive '||' or trailing '|') are silently discarded. Returns {} when no log entries are found.

Usage:

Example 1 - Typical MIB TIFF tag with BoundingBox and two log entries

raw = ['BoundingBox 0.000000 6.760000 0.000000 4.823000 0.000000 2.220000' ...
       '|MIB(2601041823): MIB demo dataset, Huh7 SBEM' ...
       '|MIB(2603131934): ImFilter: Gaussian, HSize:3  3, Sigma: 0.6,' ...
       'Orient:4,ColCh:1, Mode:2D, shown slice, Options:Apply filter,slice=1'];

[imgDesc, log] = core.MibImage.splitImageDescription(raw);
% imgDesc -> 'BoundingBox 0.000000 6.760000 0.000000 4.823000 0.000000 2.220000'
% log     -> {'MIB(2601041823): MIB demo dataset, Huh7 SBEM', ...
%             'MIB(2603131934): ImFilter: Gaussian, ...'}

Example 2 - BoundingBox only, no log

raw = 'BoundingBox 0 511.5 0 511.5 0 49.5';
[imgDesc, log] = core.MibImage.splitImageDescription(raw);
% imgDesc -> 'BoundingBox 0 511.5 0 511.5 0 49.5'
% log     -> {}

Example 3 - Log entries only, no BoundingBox (e.g. ImageJ description)

raw = 'ImageJ=1.52p|unit=um|spacing=0.2|loop=false';
[imgDesc, log] = core.MibImage.splitImageDescription(raw);
% imgDesc -> 'ImageJ=1.52p'
% log     -> {'unit=um', 'spacing=0.2', 'loop=false'}

Example 4 - Empty or default initializer string

[imgDesc, log] = core.MibImage.splitImageDescription('');
% imgDesc -> ''
% log     -> {}

[imgDesc, log] = core.MibImage.splitImageDescription('|');  % initializeImgInfo default
% imgDesc -> ''
% log     -> {}

Example 5 - Typical loader workflow: split immediately after reading metadata

raw = imginfo{'ImageDescription'};   % full string from file
[imgDesc, actionLog] = core.MibImage.splitImageDescription(raw);

% Store split parts back into the dictionary before passing to MibDataset
imginfo{'ImageDescription'} = imgDesc;
imginfo{'ActionLog'}        = actionLog;

Example 6 - Round-trip test: split then rejoin

raw = 'BoundingBox 0 10 0 8 0 4|MIB(001): opened|MIB(002): filtered';
[imgDesc, log] = core.MibImage.splitImageDescription(raw);

if isempty(log)
    rebuilt = imgDesc;
else
    rebuilt = [imgDesc '|' strjoin(log, '|')];
end
assert(strcmp(raw, rebuilt));

See also

core.MibImage.initializeImgInfo, core.MibDataset.initialize, core.MibDataset.saveImage

swapColorChannels(channel1, channel2, options)

SWAPCOLORCHANNELS - Swap two color channels in obj.data.

Syntax:
obj.swapColorChannels(channel1, channel2, options)
Input Arguments:
  • channel1 - 1-based index of the first channel

  • channel2 - 1-based index of the second channel

  • options - (optional) struct with fields:

    • .showWaitbar - logical; show progress bar (default true)

    • .ParentFigure - handle to parent figure for the progress dialog (default [])

Usage:

Example 1 - swap channels 1 and 3

obj.image.swapColorChannels(1, 3);
swapSlices(sliceFrom, sliceTo, orient)

SWAPSLICES - Swap specified slice(s) between two positions within the same array.

Syntax:
result = obj.swapSlices(sliceFrom, sliceTo, orient)

Pure data-manipulation layer: operates only on obj.data. No dialogs, no waitbars, no annotation handling. Caller (core.MibDataset.swapSlices) is responsible for auxiliary-layer operations and action-log updates.

Input Arguments:
  • sliceFrom - index or index vector of source slices

  • sliceTo - index or index vector of destination slices; must be the same length as sliceFrom

  • orient - (optional) dimension to operate on: 1 = height (y), 2 = width (x), 3 = depth (z, default), 5 = time (t)

Output Arguments:
  • result - 1 on success, 0 on failure

Usage:

Example 1

result = obj.image.swapSlices(3, 10);  % swap z-slices 3 and 10

Example 2

result = obj.image.swapSlices([1,2], [5,6], 3);  % swap two-slice blocks
updateActionLog(logEntry, action, entryIndex)

UPDATEACTIONLOG - Append or modify a timestamped entry in the action log (obj.actionLog).

Syntax:
obj.updateActionLog(logEntry, action, entryIndex)
Input Arguments:
  • logEntry - [char or string] description of the processing step to record, e.g. ‘ImFilter: Median, HSize:3 3, Orient:4’. Pass ‘’ when only performing a delete action.

  • action - (optional) additional operation to perform; when omitted, entry is appended to the end:

    • 'insert' - insert new entry before position entryIndex

    • 'delete' - delete entry at position entryIndex (logEntry is ignored)

    • 'modify' - overwrite entry at position entryIndex

  • entryIndex - (optional) 1-based index for ‘insert’, ‘delete’, ‘modify’

Output Arguments:

(none) - modifies obj.actionLog in place.

Usage:

Example 1

obj.image.updateActionLog('ImFilter: Median, HSize:3 3, Orient:4');

Example 2

obj.image.updateActionLog('MIB demo dataset', 'insert', 2);

Example 3

obj.image.updateActionLog('', 'delete', 4);

Example 4

obj.image.updateActionLog('Updated text', 'modify', 4);
updateBoundingBox(newBB, xyzShift, imgDims)

UPDATEBOUNDINGBOX - Update the bounding box of the dataset stored in obj.boundingBox.

Syntax:
obj.updateBoundingBox(newBB, xyzShift, imgDims)

The bounding box describes the physical extent of the dataset in 3D space. It is stored directly in the obj.boundingBox property as [xmin xmax ymin ymax zmin zmax] in micrometres.

Input Arguments:
  • newBB - new bounding box vector [xmin xmax ymin ymax zmin zmax] in obj.pixSize.units. Pass [] (empty) to shift the existing bounding box instead of replacing it entirely.

  • xyzShift - [optional] vector [dx dy dz] with shifts in obj.pixSize.units to apply to the current bounding box origin when newBB is empty. When omitted the origin remains unchanged.

  • imgDims - [optional] vector [height width depth] with image dimensions used to compute the new extent. When omitted obj.height, obj.width and obj.depth are used.

Output Arguments:

(none) - obj.boundingBox and obj.pixSize.x/y/z are updated in place

Usage:

Example 1 - shift the bounding box by 10 units in X, 5 in Y, 0 in Z

% shift the bounding box by 10 units in X, 5 in Y, 0 in Z:
xyzShift = [10 5 0];
mibImage.updateBoundingBox([], xyzShift);

Example 2 - assign an explicit bounding box

% assign an explicit bounding box:
mibImage.updateBoundingBox([15 50 10 150 1 15]);