How to do logical indexing of random pixels in an array of images?

5 views (last 30 days)
I have an array of 14 images with the resolution x*y and 3 rgb values per pixel. It is in the form of (14,x,y,3). Now I want to create a new image with each pixel as one random pick out of the array (use a pixel out of a random image for each pixel in the new image). I can't wrap my head around how to do it without for loops, which are very slow.
I thought it might work with logical indexing, where I make a map using randi(14,x,y) and use that to access the 3 rgb values out of the big array but I don't know how to do it. Appreciate any help!
  2 Comments
Geoff Hayes
Geoff Hayes on 13 Mar 2016
Julius - please quantify very slow. What are the dimensions x and y?
Julius Krumbiegel
Julius Krumbiegel on 13 Mar 2016
slow in this case means a couple of minutes for the operation. x and y are just the width and height of the image, that doesn't matter for the solution but it's like 4500*6300

Sign in to comment.

Accepted Answer

Geoff Hayes
Geoff Hayes on 13 Mar 2016
Julius - I'm wondering if you can perhaps use linear indexing in order to speed up the extraction of a sub-set of pixels from one of your fourteen images. For example, suppose we do the following
% generate the array of pixel indices from each of the fourteen images
pixelIdcs = randi(14,x,y);
% create the new image
newImage = uint8(zeros(x,y,3));
% iterate over each image
for k=1:14
% find the row and column indices of those pixels from the kth image
[rIdcs,cIdcs] = find(pixelIdcs == k);
% convert the row and column indices into linear indices for the first dimension
linIdcs1 = sub2ind([numRows numCols],rIdcs,cIdcs);
% now do same for second and third dimensions
linIdcs2 = linIdcs1+(x*y);
linIdcs3 = linIdcs2+(x*y);
% concatenate all three together
linIdcs = [linIdcs1 ; linIdcs2 ; linIdcs3];
% get the kth image
kthImage = squeeze(myImages(k,:,:,:));
% copy over the pixels from the kth image
newImage(linIdcs) = kthImage(linIdcs);
end
I tried the above with 14 3744x5616x3 images, and it took roughly ten seconds to do the above extraction.
  1 Comment
Julius Krumbiegel
Julius Krumbiegel on 17 Mar 2016
that worked well, thank you! the conversion of multidimensional arrays to vectors and back wasn't in my toolbox yet, but will be very helpful in the future I believe. It is much easier in some cases for certain kinds of calculations to work with vectors than with arrays

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 13 Mar 2016
I believe you might get faster if you have the 14 dimension be the last one not the first one.
Anyway, to get random logical indexes in that 4-D array, use randi
randomLogicalIndexes = logical(randi(1, 1, numel(your4Darray)));
  2 Comments
Julius Krumbiegel
Julius Krumbiegel on 13 Mar 2016
thanks so far, I'll try the numel function. The only thing is that I don't want completely random values (any of the 14, any pixel, any rgb value) but only random as in out of one random picture (any of the 14, correct pixel, correct rgb value). The end result is supposed to have the pixels in the right places and their rgb info intact, it's just supposed to be a random overlay of the images. Do you have an idea how I could achieve that?
Image Analyst
Image Analyst on 13 Mar 2016
Not sure I understand. So you just want to take one of the 14 images at random and use all of the pixels in that RGB image? Like
whichImage = randi(14)
thisRGBImage = your4DArray(whichImage, :, :, :);
That would get you one complete image extracted from your 4D array. You might have to use squeeze() on it though.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!