segmentation by marking points around the region

please can someone help me with a sample code of medical image segmentation by the method of marking points around the region to be segmented..... i marked few points around the region but dont know how to proceed.... please could someone reply.....

 Accepted Answer

Use roipoly() or roipolyold() and then poly2mask().

11 Comments

sir cud u plz show me how to convert the marked points to x and y coordinates....
[BW, x, y] = roipoly();
... As described in the documentation for roipoly.
sir i saw the function roipoly.... in that x and y coordinates are given as
x = [222 272 300 270 221 194];
y = [21 21 75 121 121 75];
BW = roipoly(I,x,y);
but the roi differs for each image.... so if i mark few points in the input image how to get its corresponding x and y value.... please do reply sir....
global inputImage
[filename pathname]=uigetfile('*.jpg','Select An Image');
inputImage=imread([pathname filename]);
[M N] = size(inputImage);
fig=figure('Units','normalized','Position',[0 0 1 1]);
figure(1);imshow(inputImage);
set(gcf,'Units','normal', 'outerposition',[0 0 1 1], 'menubar','none')
set(gca,'Visible', 'Off', 'Position',[0 0 1 1])
dcm_obj = datacursormode(fig);
set(dcm_obj,'DisplayStyle','datatip',...
'SnapToDataVertex','off','Enable','on')
c_info = getCursorInfo(dcm_obj);
[x,y] = ginput(10);
hold on;
plot(x,y,'rs','LineWidth',2,...
'MarkerEdgeColor','k',...
'MarkerFaceColor','g',...
'MarkerSize',8)
hold on
for i = 1:10
text(x(i),y(i),num2str(i),'FontSize',15,'fontweight','b','Color','white');
end
this is the code i used for marking points....
The coordinates returned for x and y by roipoly are for an array the same size as the image, and so are also array coordinates for the image itself. You do not have any other coordinate system for the image.
If you have images of different size, then it is not clear what coordinates you are looking for.
Note: ginput() will not necessarily return coordinates in the same form as roipoly() would. You would have to read the documentation for ginput().
Not sure if you still have a question. Why don't you try roipolyold() - even though it's "old" it's still there and it's what I always use. It doesn't ask for confirmation. And it lets you have a variable number of points instead of 10 like your ginput does.
I thought you were using ginput(), roipoly(), or roipolyold(). All of those can do it. Did you try them? I'm not sure what you want. Do you need an example of how to use them? (Keep in mind that we're not going to write an automatic medical image segmentation application for you - that's way way too much to ask of us.)
sir roipolyold()function is working sir.... but one thing when we select a portion that part is being cut from the image... i wanted to display that selected part in a figure... is it possible sir....
I=imread('abdo-ct-norm.jpg');
BW = ROIPOLYOLD(I);
imshow(BW);
using the above code the portion i selected will be display in white color and the remaining portion of the figure is black.... i wanted the region i selected to be displayed as it appears in input image and the remaining portion deleted.... that is like cutting a portion from a figure and pasting it in another figure.... please can u help me..
can anyone help me to find the function of mri brain image segmentation?

Sign in to comment.

More Answers (2)

See this demo:
% Demo to have the user freehand draw an irregular shape over
% a gray scale image, have it extract only that part to a new image,
% and to calculate the mean intensity value of the image within that shape.
% Also calculates the perimeter, centroid, and center of mass (weighted centroid).
% Change the current folder to the folder of this m-file.
if(~isdeployed)
cd(fileparts(which(mfilename)));
end
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 = hFH.getPosition;
% Now make it smaller so we can show more images.
subplot(2, 3, 1);
imshow(grayImage, []);
axis on;
drawnow;
title('Original Grayscale Image', 'FontSize', fontSize);
% Display the freehand mask.
subplot(2, 3, 2);
imshow(binaryImage);
axis on;
title('Binary mask of the region', 'FontSize', fontSize);
% Label the binary image and computer the centroid and center of mass.
labeledImage = bwlabel(binaryImage);
measurements = regionprops(binaryImage, grayImage, ...
'area', 'Centroid', 'WeightedCentroid', 'Perimeter');
area = measurements.Area
centroid = measurements.Centroid
centerOfMass = measurements.WeightedCentroid
perimeter = measurements.Perimeter
% Calculate the area, in pixels, that they drew.
numberOfPixels1 = sum(binaryImage(:))
% Another way to calculate it that takes fractional pixels into account.
numberOfPixels2 = bwarea(binaryImage)
% Get coordinates of the boundary of the freehand drawn region.
structBoundaries = bwboundaries(binaryImage);
xy=structBoundaries{1}; % Get n by 2 array of x,y coordinates.
x = xy(:, 2); % Columns.
y = xy(:, 1); % Rows.
subplot(2, 3, 1); % Plot over original image.
hold on; % Don't blow away the image.
plot(x, y, 'LineWidth', 2);
drawnow; % Force it to draw immediately.
% Burn line into image by setting it to 255 wherever the mask is true.
burnedImage = grayImage;
burnedImage(binaryImage) = 255;
% Display the image with the mask "burned in."
subplot(2, 3, 3);
imshow(burnedImage);
axis on;
caption = sprintf('New image with\nmask burned into image');
title(caption, 'FontSize', fontSize);
% Mask the image and display it.
% Will keep only the part of the image that's inside the mask, zero outside mask.
blackMaskedImage = grayImage;
blackMaskedImage(~binaryImage) = 0;
subplot(2, 3, 4);
imshow(blackMaskedImage);
axis on;
title('Masked Outside Region', 'FontSize', fontSize);
% Calculate the mean
meanGL = mean(blackMaskedImage(binaryImage));
% Put up crosses at the centriod and center of mass
hold on;
plot(centroid(1), centroid(2), 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(centerOfMass(1), centerOfMass(2), 'g+', 'MarkerSize', 20, 'LineWidth', 2);
% Now do the same but blacken inside the region.
insideMasked = grayImage;
insideMasked(binaryImage) = 0;
subplot(2, 3, 5);
imshow(insideMasked);
axis on;
title('Masked Inside Region', 'FontSize', fontSize);
% Now crop the image.
leftColumn = min(x);
rightColumn = max(x);
topLine = min(y);
bottomLine = max(y);
width = rightColumn - leftColumn + 1;
height = bottomLine - topLine + 1;
croppedImage = imcrop(blackMaskedImage, [leftColumn, topLine, width, height]);
% Display cropped image.
subplot(2, 3, 6);
imshow(croppedImage);
axis on;
title('Cropped Image', 'FontSize', fontSize);
% Put up crosses at the centriod and center of mass
hold on;
plot(centroid(1)-leftColumn, centroid(2)-topLine, 'r+', 'MarkerSize', 30, 'LineWidth', 2);
plot(centerOfMass(1)-leftColumn, centerOfMass(2)-topLine, 'g+', 'MarkerSize', 20, 'LineWidth', 2);
% Report results.
message = sprintf('Mean value within drawn area = %.3f\nNumber of pixels = %d\nArea in pixels = %.2f\nperimeter = %.2f\nCentroid at (x,y) = (%.1f, %.1f)\nCenter of Mass at (x,y) = (%.1f, %.1f)\nRed crosshairs at centroid.\nGreen crosshairs at center of mass.', ...
meanGL, numberOfPixels1, numberOfPixels2, perimeter, ...
centroid(1), centroid(2), centerOfMass(1), centerOfMass(2));
msgbox(message);

14 Comments

thank u sir... thank u so much....
Ahmed commented "mask by hand".
Unfortunately the comment does not appear to have enough context to be actionable.
Is it possible to use imcrop function to crop image in arbitrary shape, that is not necessary to be rectangle.
Not with imcrop(), but with imfreehand() you can. See attached demos.
I know this answer is old now but I had a question regarding it. The actions your code carries out are similar to things I need from a code I am attempting to construct. I need to create a ROI (possibly more than one) and then create a mask of this. I then need to apply that mask to multiple other matrices. The problem arises with what I am attempting to draw the ROI on. I need to create a ROI on a matrix plot (specifically a contourf plot). My question is, is there any way to create a region of interest on a plot? I have asked this question myself on the forums and Elysi kindly referred me here. I thought I would ask here as this appears to be your forte Image Analyst.
You can. Just simply display your matrix as an image with imshow(), then call imfreehand() and trace around the elements you want to include in your ROI. Attach your matrix and tell me what portion of it you want in the ROI if you don't know how to adapt my demos to your matrix.
I have just now been using roipoly on an image of my data. It is the same size as my matrices so I can use the mask developed on the image to apply it to the matrices. Does imfreehand allow the user to select more than one roi?
imfreehand() only allows one region. However you can put it into a loop where you are asking the user if they want to draw additional regions, and then OR any subsequent binary images into the main, cumulative one.
Would if loops be preferable for selecting multiple roi? If the user selects, start roipoly again. If so, my question would be how could I give the option to run roipoly again? I had thought of doing it with a uiwait message and prompt but would it be possible to do it by pressing the pushbutton that started it in the first place again? I may just create several push buttons, each one of which creates one ROI. A possible sticking point with this is that each of my ROI need to be distinct. I intend on calculating the sum inside each ROI and tabulate it
Kind of like this (untested):
again = true;
finalImage = false(rows, columns);
while again
thisRegion = roipoly;
% Add this in to the main one
finalImage = finalImage | thisRegion;
promptMessage = sprintf('Do you want to add another region?');
titleBarCaption = 'Continue?';
buttonText = questdlg(promptMessage, titleBarCaption, 'Yes', 'No', 'Yes');
if contains(buttonText, 'No', 'IgnoreCase', true)
again = false;
end
end
Thanks Image Analyst. I'm going to try this out now. I just had a question about some of the lines in your code.
What is the function of the line: finalImage = finalImage | thisRegion; and this line finalImage = false(rows, columns); ? I get an error when I try this code out resulting from the rows and columns variables. _ "Undefined function or variable 'rows'."_
I was also wondering, once i have created the various ROI, will they remain distinct once i add them to the mask?
Well you have to know how many rows your image is, right? So you did something like this:
[rows, columns, numberOfColorChannels] = size(yourImage);
Setting finalImage = false just initializes a blank, black image so that we can OR (add) individual blobs into it (the finalImage mask) with this line: finalImage = finalImage | thisRegion;
Once you OR a bunch of regions into an image, you now have a mask. I don't know what distinct means to you, but depending on how you do it, you can have the mask act as one mask, or you can do things with each individual blob in it, though you might be better off doing that inside the loop where you have that single blob only in one image by itself.
I did not set the size of my image. I know that it has 1024 rows as the image is x 1024 but I did not have a line of code like the one you detailed above. The code, spliced with yours and with the (rows, columns) line included looks like:
Folder = uigetdir('C:\Users\c13459232\Documents\MATLAB'); % selecta folder from which to select files
File = uigetfile(Folder); % select a file
Image = imread(File); % Read image
imshow(Image) % generate the image in a figure
again = true;
finalImage = false(rows, columns);
while again
thisRegion = roipoly;
% Add this in to the main one
finalImage = finalImage | thisRegion;
promptMessage = sprintf('Do you want to add another region?');
titleBarCaption = 'Continue?';
buttonText = questdlg(promptMessage, titleBarCaption, 'Yes', 'No', 'Yes');
if contains(buttonText, 'No', 'IgnoreCase', true)
again = false;
end
end
By distinct I mean that each ROI blob needs to be looked at separately. I am going to calculate the sum inside each ROI and tabulate them essentially as region 1, region 2, region 3...
When I added the line you suggested it generated an error: Undefined function 'contains' for input arguments of type 'char'. This could be due to contains being introduced in 2016. strfind is an alternative but it has a different output as far as I can tell.
Use
if strcmpi(buttonText, 'No')
To analyze all the blobs, if you want one of the measurements done by regionprops(), just pass in a labeled version of final image:
labeledImage = bwlabel(finalImage);
props = regionprops(labeledImage, 'all');
This will give you a structure with all kinds of measurements about each individual blob. You can get them out into a single array if you want, for example to get all the areas:
allAreas = [props.Area];
If you want the sum of all the gray levels instead of the sum of pixels (i.e. pixel count), use 'MeanIntensity' and pass in the gray scale image also:
props = regionprops(labeledImage, grayImage, 'Area', 'MeanIntensity');

Sign in to comment.

Thank you sir i found yours this algorithm / explanation very much helpful regarding my work to define ROI of a medical image and then get it as a separate image.

2 Comments

Hi, I would like to know why the size or the rectangle"BW" and "hpoly" are different in the following similar case
x = [4 10 10 4 4];
y = [4 4 10 10 4];
BW = poly2mask(x,y,20,20); %binary image
B = bwboundaries(BW);
b = B{1};
X = b(:, 1);
Y = b(:, 2);
hpoly = roipoly(BW,Y,X);
figure, imshow(BW)
figure, imshow(hpoly)
Any idea?
Thank you.
Meshoo
This doesn't seem to be related to Elysi's original question, so please post this as your own question in a separate discussion.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!