Main Content

images.blocked.Adapter class

Package: images.blocked

Adapter interface for blockedImage objects

Description

The images.blocked.Adapter class specifies the interface for block-based reading and writing of array data. Classes that inherit from this interface can be used with blockedImage objects, enabling block-based stream processing of array data.

The images.blocked.Adapter class is a handle class.

Class Attributes

Abstract
true

For information on class attributes, see Class Attributes.

Creation

To implement this class, you must:

  • Inherit from the images.blocked.Adapter class. Type the following syntax as the first line of your class definition file:

    classdef MyAdapter < images.blocked.Adapter
        ...
    end
  • Define three required methods for reading image data from disk: openToRead, getInfo, and getIOBlock.

  • Optionally, define methods that enable additional reading and writing capabilities. The table lists the complete set of capabilities offered by Adapter methods.

  • Optionally, for single-file destinations, define an Extension property that specifies the file extension to use when automatically creating a destination location. The property must be a string, such as "jpg". For adapters that store data in a folder, do not add this property or specify the value of the property as empty ([]).

CapabilityMethods to Implement
Read data (Required)

openToRead – Open source for reading

getInfo – Gather information about the source

getIOBlock – Get specified I/O block

Write data (Optional)

openToWrite – Create and open destination for writing

setIOBlock – Set specified I/O block

Perform clean up tasks (Optional)close – Perform clean up tasks such as closing file handles
Enable parallel block processing (Optional)openInParallelToAppend – Use the adapter in parallel mode with the apply object function
Resume writing after interruption (Optional)alreadyWritten – Enable the resume option in the apply object function

Examples

collapse all

This example shows how to define and use a custom adapter that reads 3-D TIFF image data as a single volumetric image.

Create a .m class definition file that contains the code implementing your custom adapter. You must save this file in your working folder or in a folder that is on the MATLAB® path. The name of the .m file must be the same as the name of your object. For example, if you want your adapter to have the name My3DTIFFAdapter, then the name of the .m file must be My3DTIFFAdapter.m. The .m class definition file must contain the following steps:

  • Step 1: Inherit from the images.blocked.Adapter class.

  • Step 2: Define required methods.

In addition to these steps, define any other properties or methods that you need to process and analyze your data.

%% STEP 1: INHERIT FROM ADAPTER CLASS
classdef My3DTIFFAdapter < images.blocked.Adapter
    
    properties
        File (1,1) string
        Info (1,1) struct
    end    
    
%% STEP 2: DEFINE REQUIRED METHODS
    methods
        
        % Define the openToRead method
        function openToRead(obj,source)
            obj.File = source;
        end

        % Define the getInfo method      
        function info = getInfo(obj)
            % Read raw file info
            finfo = imfinfo(obj.File);
            
            % Make sure all slices are the same size.
            assert(all(finfo(1).Width==[finfo.Width]), ...
                'All slices do not have the same width.');
            assert(all(finfo(1).Height==[finfo.Height]), ...
                'All slices do not have the same height.');
            obj.Info.Size = [finfo(1).Height, finfo(1).Width, numel(finfo)];
            
            % The first two dims of the smallest unit of data that can be
            % read depends on the type of TIFF file - stripped or tiled.
            % The third dim is always 1 - indicating that the smallest unit
            % that can be read in the third dimensions is 1 (one slice).
            if isempty(finfo(1).TileWidth)
                % This is a stripped TIFF file
                obj.Info.IOBlockSize = [finfo(1).RowsPerStrip, finfo(1).Width, 1];
            else
                % This is a tiled TIFF file
                obj.Info.IOBlockSize = [finfo(1).TileLength, finfo(1).TileWidth, 1];
            end
            
            % This is usually the same for a data set and can be hardcoded.
            assert(finfo(1).BitsPerSample==8 && finfo(1).BitDepth==8)
            obj.Info.Datatype = "uint8";
            obj.Info.InitialValue = cast(0,obj.Info.Datatype);
            info = obj.Info;
        end
        
        % Define the getIOBlock method
        function block = getIOBlock(obj,ioblockSub,level)
            assert(level==1)
            
            % Convert ioblockSub (which is in terms of IOBlockSize) into a
            % 'PixelRegion' coordinate.
            regionStart = (ioblockSub-1).*obj.Info.IOBlockSize + 1;
            regionEnd = (ioblockSub).*obj.Info.IOBlockSize;
            rows = [regionStart(1), regionEnd(1)];
            cols = [regionStart(2), regionEnd(2)];
            slices = [regionStart(3), regionEnd(3)];
            
            block = tiffreadVolume(obj.File, ...
                'PixelRegion',{rows,cols,slices});
        end

    end
end

Your custom adapter is now ready. Use My3DTIFFAdapter to create an adapter object that reads files with 3-D TIFF image data.

Create a blocked image that reads data using the custom adapter, My3DTIFFAdapter. This adapter is attached to the example as a supporting file. Display the size of the blocked image.

filename = 'mri.tif';
a = My3DTIFFAdapter
a = 
  My3DTIFFAdapter with properties:

    File: ""
    Info: [1×1 struct]

bim = blockedImage(filename,'Adapter',My3DTIFFAdapter);
bimSize = bim.Size
bimSize = 1×3

   128   128    27

For comparison, create a blocked image that reads the data using the default adapter. Display the size of the blocked image.

bimDefault = blockedImage(filename);
bimDefaultSize = bimDefault.Size
bimDefaultSize = 27×2

   128   128
   128   128
   128   128
   128   128
   128   128
   128   128
   128   128
   128   128
   128   128
   128   128
      ⋮

Test the custom adapter by reading one quadrant of the volumetric data.

regionStart = [1 1 1];
regionEnd = [bimSize(1:2)/2 bimSize(3)];
vol = getRegion(bim,regionStart,regionEnd);

Display the data.

p = uipanel(figure);
volshow(vol,'Parent',p);

Tips

  • The toolbox includes several built-in adapters that subclass from the Adapter class. All these adapters support both read and write operations. All of the adapters that work on a per-block basis, such as GenericImageBlocks, can be used with the parallel mode of the apply object function.

    AdapterDescription
    BINBlocksStore each block as a binary file in a folder
    GenericImage Store blocks in a single image
    GenericImageBlocksStore each block as an image file in a folder
    H5Store blocks in a single HDF5 image
    H5BlocksStore each block as an HDF5 file in a folder
    InMemoryStore blocks in a variable in main memory
    JPEGBlocksStore each block as a JPEG file in a folder
    MATBlocksStore each block as a MAT file in a folder
    PNGBlocksStore each block as a PNG file in a folder
    TIFFStore blocks in a single TIFF file

See Also

Introduced in R2021a