Clear Filters
Clear Filters

How to get the distance references of geometry and curvature of the object?

2 views (last 30 days)
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 Comments
Matt J
Matt J on 27 Nov 2023
Edited: Matt J on 27 Nov 2023
Why is there a chequerboard pattern in your image background? Can the image be retaken without it? Most of the effort in your code is devoted towards getting rid of it.
Rhandrey Maestri
Rhandrey Maestri on 27 Nov 2023
I do not know. I have not paid attention to that before. Now it would be difficult to retake these pictures.

Sign in to comment.

Answers (1)

Matt J
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
ans = 1×2
220 92
distance=abs(median(sborder(1).y)-median(sborder(4).y)) %distance ebtween top and bottom lines
distance = 180
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)
circ1 =
circularFit with properties: center: [161.2045 153.6687] radius: 86.6585
circ2=circularFit(XY2)
circ2 =
circularFit with properties: center: [259.8320 153.7851] radius: 72.6716
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
Image Analyst on 30 Nov 2023
What is showfit()? I've heard of the built-in viscircles but not showfit.
help viscircles
viscircles - Create circle This MATLAB function draws circles with specified centers and radii onto the current axes. Syntax viscircles(centers,radii) viscircles(ax,centers,radii) viscircles(___,Name=Value) h = viscircles(___) Input Arguments centers - Coordinates of circle centers two-column numeric matrix radii - Circle radii positive number | column vector ax - Axes in which to draw circles handle Name-Value Arguments EnhanceVisibility - Augment drawn circles with contrasting features to improve visibility true or 1 (default) | false or 0 Color - Color of boundary "red" (default) | RGB triplet | hexadecimal color code | color name | short color name LineStyle - Line style of circle edge "-" (default) | "--" | ":" | "-." | "none" LineWidth - Width of circle edge positive number | 2 (default) Output Arguments h - Circles drawn hggroup object Examples openExample('images/DrawLinesAroundBrightAndDarkCirclesInImageExample') openExample('images/ClearAxesBeforePlottingCirclesExample') See also Image Viewer, visboundaries, imfindcircles, imdistline, drawcircle Introduced in Image Processing Toolbox in R2012a Documentation for viscircles doc viscircles

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!