How to get the distance references of geometry and curvature of the object?
1 view (last 30 days)
Show older comments
Dear members, I would be truly grateful if you could assist me in extracting automatically the distances indicated in the image and obtaining the curvature of its extreme points on the right and left. My goal now is to obtain the curvature of the object as it flows.
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1553122/image.png)
Could you please guide me on the correct approach for achieving this?
I have tried to obtain the distances but it was manual.
%%
clc
clear all
close all
% Load the image
I = imread('20000002002.bmp');
% Binarize
BW = imbinarize(I);
% Extract the ROI
BW = ~BW;
se = strel("disk", 5);
BW = imopen(BW, se);
BW = imclearborder(BW);
BW = bwareafilt(BW, 1);
BW = imfill(BW, "holes");
% Calculate the centroid
s = regionprops(BW, "Centroid");
% Calculate the extreme points
idx = any(BW);
pt1 = find(idx, 1);
pt2 = find(idx, 1, "last");
% Visualize the result
imshow(I)
hold on
% Adiciona uma linha vertical constante em x = 860
xline(860, "g", "X = 860", "FontSize", 18);
% Calcula a distância entre pt1 e 860
distancia_pt1_860 = abs(860 - pt1);
% Exibe as linhas e pontos
xline(pt1, "r", sprintf("X = %d", pt1), "FontSize", 18)
xline(pt2, "r", sprintf("X = %d", pt2), "FontSize", 18)
h = scatter(s.Centroid(1), s.Centroid(2), "r", "filled");
% Adiciona linhas horizontais com o centroide no meio delas
distancia_entre_linhas = 183;
linha_superior_y = s.Centroid(2) + distancia_entre_linhas/2;
linha_inferior_y = s.Centroid(2) - distancia_entre_linhas/2;
% Adiciona a linha superior
plot([pt1, pt2], [linha_superior_y, linha_superior_y], 'b', 'LineWidth', 1);
% Adiciona a linha inferior
plot([pt1, pt2], [linha_inferior_y, linha_inferior_y], 'b', 'LineWidth', 1);
% Adiciona os pontos extremos e o centroide
scatter([pt1, pt2, s.Centroid(1)], [linha_superior_y, linha_superior_y, s.Centroid(2)], "b", "filled");
% Adiciona os pontos extremos e o centroide
scatter([pt1, pt2, s.Centroid(1)], [linha_inferior_y, linha_inferior_y, s.Centroid(2)], "b", "filled");
% Exibe a distância entre pt1 e 860
disp(['Distância entre pt1 e x=860: ', num2str(distancia_pt1_860)]);
4 Comments
Answers (1)
Matt J
on 27 Nov 2023
Edited: Matt J
on 27 Nov 2023
I was able to do it with the help of some FEX downloads:
I'm not sure if it's a coincidence that the two circles intersect at the minimum dip point. You would know better than me, I'd imagine.
BW=~imbinarize(imread('https://www.mathworks.com/matlabcentral/answers/uploaded_files/1553107/20000002002.bmp'));
BW=BW(round(end/4):round(2*end/3),round(end/3):round(2*end/3));
BW=imfill(BW,'holes');
BW=imclose(imerode(BW,[1 0;0 1]),ones(2));
BW=bwareaopen(BW,30);
bullet=bwareafilt(BW,1);
bg=bwareafilt(bwlalphaclose(BW&~bullet,5),4);
sbullet=boundaryXY(bullet);
sborder=boundaryXY(bwmorph(bg,'skel',inf));
ydip=max(sborder(2).y);
xdip=mean(sborder(2).x(sborder(2).y==ydip));
[xdip,ydip] %Minimum Dip Point
distance=abs(median(sborder(1).y)-median(sborder(4).y)) %distance ebtween top and bottom lines
XY=[sbullet.x, sbullet.y]';
xmin=min(XY(1,:),[],2);
xmax=max(XY(1,:),[],2);
XY1=XY(:,XY(1,:)<=xmin+4);
XY2=XY(:,XY(1,:)>=xmax-4);
circ1=circularFit(XY1)
circ2=circularFit(XY2)
imshow(BW);hold on
showfit(circ1);
showfit(circ2);
scatter(xdip,ydip,'c','filled','SizeData',80);
hold off
function s=boundaryXY(bw)
B=bwboundaries(bw);
for i=1:numel(B)
s(i).x=B{i}(:,2);
s(i).y=B{i}(:,1);
end
end
9 Comments
Image Analyst
on 30 Nov 2023
help viscircles
Matt J
on 30 Nov 2023
It is a method defined for the circularFit class in this FEX fitting library,
See Also
Categories
Find more on Explore and Edit Images with Image Viewer App in Help Center and File Exchange
Products
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!