1
votes

How do I assign 1 dimensional slices in a 3d array in MATLAB?

I have a logical 2d array named 'CD' which corresponds to the pixels of a 3-D image matrix (RGB format) that I would like to set.

CD = any(d, 3);
CDM(CD) = 255;

So in this case, 'CDM' is a 3d matrix containing R,G,B values for every pixel (e.g. it's a 771x457x3 matrix).

The above code works. It generates an image of red pixels I want them.

But suppose now that I want to generate, say, green or cyan pixels? How do I access the second and third "layers" (the green and blue values) of 'CDM'? I tried assigning

CDM(CD) = [0 255 255];

but this returns the error

In an assignment  A(:) = B, the number of elements in A and B must be the same.
1

1 Answers

2
votes

In order to modify each channel with a 2D array like that, you need to grab each channel (as a 2D array), then use the 2D logical array to replace the pixels you want with the desired value and then assign it back into the array.

green = CDM(:,:,2);
green(CD) = 255;
CDM(:,:,2) = green;

Alternately, you could do something like the following to vectorize the problem.

replace_color = [0 255 255];
CDM = bsxfun(@times, ~CD, CDM) + bsxfun(@times, CD, reshape(replace_color, [1 1 3]))

Explanation

First we use bsxfun to perform dimension broadcasting and multiply every RGB pixel within CDM with the inverse (~) of the logical matrix. This sets all of the pixels that are 1 in CD to 0 and leaves all other pixels as their original value (since they are multiplied by 1).

bsxfun(@times, ~CD, CDM)

We then multiply CD by the new color (reshaped to be a 1 x 1 x 3 array) to produce an M x N x 3 array where each RGB vector where CD was 1 is the desired RGB value and all other values are 0.

bsxfun(@times, CD, reshape(replace_color, [1 1 3]))

We then add these two together to keep the RGB value wherever CD was 0 and replace the RGB value with the new value wherever CD was 1.

If you're on R2016b or later, you can remove bsxfun and the solution is simplified to:

CDM = (~CD .* CDM) + (CD .* reshape(replace_color, [1 1 3]));