horseshoe
horseshoe

Reputation: 1477

Matlab array as index for matrix

I have an image and a pixellist of several large objects in that image defined with regionprops. Now I want to generate a new image that only contains one object which is resized to the size of the object. So what I do is

rawimage = imread('testfile.tif');
processimage = squeeze((sum(rawimage,3))');
IMAGE_labeled = bwlabel(processimage,8);
shapedata=regionprops (IMAGE_labeled,'Area','PixelList');
index = find ([shapedata.Area]>5000);

for i = 1:length(index)
   ix = shapedata(index(i)).PixelList(:,1);
   iy = shapedata(index(i)).PixelList(:,2);
   newimage = zeros(max(ix)-min(ix)+1,max(iy)-min(iy)+1,3);
   for im = 1:length(ix)
      newimage(ix(im)-min(ix)+1,iy(im)-min(iy)+1,:) =   rawimage(ix(im),iy(im),:);
   end
   newimage = uint8(newimage);
   imwrite(newimage,'myimage.tif','tif')
end

Has anyone an idea how I can vectorize the second for loop to speed the whole code up? In the end the question is how can I use two vectors as index in a matrix.

I found

Vc = num2cell([ix,iy])
rawimage(sub2ind(size(rawimage),Vc{i,:}))

but this again requires a for loop to go through all indices of Vc as I cannot use

rawimage(sub2ind(size(rawimage),Vc))  

Thanks for your suggestions

Upvotes: 0

Views: 60

Answers (1)

Suever
Suever

Reputation: 65430

Because your image has a third dimension, you'll need to reshape it a bit into an [M*N x 3] array first. You can then use sub2ind as you've shown.

for k = 1:numel(shapedata)
    % Flip the PixelList so it's row/column rather than x/y
    list = fliplr(shapedata(k).PixelList);

    % Figure out the extents of the PixelList values
    minima = min(list, [], 1);
    maxima = max(list, [], 1);

    % Grab a square of the image containing the object of interest
    subimage = rawimage(minima(1):maxima(1), minima(2):maxima(2),:);

    % Store the size
    sz = size(subimage);

    % Convert the PixelList values to linear indices within this sub-image
    inds = sub2ind(sz(1:2), bsxfun(@minus, list, minima - 1));

    % Reshape so that we can index into the first two dimensions at the same time
    subimage = reshape(subimage, [], size(subimage, 3));

    % Now create the output which is all zeros, but then we grab the values that are
    % in PixelList and set them within the new matrix.
    newimage = zeros(size(subimage));
    newimage(inds,:) = subimage(inds,:);

    % Reshape the result to be the expected dimension
    newimage = reshape(newimage, sz);
end

Upvotes: 2

Related Questions