How to get the distance references of geometry and curvature of the object?
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
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.
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 commentaires
Réponses (1)
Matt J
le 27 Nov 2023
Modifié(e) : Matt J
le 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 commentaires
Image Analyst
le 30 Nov 2023
help viscircles
Matt J
le 30 Nov 2023
It is a method defined for the circularFit class in this FEX fitting library,
Voir également
Produits
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!