0

I have a code to crop connected components of input image, input, by finding the boundary conditions from a binary image's labelled map, labelledmap ([labelledmap, labelcount] = bwlabel(hvedged, 8);)

I'm new to matlab so this might sound stupid.. The problem is, I am unable to store different cropped images in the same variable, Because matlab seems to merge the ends of the already existing image and the new cropped image, i.e, it is storing the complete map between the two cropped images, the way i see it :/

This is the output Using different variables for storing cropped image (the kind of output i want) Output Using different variables for storing cropped image

enter image description here

This is the output i'm getting by storing the cropped image in the same variable(not helpful) Output when storing cropped image in the same varible

enter image description here

I tried using an array of size equal to total number of labels produced but it's giving the same result.. also i tried clearvars for clearing the output token image, ltoken, after every iteration of the loop but it's not helping

So, is there any possible way to display individual cropped images.. also the number of cropped images might be in thousands so i want to use a loop to code their cropping mechanism

here is a part of the code attached.. thanks in advance ;)

for h=1:labelcount
    for i=1:r
        for j=1:c

             if labelledmap(i,j)==h
                    if i<ltop
                        ltop=i;
                    end
                    if i>lbottom
                        lbottom=i;
                    end
                    if j<lleft
                        lleft=j;
                    end
                    if j>lright
                        lright=j;
                    end
             end

        end
    end

    if ltop>5
        ltop=ltop-5;
    end
    if lbottom<r-5
        lbottom=lbottom+5;
    end
    if lleft>5
        lleft=lleft-5;
    end
    if lright<c-5
        lright=lright+5;
    end

    lwidth=lright-lleft;
    lheight=lbottom-ltop;

    ltoken=imcrop(input,[lleft ltop lwidth lheight]);
    figure('Name', 'Cropped Token'), imshow(ltoken);
    clearvars ltoken;
end
marsei
  • 7,691
  • 3
  • 32
  • 41
gagan1411
  • 25
  • 3
  • 1
    Try using a cell array. Initialise with `imlist={}`, append a new image with `imlist{end+1}=...` – Daniel Nov 26 '13 at 12:31
  • @gagan BTW, it is best [not to use `i` and `j` as variable names in Matlab](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab). – Shai Nov 26 '13 at 12:57
  • 1
    @DanielR in this case he knows in advance the number of elements in `imlist` - he should pre-allocate and not make `imlist` gors inside a loop - this is bad practice. – Shai Nov 26 '13 at 12:57
  • You are right. `imlist=cell(labelcount,1)` to initialise and `imlist{h}=...` to write. For some reason I missed the outer loop. – Daniel Nov 26 '13 at 13:56

1 Answers1

1
  1. you need to initialize ltop lbottom lleft and lright for each iteration of label h. I think this is the reason why you get the cropped images "glued" together.

  2. It is EXTREMELY inefficient to go through all the pixels for each and every one of your labels. Especially when you are expected to have many labels.
    Use regionprops to get the 'BoundingBox' property for each label.

Here's an example

st = regionprops( labelledmap, 'BoundingBox' );
imlist = cell( 1, numel(st) ); % pre-allocate
for ii=1:numel(st)
    r = st(ii).BoundingBox;
    % I understand you want to increase the BB by 5 pixels at each side:
    r(1:2) = r(1:2) - 5;  % start point moves -5
    r(3:4) = r(3:4) + 10; % width and height increases by 10
    imlist{ii} = imcrop( input, r );
end

I'm still a bit in shock by your code that explicitly loops through all pixels just for finding the bouding box. This is NOT the matlab way of doing things.
If you insist on NOT using regionprops here's a more Matlab-ish way of finding the ii-th bounding box:

imsk = (labeledmap == ii); % create a binary map with True for ii-th region
xFlat = any(imsk,1); % "flattening" imsk on the x-axis
lleft = find( xFlat, 1, 'first' );
lright = find( xFlat, 1, 'last' );
yFlat = any(imsk, 2);
ltop = find( yFlat, 1, 'first' );
lbottom = find( yFlat, 1, 'last' );

No loops at all over image coordinates.

Shai
  • 111,146
  • 38
  • 238
  • 371