Identifying the circle that fits the outer white pixels in a binary image (or make external mask)
3 Ansichten (letzte 30 Tage)
Ältere Kommentare anzeigen
Dyhia Bouhadjra
am 27 Mär. 2020
Bearbeitet: Dyhia Bouhadjra
am 1 Apr. 2020
Hi all,
I want to process a series of images similar to the attached one in order to measure their porosities: V_pores / V_total. For my case, in a 2D context, V_total is the surface of circle containing all pores. It is important to know that the radius and center of the circle changes, and also many circular shapes can be identified in between, however, I am only interested, at this moment, in measuring the general surface of the circle (Vt).
Alernatively, I would be interested in applying a mask to the image. But it seems to be more difficult.
Any help would be appreciated. Many thanks.
0 Kommentare
Akzeptierte Antwort
KSSV
am 27 Mär. 2020
I = imread("SampleXRmorph.PNG");
[y,x] = find(I) ;
% Get center of cricle
C = [mean(x) mean(y)] ;
% GEt raidus
d = sqrt((C(1)-x).^2+(C(2)-y).^2) ;
R = max(d) ;
% plot circle
th = linspace(0,2*pi) ;
xc = C(1)+R*cos(th) ;
yc = C(2)+R*sin(th) ;
%
imshow(I)
hold on
plot(xc,yc,'r')
9 Kommentare
Weitere Antworten (1)
Image Analyst
am 29 Mär. 2020
Bearbeitet: Image Analyst
am 29 Mär. 2020
Sorry I didn't see this earlier, but anyway...
How I'd solve it is
- Use bwconvhull() to get a convex hull of all the blobs.
- Uuse imerode() to shrink that a certain amount to get a smaller circular blob.
- Use the eroded image to erase every blob in the interior so you have only the outer blobs.
- If you need a perfect circle, call regionprops(mask, 'Centroid') to get a list of (x,y) coordinates.
- Use the FAQ to fit a circle through the centroids.
% Initialization steps.
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
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 short g;
format compact;
fontSize = 15;
mask = imread('morequestion.png');
imshow(mask);
if ndims(mask) > 2
mask = mask(:, :, 1); % Take red channel
end
mask2 = bwconvhull(mask, 'union');
se = strel('disk', 20, 0);
smallMask = imerode(mask2, se);
mask3 = mask & ~smallMask;
props = regionprops(mask3, 'Centroid');
xy = vertcat(props.Centroid);
x = xy(:, 1);
y = xy(:, 2);
[xc,yc,R,a] = circfit(x,y);
viscircles([xc, yc], R);
fprintf('Done running %s.m ...\n', mfilename);
function [xc,yc,R,a] = circfit(x,y)
%CIRCFIT Fits a circle in x,y plane
%
% [XC, YC, R, A] = CIRCFIT(X,Y)
% Result is center point (yc,xc) and radius R. A is an optional
% output describing the circle's equation:
%
% x^2+y^2+a(1)*x+a(2)*y+a(3)=0
% by Bucher izhak 25/oct/1991
n=length(x); xx=x.*x; yy=y.*y; xy=x.*y;
A=[sum(x) sum(y) n;sum(xy) sum(yy) sum(y);sum(xx) sum(xy) sum(x)];
B=[-sum(xx+yy) ; -sum(xx.*y+yy.*y) ; -sum(xx.*x+xy.*y)];
a=A\B;
xc = -.5*a(1);
yc = -.5*a(2);
R = sqrt((a(1)^2+a(2)^2)/4-a(3));
end
Adapt as needed.
5 Kommentare
Image Analyst
am 31 Mär. 2020
To get the area of the white in the mask, I'd do
numWhitePixels = nnz(mask)
% Now to get the area of the holes
holesImage = imclearborder(~mask);
imshow(holesImage);
numHolePixels = nnz(holesImage)
Siehe auch
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!