From: Jim O'Doherty on
Hi matlab-ers,
Probably an easy one this, but I'm relatively new so here goes....
I've got a greyscale image where each pixel represents a number of counts. I want to outline an object in the image by clicking with the mouse, and output the total number of counts.
Is "impoly" with "imshow" the best way? I'd like to be able to do it with the imtool function since I need to adjust the contrast for the outlining procedure. How would I apply this ROI to output the counts?

Thanks
Jim
From: Image Analyst on
Jim O'Doherty:
See my freehand drawing demo. I posted it earlier today in fact. Be sure to join any lines split into two by the newsreader. You outline an area and it calculates the mean. You would just use sum() instead of mean() since your pixels represent "count" and you want to sum up the total count in the drawn area.

% 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 = 20;

% Read in standard MATLAB gray scale demo image.
grayImage = imread('cameraman.tif');
subplot(2, 2, 1);
imshow(grayImage, []);
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();
% Display the freehand mask.
subplot(2, 2, 2);
imshow(binaryImage);
title('Binary mask of the region', 'FontSize', fontSize);

% 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, 2, 1); % Plot over original image.
hold on; % Don't blow away the image.
plot(x, y, 'LineWidth', 2);

% 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, 2, 3);
imshow(burnedImage);
title('New image with mask burned into image', 'FontSize', fontSize);

% Mask the image and display it.
% Will keep only the part of the image that's inside the mask, zero outside mask.
maskedImage = grayImage;
maskedImage(~binaryImage) = 0;
subplot(2, 2, 4);
imshow(maskedImage);
title('Masked Image', 'FontSize', fontSize);

% Calculate the mean
meanGL = mean(maskedImage(binaryImage));

% Report results.
message = sprintf('Mean value within drawn area = %.3f\nNumber of pixels = %d\nArea in pixels = %.2f', ...
meanGL, numberOfPixels1, numberOfPixels2);
msgbox(message);
From: Jim O'Doherty on
Thank you for that, this is exactly what I wanted to do.
Also, if I already have the X,Y coordinates of an ROI determined from some other program, how would I apply these to the image in Matlab? Would I still have to make a binary image and mask?

Jim


"Image Analyst" <imageanalyst(a)mailinator.com> wrote in message <i2qd3j$jrk$1(a)fred.mathworks.com>...
> Jim O'Doherty:
> See my freehand drawing demo. I posted it earlier today in fact. Be sure to join any lines split into two by the newsreader. You outline an area and it calculates the mean. You would just use sum() instead of mean() since your pixels represent "count" and you want to sum up the total count in the drawn area.
>
> % 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 = 20;
>
> % Read in standard MATLAB gray scale demo image.
> grayImage = imread('cameraman.tif');
> subplot(2, 2, 1);
> imshow(grayImage, []);
> 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();
> % Display the freehand mask.
> subplot(2, 2, 2);
> imshow(binaryImage);
> title('Binary mask of the region', 'FontSize', fontSize);
>
> % 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, 2, 1); % Plot over original image.
> hold on; % Don't blow away the image.
> plot(x, y, 'LineWidth', 2);
>
> % 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, 2, 3);
> imshow(burnedImage);
> title('New image with mask burned into image', 'FontSize', fontSize);
>
> % Mask the image and display it.
> % Will keep only the part of the image that's inside the mask, zero outside mask.
> maskedImage = grayImage;
> maskedImage(~binaryImage) = 0;
> subplot(2, 2, 4);
> imshow(maskedImage);
> title('Masked Image', 'FontSize', fontSize);
>
> % Calculate the mean
> meanGL = mean(maskedImage(binaryImage));
>
> % Report results.
> message = sprintf('Mean value within drawn area = %.3f\nNumber of pixels = %d\nArea in pixels = %.2f', ...
> meanGL, numberOfPixels1, numberOfPixels2);
> msgbox(message);
From: ImageAnalyst on
Jim:
You would pass those coordinates in to the poly2mask() function to
create the binary mask. The best way to proceed would still be
masking. There are some ROI-based processing options in MATLAB but
not really what you'd think (see the help). They still involve
creating a mask.
ImageAnalyst