Block Size and Performance
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.
TIFF Image Characteristics
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. (Stripped TIFF images are always organized in rows, never in columns.) 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 imfinfo
function.
The struct returned by imfinfo
for TIFF images contains the fields
TileWidth
and 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 ([]
), then
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.
Choose Block Size to Optimize blockproc Performance
This example shows how block size influences the performance of blockproc
. In each of these cases, the total number of pixels in each block is approximately the same. Only the dimensions of the blocks are different.
Read an image file and convert it to a TIFF file.
I = imread('concordorthophoto.png','PNG'); imshow(I)
imwrite(I,'concordorthophoto.tif','TIFF');
Use imfinfo
to determine whether concordorthophoto.tif
is organized in strips or tiles. The RowsPerStrip
field of the info
struct indicates that this TIFF image is organized in strips with 34 rows per strip. Each strip spans the width of the image and is 34 pixels tall.
info = imfinfo('concordorthophoto.tif');
info.RowsPerStrip
ans = 34
Get the image size from the Height
and Width
fields of info
. This image has size 2215-by-2956 pixels.
h = info.Height
h = 2215
w = info.Width
w = 2956
Case 1: Square Blocks
Process the image using square blocks of size 500-by-500 pixels. 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 34 rows per strip and 500 rows per block, blockproc
accesses the disk 15 times for each block. The image is approximately 6 blocks wide (2956/500 = 5.912). blockproc
reads the same strip over and over again for each block that includes pixels contained in that strip. Since the image is six blocks wide, blockproc
reads every strip of the file six times.
blockSizeSquare = 500;
tic
im = blockproc('concordorthophoto.tif',[blockSizeSquare blockSizeSquare],@(s) s.data);
toc
Elapsed time is 0.258248 seconds.
Case 2: Column-Shaped Blocks
Process the image using blocks that span the full height of the image. Stripped TIFF files are organized in rows, so this block layout is exactly opposite the actual file layout on disk.
Select a block width such that the blocks have approximately the same number of pixels as the square block.
numCols = ceil(blockSizeSquare.^2 / h)
numCols = 113
The image is over 26 blocks wide (2956/numCols
= 26.1593). Every strip must be read for every block, therefore blockproc
reads the entire image from disk 26 times.
tic
im = blockproc('concordorthophoto.tif',[h numCols],@(s) s.data);
toc
Elapsed time is 0.145255 seconds.
Case 3: Row-Shaped Blocks
Process the image using blocks that span the full width of the image. This block layout aligns with the TIFF file layout on disk.
Select a block height such that the blocks have approximately the same number of pixels as the square block.
numRows = ceil(blockSizeSquare.^2 / w)
numRows = 85
Each block spans the width of the image, therefore blockproc
reads each strip exactly once. The execution time is shortest when the block layout aligns with the TIFF image strips.
tic
im = blockproc('concordorthophoto.tif',[numRows w],@(s) s.data);
toc
Elapsed time is 0.080977 seconds.