how can you determine the threshold that covers the functional area of the image in matlab?
5 views (last 30 days)
Show older comments
I have an image of a tissue and I want to make a mask of that tissue that is only of the functional area in the image (minus the long black tubular shapes which are blood vessels that I don't want to include in my measurements). How can I make this mask? Here's what i tried:
% Load image
img = imread('tissueimage.tif');
% Convert to grayscale
gray_img = rgb2gray(img);
% Threshold the image to create a binary mask
threshold = 8;
mask = gray_img > threshold;
% Remove small objects
min_size = 1000;
mask = bwareaopen(mask, min_size);
% Fill holes
mask = imfill(mask, 'holes');
% Erode and dilate the mask to remove noise and smooth edges
se = strel('disk', 5);
mask = imerode(mask, se);
mask = imdilate(mask, se);
% Display the original image and the resulting mask
figure;
subplot(1,2,1); imshow(img); title('Original Image');
subplot(1,2,2); imshow(mask); title('Functional Mask');
Here's what I have done so far:
- Preprocess the image
- Segment the tissue (removed background)
here's is where I'm unsure
Remove the blood vessels
i did try thresholding and picking numbers from 0-10 but 0, gets too many of the blood vessels and 10, I'm not sure if its all of the functional area or just the white pixels.
here's how i imagine it should look like (masked image). How can i get this?
Thanks pictures attached.
-L
3 Comments
Accepted Answer
Image Analyst
on 4 Mar 2023
@Laura just take your existing mask (top image) and invert it
mask = ~mask;
15 Comments
Image Analyst
on 9 Mar 2023
OK but how would you create the worm mask? Describe your thought process.
More Answers (1)
Image Analyst
on 11 Mar 2023
@Laura try this:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 16;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN TEST IMAGE
folder = [];
baseFileName = 'laura.jpeg';
fullFileName = fullfile(folder, baseFileName);
% Check if file exists.
if ~exist(fullFileName, 'file')
% The file doesn't exist -- didn't find it there in that folder.
% Check the entire search path (other folders) for the file by stripping off the folder.
fullFileNameOnSearchPath = baseFileName; % No path this time.
if ~exist(fullFileNameOnSearchPath, '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);
% Get the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
if numberOfColorChannels > 1
% It's not really gray scale like we expected - it's color.
fprintf('It is not really gray scale like we expected - it is color\n');
% Extract the blue channel.
grayImage = rgb2gray(grayImage);
end
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(3, 2, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Gray Scale Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Update the dimensions of the image.
% numberOfColorChannels should be = 1 for a gray scale image, and 3 for an RGB color image.
[rows, columns, numberOfColorChannels] = size(grayImage)
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get mask
mask = grayImage > 0;
subplot(3, 2, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
%--------------------------------------------------------------------------------------------------------
% Get Euclidean distance transform
edtImage = bwdist(mask);
subplot(3, 2, 3);
imshow(edtImage, []);
impixelinfo;
axis('on', 'image');
title('EDT Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
%--------------------------------------------------------------------------------------------------------
% Threshold the edt image to get the large black regions.
mask2 = edtImage > 8;
% The mask has sharp corners. OPTIONAL: if you want to smooth them out, blur and threshold.
windowWidth = 9;
mask2 = conv2(double(mask2), ones(windowWidth)/windowWidth^2, 'same') > 0.5;
% Looks like maybe we don't want blobs smaller than 1000 pixels. Remove those. (OPTIONAL)
mask2 = bwareaopen(mask2, 1000);
%--------------------------------------------------------------------------------------------------------
% Measure the areas of all the blobs.
props = regionprops(mask2, 'Area')
allAreas = sort([props.Area])
subplot(3, 2, 4);
imshow(mask2, []);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
drawnow;
%--------------------------------------------------------------------------------------------------------
% Plot the borders of all the blobs in the overlay above the original grayscale image
% using the coordinates returned by bwboundaries().
% bwboundaries() returns a cell array, where each cell contains the row/column coordinates for an object in the image.
subplot(3, 2, 5);
imshow(grayImage); % Optional : show the original image again. Or you can leave the binary image showing if you want.
% Here is where we actually get the boundaries for each blob.
boundaries = bwboundaries(mask2);
% boundaries is a cell array - one cell for each blob.
% In each cell is an N-by-2 list of coordinates in a (row, column) format. Note: NOT (x,y).
% Column 1 is rows, or y. Column 2 is columns, or x.
numberOfBoundaries = size(boundaries, 1); % Count the boundaries so we can use it in our for loop
% Here is where we actually plot the boundaries of each blob in the overlay.
hold on; % Don't let boundaries blow away the displayed image.
for k = 1 : numberOfBoundaries
thisBoundary = boundaries{k}; % Get boundary for this specific blob.
x = thisBoundary(:,2); % Column 2 is the columns, which is x.
y = thisBoundary(:,1); % Column 1 is the rows, which is y.
plot(x, y, 'r-', 'LineWidth', 2); % Plot boundary in red.
end
hold off;
caption = sprintf('%d Outlines, from bwboundaries()', numberOfBoundaries);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
5 Comments
Image Analyst
on 13 Mar 2023
Because I think you said you want to measure things about the bright blobs. So you can get a mask of those. It's not needed to get the mask of larger dark areas in order to measure the small white blobs.
See Also
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!