I cant locate the black region on my image using regionprops and imfindcircles.

6 views (last 30 days)
I cant locate the dark region shown on the image.
On the left I have the original image, on the right graytreshed and binarized image can be seen. However, I can't find the position and also the radius of the dark region. On the 2nd and 3rd image I provided the regionprops result. It finds many circles, but not the one needed.
Do I need an additional processing step before using regionprops? Any comment and suggestion is highly appreciated.
  3 Comments
Matt J
Matt J on 24 May 2023
Edited: Matt J on 24 May 2023
Is it supposed to be a perfect circle? One side of the region in imageprocessing4.jpeg looks rather flat.
Ali Aykut
Ali Aykut on 24 May 2023
Edited: Ali Aykut on 24 May 2023
This is a measurement from a fluorescent sample taken using a microscope. And the data is not always perfect sometimes the image has background and/or the sample has impurities. An inner or outer circle that is kind of a fit to the edge would be enough for tracking purposes of this dark region.

Sign in to comment.

Accepted Answer

Image Analyst
Image Analyst on 24 May 2023
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 = 18;
markerSize = 40;
%--------------------------------------------------------------------------------------------------------
% READ IN TEST IMAGE
folder = pwd;
baseFileName = 'imageprocessing.tif';
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);
% Display the image.
subplot(2, 2, 1);
imshow(grayImage, []);
impixelinfo;
axis('on', 'image');
title('Original Image', 'FontSize', fontSize, 'Interpreter', 'None');
% 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 max channel.
% grayImage = max(grayImage, [], 3);
% Extract the green channel.
grayImage = grayImage(:, :, 2);
end
% Maximize window.
g = gcf;
g.WindowState = 'maximized';
drawnow;
%--------------------------------------------------------------------------------------------------------
% Threshold to create mask of the dark spot.
lowThreshold = 0;
highThreshold = 3900;
% Interactively and visually set a threshold on a gray scale image.
% https://www.mathworks.com/matlabcentral/fileexchange/29372-thresholding-an-image?s_tid=srchtitle
% [lowThreshold, highThreshold] = threshold(lowThreshold, highThreshold, grayImage)
mask = grayImage >= lowThreshold & grayImage <= highThreshold;
% Take the largest blob only.
mask = bwareafilt(mask, 1);
subplot(2, 2, 2);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get the convex hull of the bright blobs to make the boundary smoother.
mask = bwconvhull(mask, "objects");
subplot(2, 2, 3);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image', 'FontSize', fontSize, 'Interpreter', 'None');
% Get the mean gray level.
meanBlobGrayLevel = mean(grayImage(mask));
caption = sprintf('Mean of region = %.1f gray levels.', meanBlobGrayLevel)
title(caption, 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get boundary of region and plot it over original image.
% 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(2, 2, 4);
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(mask);
% 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('Area = %d pixels with a threshold of %d.', nnz(mask), highThreshold);
fontSize = 15;
title(caption, 'FontSize', fontSize);
axis('on', 'image'); % Make sure image is not artificially stretched because of screen's aspect ratio.
Of course, the diameter depends greatly on what threshold you select. See my interactive threshold to visually set one.
That's how I decided on 3900, but it's a very gradual edge so it's really a judgment call.
  2 Comments
Image Analyst
Image Analyst on 25 May 2023
@Ali Aykut haven't heard from you. Does this work for you?
If this Answer solves your original question, then could you please click the "Accept this answer" link to award the answerer with "reputation points" for their efforts in helping you? They'd appreciate it. Thanks in advance. 🙂 Note: you can only accept one answer (so pick the best one) but you can click the "Vote" icon for as many Answers as you want. Voting for an answer will also award reputation points.

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 24 May 2023
You can threshold and then use imclearborder and then bwareafilt. If you need more help, attach the original image by itself.
Something like
mask = imclearborder(grayImage < someThreshold); % Get rid of blob touching the edges of the image.
mask = bwareafilt(mask, 1); % Take largest blob only.
% 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.
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(mask);
% 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.
  1 Comment
Ali Aykut
Ali Aykut on 24 May 2023
I followed the steps recomended but I couldn't have a major improvement on the result.
The dark region in the image gets smaller with time and my purpose is to locate its center and also find radius with time. I am attaching a single tif image from a stack. Thank you in advence for your help and suuport.
*I had to crop the image a litte to reduce its size(<5MB).

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!