Combine impoly and imfreehand?

Hello,
for research I'm trying to draw a closed shape by hand on an anatomic image using a pen tablet. I've tried impoly and imfreehand for drawing but both have their pros and cons. With impoly I can accurately cover (fairly) straight distances but it gets troublesome in the nooks and crannies. With imfreehand these nooks and crannies are easy to navigate but not being able to move my hand easily (lifting the pen will close the shape) mostly ruins the drawn shape.
What I'm looking for is a way to draw like imfreehand but being able to lift the pen, move it and click for a straight line like impoly and then being able to draw again. In the end the shape should be closed, so like impoly it'd be nice to click a button and close the shape.
I've looked at a couple of uploaded files but haven't quite found what I'm looking for. Does anyone know of an existing file, maybe even one from matlab itself that I overlooked or a user uploaded one that might be useful?
Thanks in advance, Rik

Answers (3)

Hi,
So I had the same problem as you. I found a quick way to solve the problem. basically what you need to do is call imfreehand(gca,'closed',0) This allows you to draw unclosed boundaries. Then all you need to do is put that in a while loop with a ginput. when the person presses down with the pen, ginput will give you a unique decimal value. Then all you need to down is store the position values and call poly2mask to make a mask out of the position values
So your code should look something like this
while loop
freehand = imfreehand(gca,'closed',0)
[~,~,key] = ginput(1)
if key ==1
temp_pos = getposition(freehand);
end
end
mask = poly2mask();%you will need to fill this in
This should be enough. The rest is just checking for errors as there are a lot of cases you should consider when using imfreehand.
hope this helps
Rik
Rik on 11 Apr 2011
Hello,
thanks for replying, but maybe I'm not seeing how to use this? I had some errors (matlab 2008a) so I'll post what I did. basically I created an 'infinite' while loop and substituted x and y for the ~ since those gave errors. Now I can draw the first line, and when I release the mouse I get a position matrix back. But then starting to draw again doesn't work in the way I hoped it would. Now I have to make 2 mouse clicks to start drawing again and I only get the position from the first click back as 1 coordinate via ginput...? Also there's a gap between the lines, so calculating a surface is not possible.
while 1<2
freehand = imfreehand(gca,'closed',0)
[x,y,key] = ginput(1)
if key ==1
temp_pos = getPosition(freehand);
end
end
I guess i didn't really make my post really good. The loops shouldn't be infinite. You should stop looping when the user wants to. ie when they press 'y'.
I don't know why you can't remove x,y. I'm running 2010a and it works fine.
so the thing with this method is that you need to store all the values every time you lift your hand off(see code below).
and you can't remove the fact that you are going to have to make two clicks before you can redraw. That's just how this method works, but the fact that you get the first clicks position is odd. It should give you the second clicks position because the first one is just to tell ginput to recurse.
So the two values that I save from my code are allpoints and mask. allpoints is basically what impoly is. just the minimal number of points to regerenate the ROI. mask contains a pixel by pixel uint8 array of the ROI.
This should be more extensive. I've also copied a portion of my code that is relevant in this case. Hope this helps
loop =1;
counter = 1; %keeps track of how many times the user lifts the pen off the screen
while loop
freehand = imfreehand(gca,'closed',0);
if isempty(freehand)
allpoints = -1;
maskindex = -1;
mask = -1;
return
end
[~,~,key] = ginput(1);
if key == 121 %y
loop = 0;
elseif key == 110 %n
delete(freehand);
elseif key == 1 %continue to draw
temp_pos = getPosition(freehand);
if (counter == 1)
pos = temp_pos;
else
pos = [pos;temp_pos]; %#ok<AGROW>
end
counter = counter +1;
else
end
end
% get points that make up drawn boundary
temp_pos = getPosition(freehand);
if (counter == 1)
pos = temp_pos;
else
pos= [pos;temp_pos]; %#ok<AGROW>
end
pos = [pos;pos(1,:)];%#ok<AGROW> %this will close the polygon
mask = poly2mask(pos(:,1),pos(:,2),imgsize(1),imgsize(2));
end

1 Comment

Hi I have seen the post to combine imfreehand and impoly. I am also facing the problem that i am not able to create the mask after selecting the ROI with imfreehand. Please help!

Sign in to comment.

Asked:

Rik
on 24 Feb 2011

Community Treasure Hunt

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

Start Hunting!