How to get the distance references of geometry and curvature of the object?
1 次查看(过去 30 天)
显示 更早的评论
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 个评论
回答(1 个)
Matt J
2023-11-27
编辑:Matt J
2023-11-27
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 个评论
Image Analyst
2023-11-30
help viscircles
Matt J
2023-11-30
It is a method defined for the circularFit class in this FEX fitting library,
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!