Manually defining a non-rectangular ROI
Those of you who have worked with image processing tools have probably been wondering if a manual, freehand selection of a ROI is possible in MATLAB. This is an extremely useful tool, since there are many applications with ROIs, which should be very tightly defined in order to be efficiently masked. This is another area in which MATLAB doesn't fall short of competitive tools. In fact, there are two possible choices; a polygonal ROI defined by many points can be defined using roipoly
, while function imfreehand
can be used for accomplishing a totally free selection. Let's see how we can use them.
Using roipoly to make a mask
We will start with our three rock images in order to explain the process of making a mask using roipoly
. First, we will load, convert, and crop our image (to make our results more visible):
>> img = imread('3rocks.jpg'); >> rock = rgb2gray(img); >> rock = imcrop(rock)
Then, it is time to call roipoly
and define the corner points of our polygon:
>> mask = roipoly(rock);
Once we have finished selecting our points, we double-click on the ROI to save our result. Let's display the result in a new figure, to verify it worked:
>> figure,imshow(mask)
Success! The rock has been very accurately defined and our mask is probably better than anything we could generate using an automatic thresholding method. But what happens when we want even more freedom in our selection and do not wish to click on many points? Then we would have to use imfreehand
, as we will show next.
Using imfreehand to make a mask
Once again, for the sake of comparison, we will work with the three-rocks image. Without clearing our workspace (if we have, then we must type in the first three commands of the previous example and crop the image), we type in the following commands:
>> figure, imshow(rock); % Show image
>> h = imfreehand; % Call imfreehand, using a handle as output
>> pos = wait(h); % Save the positions of all points of the
selection
After the highlighted code in the second line, we are faced with the image and we can draw the region we want to isolate by keeping the left mouse button clicked and dragging the mouse. This is accomplished by using a handle for the output of imfreehand
. This handle is then used as an input to the wait
function, to block the MATLAB command line, finally outputting the positions of the points selected by the user with the imfreehand
function. More information on this little trick can be found at http://www.mathworks.com/help/images/ref/imfreehand.html.
When we are done defining the ROI, we let go of the mouse button and then double-click on it.
When this process is done, we type in the third command to save the row and column coordinates of all the points on the ROI perimeter in variable pos
. These coordinates must then be converted into a mask:
>> [rows,columns] = size(rock); % Get the size of the image >> mask_freehand = poly2mask(pos(:,1),pos(:,2),rows,columns); % Make mask >> figure, imshow(mask_freehand)
As we can see, our results are once again very precise and this technique also produces a smoother result with fewer sharp angles. Now, let's try to combine the various tools we have demonstrated into one function that can be used for erasing objects from an image.