Identifying blobs and area filtering

조회 수: 11 (최근 30일)
Jason
Jason 2023년 1월 22일
댓글: Jason 2023년 1월 25일
Hello, Im trying to identify the centres of the drops in the image below. Although in each drop there is a bright area, I dont care about this.
My analysis fails when the drop in the middle picture (binary) touches the large white circle (at the green line).
1: How can I get that last drop included thats touching the boundary
Here is my code.
IM=getimage(app.UIAxes);
pos=myfigure(app,1450,520); %my own function
figA=figure('position',pos);
m = uimenu(figA,Label="My Save As");
m.MenuSelectedFcn = @app.mysavefunc;
ax1=subplot(1,3,1);
myImagesc(app,ax1,IM); %My version of ImageSc
title(ax1,'Raw Image');
%Use adaptive thresholding as varying background
BW = imbinarize(IM,'adaptive','ForegroundPolarity','dark','Sensitivity',0.4);
BW = imcomplement(BW);
ax2=subplot(1,3,2);
myImagesc(app,ax2,BW);
title(ax2,'Imbinarise');
ax3=subplot(1,3,3);
BW=imclearborder(BW); %Clear up borders
BW = bwareafilt(BW,[5000 100000]); % Make sure no small areas are passed
keep = bwareafilt(BW,10); % Allow upto 10 largest objects to be kept
keep = imfill(keep,"holes"); % Fill any holes
myImagesc(app,ax3,keep);
title(ax3,'bwareafilt');
S = regionprops(keep, 'Area','Centroid')
[sy,~]=size(S)
centroids=S.Centroid
hold(ax2,'on');
% cl = {'r+','b+','m+','r*','b*','m*','c+','c*'};
for i=1:sy
xc=S(i).Centroid(:,1); yc=S(i).Centroid(:,2);
ReportMessage(app,['Area ',num2str(i),' = ',num2str(S(i).Area),', xc=',num2str(xc,'%.1f'), ', yc=',num2str(yc,'%.1f')])
plot(ax2,xc,yc,'r+'); % plot(ax2,xc,yc,cl{i});
end
Thanks for any help
  댓글 수: 2
Matt J
Matt J 2023년 1월 23일
I suggest attaching the input image IM in a .mat file, so that we can play with it.
Jason
Jason 2023년 1월 23일
편집: Jason 2023년 1월 24일
Hi Matt, here you go.

댓글을 달려면 로그인하십시오.

채택된 답변

Image Analyst
Image Analyst 2023년 1월 24일
Try the attached.
% 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 = 'im.png';
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
%--------------------------------------------------------------------------------------------------------
% READ IN BACKGROUND IMAGE
folder = [];
baseFileName = 'im background.png';
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
backgroundImage = imread(fullFileName);
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 3, 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;
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 3, 2);
imshow(backgroundImage, []);
impixelinfo;
axis('on', 'image');
title('Background Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Divide the two
correctedImage = double(grayImage) ./ double(backgroundImage);
%--------------------------------------------------------------------------------------------------------
% Display the image.
subplot(2, 3, 3);
imshow(correctedImage, []);
impixelinfo;
axis('on', 'image');
title('Background Corrected Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Display histogram
subplot(2, 3, 4);
histogram(correctedImage);
grid on;
title('Histogram of Background Corrected Image', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Threshold to create mask
mask = ~(correctedImage >= 0.9 & correctedImage <= 1.1);
% Get rid of blobs touching the border.
mask = imclearborder(mask);
% Take 6 largest blobs.
mask = bwareafilt(mask, 6);
% Fill the blobs.
mask = imfill(mask, 'holes');
subplot(2, 3, 5);
imshow(mask);
impixelinfo;
axis('on', 'image');
title('Mask Image with Centroids Marked', 'FontSize', fontSize, 'Interpreter', 'None');
%--------------------------------------------------------------------------------------------------------
% Get the areas, diameters, and centroids.
props = regionprops(mask, 'Area', 'Centroid', 'EquivDiameter');
allAreas = [props.Area]
allDiameters = [props.EquivDiameter]
xy = vertcat(props.Centroid);
% Plot centroids on image.
xCentroids = xy(:, 1);
yCentroids = xy(:, 2);
hold on;
plot(xCentroids, yCentroids, 'r+', 'LineWidth', 3, 'MarkerSize', 20)
  댓글 수: 5
Image Analyst
Image Analyst 2023년 1월 25일
I have no idea where the boundaries are. You might have to manually trace it. See attached demos.
Jason
Jason 2023년 1월 25일
Yep, I guessed it might be too difficult, but thanks anyway for sharing your examples
Jason

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

Image Analyst
Image Analyst 2023년 1월 23일
I would try to get an image with no drops in it and then do a background correction by dividing by it. Then your global threshold will work better. See attached background correction demo.
If you need more help, attach your droplets image and your background image without any droplets in it with the paperclip icon.

카테고리

Help CenterFile Exchange에서 Image Segmentation and Analysis에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by