Creating masks of open lines with imfreehand and impoly ROI tools
2 views (last 30 days)
Show older comments
With both the imfreehand and impoly tools one can set the 'Closed' line property to false which allows for the creation of open non straight lines. Surprisingly, masks created with these tools using createMask are always closed even when the 'Closed' property is set to false. This appears to be a bug?
I would like to create masks of non straight lines which precludes using the imline tool. Any suggestions on how to achieve this given the stated issues with the imfreehand and impoly tools? Thanks for any assistance.
0 Comments
Accepted Answer
Teja Muppirala
on 30 Jul 2012
If I understand you correclty, you want to create an image of the line, without closing the curve. That's certainly doable.
I = imread('peppers.png');
imshow(I);
M = imfreehand(gca,'Closed',0);
F = false(size(M.createMask));
P0 = M.getPosition;
D = round([0; cumsum(sum(abs(diff(P0)),2))]); % Need the distance between points...
P = interp1(D,P0,D(1):.5:D(end)); % ...to close the gaps
P = unique(round(P),'rows');
S = sub2ind(size(I),P(:,2),P(:,1));
F(S) = true;
figure;
imshow(F);
4 Comments
More Answers (1)
Image Analyst
on 29 Jul 2012
A mask is an area. If you want lines as a mask, like just a one pixel wide path, then you'd have to set those pixels from the x,y coordinates that those functions return. If you want non-straight "lines" then use imfreehand to draw curves of arbitrary shape. Why do you want a "mask" of just a single pixel wide path anyway? You have the coordinates so why do you now need a binary image of those coordinates?
5 Comments
Image Analyst
on 29 Jul 2012
Edited: Image Analyst
on 29 Jul 2012
My very first responses addressed your initial questions. I said basically, that's not how they work. Then I gave you two workarounds (imline, with demo code, and imfreehand) to do what you want to do. So you can either do one of the workarounds and move on, or put in a feature request with the Mathworks and wait for some version in the future that may do it the way you think it should work.
You can try this imfreehand code below, but be aware that imfreehand doesn't give adjacent coordinates, particularly if you draw fast, so in that case you might have to us imline anyway (in between the coordinates that imfreehand gives you) to make sure there are no gaps in the drawn curve.
% Demo to have the user freehand draw an irregular shape over
% a gray scale image, and burn the curve points into the image.
clc; % Clear command window.
clear; % Delete all variables.
close all; % Close all figure windows except those created by imtool.
imtool close all; % Close all figure windows created by imtool.
workspace; % Make sure the workspace panel is showing.
fontSize = 16;
% Read in a standard MATLAB gray scale demo image.
folder = fullfile(matlabroot, '\toolbox\images\imdemos');
baseFileName = 'cameraman.tif';
% Get the full filename, with path prepended.
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% File doesn't exist -- didn't find it there. Check the search path for it.
fullFileName = baseFileName; % No path this time.
if ~exist(fullFileName, 'file')
% Still didn't find it. Alert user.
errorMessage = sprintf('Error: %s does not exist in the search path folders.', fullFileName);
uiwait(warndlg(errorMessage));
return;
end
end
grayImage = imread(fullFileName);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
set(gcf, 'Position', get(0,'Screensize')); % Maximize figure.
message = sprintf('Left click and hold to begin drawing.\nSimply lift the mouse button to finish');
uiwait(msgbox(message));
hFH = imfreehand();
% Create a binary image ("mask") from the ROI object.
binaryImage = hFH.createMask();
xy = int32(hFH.getPosition);
% Now make it smaller so we can show more images.
subplot(2, 2, 1);
imshow(grayImage, []);
axis on;
title('Original Grayscale Image', 'FontSize', fontSize);
% Display the freehand mask just for fun - we won't use binaryImage.
binaryImage = false(size(grayImage));
linearIndexes = sub2ind(size(grayImage), xy(:, 2), xy(:, 1));
binaryImage(linearIndexes) = true;
subplot(2, 2, 2);
imshow(binaryImage);
axis on;
title('Binary mask of the region', 'FontSize', fontSize);
% Display it.
subplot(2, 2, 3);
grayImage(linearIndexes) = 255;
imshow(grayImage);
axis on;
title('Grayscale Image with freehand curve burned in', 'FontSize', fontSize);
See Also
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!