2
votes

I have an image in grayscale (128x128 pixels, imports into Matlab as a uint8, and I convert it to double with im2double for my analysis). Using another script that I've written, I identify pixels of interest in the image, which are in a cell array of size 1*k (where k is the number of points; each cell in that array, which I've called mypoints) has the coordinates of a pixel in the image.

What I want to do is take the original image, and color those cells in in red (or whatever other color). I can't figure out a good way to change the double image to RGB (it doesn't give a 3-Dimensional matrix, like colored images give), and I've tried to superimpose an otherwise blank graph with those pixels colored in over the image, but I've had no luck with that yet.

Any help would be very much appreciated. Thank you!

1

1 Answers

4
votes

I'm going to assume that each co-ordinate in your cell array is stored in a (x,y) fashion, where x and y denote the column and row of the pixels you want to to colour red in the image.

To make this fast and vectorized, unpack all of your cell elements into a 2D matrix, where the first column represents the x or column co-ordinates, then the second column represents the y or row co-ordinates. You can do that with vertcat like so:

pixels = vertcat(mypoints{:});

mypoints would be that cell array of points that you're talking about (see your previous question regarding if/else statements). Once you do this, I would use sub2ind to convert the column and row co-ordinates into linear indices, then use this to set the locations in your image to red. However, to create a RGB image, you need to create a 3D matrix such that there are three planes, with each plane having the same grayscale image.

If you don't know this already, grayscale pixels in the RGB colour space all have the same red, green and blue values. Therefore, gray would be (R,G,B) = (128.128,128). As such, create three copies of your image and call them red, green and blue. Then, using the locations you found in sub2ind, set those locations in red to be 255, while the same locations in green and blue to 0. Therefore, assuming your image is stored in im, do something like this:

pixels = vertcat(mypoints{:});
ind = sub2ind(size(im), pixels(:,2), pixels(:,1));
red = im;
red(ind) = 255;
green = im;
green(ind) = 0;
blue = im;
blue(ind) = 0;
out_image = cat(3, red, green, blue);
imshow(out_image);

Here's a quick example. Supposing I load the cameraman.tif image, which is built-in to MATLAB, and is uint8 and grayscale. Let's generate a bunch of random co-ordinates in the image... about 200 in total... place them into a cell array like you have and call it mypoints, and run this code:

rng(123); %// Set seed for reproducibility
im = imread('cameraman.tif');
N = 200; %// Number of pixels I want to set
rows = randi(size(im,1), N, 1);
cols = randi(size(im,2), N, 2);
mypoints = arrayfun(@(x) [cols(x) rows(x)], 1:N, 'uni', 0);

You don't need to understand what I did above, but the point is that it reads in the image, and we generate 200 random row and column locations in our image. We then create a cell array where each element is a 2 element array that contains our column and row locations for a particular pixel in the image. randi allows you to generate random integers from 1 up to a specified maximum, and you can specify the size of the output matrix that will store these random numbers. I simply created a N=200 element vector of row and column locations. I then use arrayfun to go over each pair of points and place them as an element into a cell array. The uni=0 flag is important for us to do this.


With mypoints being the cell array you desire, this is what I get when I run the code placing red pixels in our desired locations:

enter image description here

As you can see, there are random pixels in the image that are coloured in red, and these locations were provided from the mypoints cell array.


Have fun!