When using the
blockproc function to either read or write image
files, the number of times the file is accessed can significantly affect performance. In
general, selecting larger block sizes reduces the number of times
blockproc has to access the disk, at the cost of using more memory to
process each block. Knowing the file format layout on disk can help you select block sizes
that minimize the number of times the disk is accessed. See the
blockproc reference page for more information about file formats.
TIFF images organize their data on disk in one of two ways: in tiles or in strips. A tiled TIFF image stores rectangular blocks of data contiguously in the file. Each tile is read and written as a single unit. TIFF images with strip layout have data stored in strips; each strip spans the entire width of the image and is one or more rows in height. Like a tile, each strip is stored, read, and written as a single unit.
When selecting an appropriate block size for TIFF image processing, understanding the
organization of your TIFF image is important. To find out whether your image is
organized in tiles or strips, use the
The struct returned by
imfinfo for TIFF images contains the fields
TileLength. If these fields have
valid (nonempty) values, then the image is a tiled TIFF, and these fields define the
size of each tile. If these fields contain values of empty (
the TIFF is organized in strips. For TIFFs with strip layout, refer to the struct field
RowsPerStrip, which defines the size of each strip of data.
When reading TIFF images, the minimum amount of data that can be read is a single
tile or a single strip, depending on the type of TIFF. To optimize the performance of
blockproc, select block sizes that correspond closely with how
your TIFF image is organized on disk. In this way, you can avoid rereading the same
pixels multiple times.
The following three cases demonstrate the influence of block size on the performance
blockproc. In each of these cases, the total number of pixels in
each block is approximately the same; only the size of the blocks is different.
First, read in an image file and convert it to a TIFF.
imageA = imread('concordorthophoto.png','PNG'); imwrite(imageA,'concordorthophoto.tif','TIFF');
imfinfo to determine whether
concordorthophoto.tif is organized in strips or tiles.
Select fields from the struct appear below:
ans = struct with fields: Filename: '\\fs-21-ah\home$\jholohan\Documents\MATLAB\concordorthophoto.tif' FileModDate: '10-Nov-2016 17:34:44' FileSize: 6586702 Format: 'tif' FormatVersion:  Width: 2956 Height: 2215 BitDepth: 8 ColorType: 'grayscale' FormatSignature: [73 73 42 0] ByteOrder: 'little-endian' NewSubFileType: 0 BitsPerSample: 8 Compression: 'PackBits' PhotometricInterpretation: 'BlackIsZero' StripOffsets: [1×66 double] SamplesPerPixel: 1 RowsPerStrip: 34 StripByteCounts: [1×66 double] XResolution: 72 YResolution: 72 ResolutionUnit: 'Inch' Colormap:  PlanarConfiguration: 'Chunky' TileWidth:  TileLength:  TileOffsets:  TileByteCounts:  Orientation: 1 FillOrder: 1 GrayResponseUnit: 0.0100 MaxSampleValue: 255 MinSampleValue: 0 Thresholding: 1 Offset: 6585984
The value 2 in
RowsPerStrip indicates that this TIFF image is
organized in strips with two rows per strip. Each strip spans the width of the image
(2956 pixels) and is two pixels tall. The following three cases illustrate how choosing
an appropriate block size can improve performance.
First try a square block of size
[500 500]. Each time the
blockproc function accesses the disk it reads in an entire
strip and discards any part of the strip not included in the current block. With two
rows per strip and 500 rows per block, the
accesses the disk 250 times for each block. The image is 2956 pixels wide and 500
rows wide, or approximately six blocks wide (2956/500 = 5.912). The
blockproc function reads the same strip over and over again for
each block that includes pixels contained in that strip. Since the image is six
blockproc reads every strip of the file six
tic, im = blockproc('concordorthophoto.tif',[500 500],@(s) s.data); toc
Elapsed time is 17.806605 seconds.
The file layout on the disk is in rows. (Stripped TIFF images are always organized in rows, never in columns.) Try choosing blocks shaped like columns of size [2215 111]. Now the block is shaped exactly opposite the actual file layout on disk.
The image is over 26 blocks wide (2956/111 = 26.631). Every strip must be read for
every block. The
blockproc function reads the entire image from
disk 26 times. The amount of time it takes to process the image with the
column-shaped blocks is proportional to the number of disk reads. With about four
times as many disk reads in Case 2, as compared to Case 1, the elapsed time is about
four times as
tic, im = blockproc('concordorthophoto.tif',[2215 111],@(s) s.data); toc
Elapsed time is 60.766139 seconds.
Finally, choose a block that aligns with the TIFF strips, a block of size [84 2956]. Each block spans the width of the image. Each strip is read exactly one time, and all data for a particular block is stored contiguously on disk.
tic, im = blockproc('concordorthophoto.tif',[84 2956],@(s) s.data); toc
Elapsed time is 4.610911 seconds.