3

I'd like to manually draw multiple regions on an image to create a binary mask of the drawn regions (ground truth).

I attached the code to do it using imfreehand that does the job for one region, but once in release the mouse button, binary mask for that single region is displayed. Is there a way to draw multiple regions and then display the binary mask? (Calling imfreehand multiple times may not work because the number of regions varies with each image).

h= imfreehand();

h = imfreehand(gca);
setColor(h,'red');

position = wait(h); 
BW = createMask(h);
figure,imshow(BW);
axis on;

Thanks.

Shai
  • 111,146
  • 38
  • 238
  • 371
user3602648
  • 31
  • 1
  • 2

2 Answers2

2

You can loop until you get an empty mask - this will indicate that the user finished drawing all masks.
Let sz be the desired size of the output mask, then

totMask = false( sz ); % accumulate all single object masks to this one
h = imfreehand( gca ); setColor(h,'red');
position = wait( h );
BW = createMask( h );
while sum(BW(:)) > 10 % less than 10 pixels is considered empty mask
      totMask = totMask | BW; % add mask to global mask
      % you might want to consider removing the old imfreehand object:
      delete( h ); % try the effect of this line if it helps you or not.

      % ask user for another mask
      h = imfreehand( gca ); setColor(h,'red');
      position = wait( h );
      BW = createMask( h );
end
% show the resulting mask
figure; imshow( totMask ); title('multi-object mask');
Shai
  • 111,146
  • 38
  • 238
  • 371
  • Shai, thanks! This works. I deleted the delete(h) statement in your code as that would ensure user sees all the regions he has drawn. I would also like to give the user a chance to correct what he draws. As in once he draws something and realizes that region is not correct and he wants to redraw, I want to be able to delete that specific mask he specifies (by a right click may be?) and let him draw again. Can this be done? – user3602648 May 06 '14 at 03:09
  • 1
    Thank you Shai. This was useful for what I'm currently developing. +1. – rayryeng Sep 07 '16 at 16:35
0

As a complement to the answer given by @Shai, you can also use the input() function in Matlab to prompt the user for the total number of masks needed or simply as a yes/no question in a while loop. That is, either:

imshow(img,[]) %display image to determine number of masks needed
n = input('How many masks are needed? ')  %Ask user for number of masks needed
for i=1:n
    create multiple masks...
end

or

n=1;
while(n==1)
     create mask ...
     n = input('Need more masks? [0=No, 1=Yes] ')
end
Ghaul
  • 3,340
  • 1
  • 19
  • 24
  • Thanks Ghaul. The user actually wouldn't know how many regions exist even after looking at the image. So I just added a message - message1 = sprintf('Single left click when done'); %since while loop runs only when the number of pixels is more than 10 uiwait(msgbox(message1)); Can you also have a look at the comment I posted on the answer given by @Shai. – user3602648 May 06 '14 at 03:12