File Exchange

## mat2im

version 1.4.0.0 (2.14 KB) by Rob Campbell

### Rob Campbell (view profile)

Convert 2D matrix to a 3D image matrix as used by the image processing toolbox

Updated 15 Aug 2010

This code snippet converts a 2D matrix to a 3D matrix where the values in the 3rd dimension correspond to pixel intensity in the red, green, and blue domains. This is the format used by many functions in the Image Processing Toolbox (which is not required for this function to run).

The code works by mapping the values of matrix "mat" onto the rows of colormap "cmap" using a fast vectorised operation.

function im=mat2im(mat,cmap,maxVal)

PURPOSE
Uses vectorized code to convert matrix "mat" to an m-by-n-by-3
image matrix which can be handled by the Mathworks image-processing
functions. The the image is created using a specified color-map
and, optionally, a specified maximum value. Note that it discards
negative values!

INPUTS
mat - an m-by-n matrix
cmap - an m-by-3 color-map matrix. e.g. hot(100). If the colormap has
few rows (e.g. less than 20 or so) then the image will appear
contour-like.
limits - by default the image is normalised to it's max and min values
so as to use the full dynamic range of the
colormap. Alternatively, it may be normalised to between
limits(1) and limits(2). Nan values in limits are ignored. So
to clip the max alone you would do, for example, [nan, 2]

OUTPUTS
im - an m-by-n-by-3 image matrix

Example 1 - combine multiple color maps on one figure
clf, colormap jet, r=rand(40);
subplot(1,3,1),imagesc(r), axis equal off , title('jet')
subplot(1,3,2),imshow(mat2im(r,hot(100))) , title('hot')
subplot(1,3,3),imshow(mat2im(r,summer(100))), title('summer')
colormap winter %changes colormap in only the first panel

Example 2 - clipping
p=peaks(128); J=jet(100);
subplot(2,2,1), imshow(mat2im(p,J)); title('Unclipped')
subplot(2,2,2), imshow(mat2im(p,J,[0,nan])); title('Remove pixels <0')
subplot(2,2,3), imshow(mat2im(p,J,[nan,0])); title('Remove pixels >0')
subplot(2,2,4), imshow(mat2im(p,J,[-1,3])); title('Plot narrow pixel range')

Rob Campbell - April 2009

### Cite As

Rob Campbell (2020). mat2im (https://www.mathworks.com/matlabcentral/fileexchange/26322-mat2im), MATLAB Central File Exchange. Retrieved .

Daniel Moran

### Daniel Moran (view profile)

sorry -- ignore my comment on 7 Feb 2018. It is totally wrong.

Daniel Moran

### Daniel Moran (view profile)

Fails if the colormap is too small (specifically, if numel(mat) < size(cmap,1) )

One way to fix this - not so elegant, I know - is to create a larger colormap using linear interpolation on the provided one. Add these lines of code just before the step, "%Vectorised way of making the image matrix"

if size(cmap,1)<numel(mat)
nc = size(cmap,1);
nv = numel(mat);
cx = 1:nc; cx=cx-min(cx); cx = cx/max(cx);
vx = 1:nv; vx=vx-min(vx); vx = vx/max(vx);

newcmap = zeros(nv,3);
newcmap(:,1) = interp1(cx,cmap(:,1),vx);
newcmap(:,2) = interp1(cx,cmap(:,2),vx);
newcmap(:,3) = interp1(cx,cmap(:,3),vx);
cmap = newcmap;
end

Great util though! Thank you!

John Booker

Jurgen

### Jurgen (view profile)

Hi I made some changes to this:
- for uint8 use limits [0 255] instead of [1 256] etc.
- Expanded input checking logic
- Changed output type to single

test

Wolfgang Schwanghart

chunsu

Rob Campbell

### Rob Campbell (view profile)

Righto, will insert it when I have time.
BTW, the clipping is now completely re-written and now works in the way you are suggesting.

Jan

### Jan (view profile)

Rob, if "mat(mat>L)" is only needed if a clipping value is specified, you could move it inside the corresponding IF branch to save time otherwise.
With "double(mat)+1" MAT2IM would additionally support zero-base indexed images in integer formats (e.g. from see help of IND2RGB, IMREAD) - it is not "needed", but a nice extra feature.

Rob Campbell

### Rob Campbell (view profile)

Jan, I didn't add the "if ~isa(mat, 'double'), mat = double(mat) + 1; end" because I don't think it's needed here due to the normalisation step. If I've misunderstood why it's needed then let me know and I'll introduce it.

Rob Campbell

### Rob Campbell (view profile)

Thanks for the comments, I will update it accordingly and add the possibility to specificity minimum value.

Jan, the "mat(mat>L)" line is actually used to do the clipping/scaling if you specify a different maximum value.

Oliver Woodford

### Oliver Woodford (view profile)

A slightly faster version of IND2RGB, if you want colors discretized as per the colormap.

If you want smooth (linear) interpolation between colors in the colormap then an alternative is REAL2RGB (here on the FEX). It also allows a min and a max value to be specified for clipping. However, it is over 5 times slower than this function (but still a fraction of a second for a megapixel image).

Jan

### Jan (view profile)

Good help, no H1-line (it is worth to follow this convention to support LOOKFOR), checks number but not type of inputs, several examples. The function works efficiently. I personally do not need/want the normalization, but it may be useful for others.

If the input is normalized to the max value, you do not have to chech for "mat(mat>L)" anymore.
If image matrices have INT type, they're 0-based in Matlab usually. Think of "if ~isa(mat, 'double'), mat = double(mat) + 1; end".
This function is very similar to Matlab's IND2RGB (so it is worth to mention it, e.g. "See also..."), but it is remarkably faster: 36% processing time of IND2RGB for a 1024x768 image with 1000 colors!

@TMW: Please insert the faster methods to limit the input and to create the output into IND2RGB!