Could you please help me to fit 2 circles so as to detect left and right half of breast?

3 views (last 30 days)
Beren Ac
Beren Ac on 13 Oct 2021
Commented: Beren Ac on 16 Oct 2021
Hi, I’d like to seperate as left half and right half of breast. But I couldn’t fit circle with Kasa or other circle fitting methods (Section b red circles of 3rd pic.). You can see my code and pics below. I could detect curves as half and left then i find center line of breast also i can seperate from the middle of breast with all body but All I need is to seperate left and right of breast without body like section c of 3rd photo.
Original Image
What my code has done
What I want
clc; % Clear the command window.
fprintf('Beginning to run %s.m ...\n', mfilename);
close all; % Close all figures (except those of imtool.)
clearvars;
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 20;
grayImage = rgb2gray(imread('DINAMIC-FRONTAL1.jpg'));
en = imsharpen(grayImage,'Radius',2,'Amount',1);
B = double(imgaussfilt(en,1.4));
% filtered_image = zeros(size(B));
% Mx = [-1 0 1; -1 0 1; -1 0 1];
% My = [-1 -1 -1; 0 0 0; 1 1 1];
% for i = 1:size(B, 1) - 2
% for j = 1:size(B, 2) - 2
%
% % Gradient approximations
% Gx = sum(sum(Mx.*B(i:i+2, j:j+2)));
% Gy = sum(sum(My.*B(i:i+2, j:j+2)));
%
% % Calculate magnitude of vector
% filtered_image(i+1, j+1) = sqrt(Gx.^2 + Gy.^2);
%
% end
% end
% filtered_image = uint8(filtered_image);
% figure(); imshow(filtered_image); title('Filtered Image');
% thresholdValue = 100; % varies between [0 255]
% output_image = max(filtered_image, thresholdValue);
% output_image(output_image == round(thresholdValue)) = 0;
ed=edge(B,'canny',0.3,0.5);
figure();
imshow(ed);
title('Initial Canny Edge', 'FontSize', fontSize);
bw1=bwareaopen(ed,10);
se = strel('disk',4);
bw=imdilate(bw1,se);
subplot(2, 2, 2);
imshow(bw);
title('Next Mask', 'FontSize', fontSize);
% Take largest 2 blobs.
bw = bwareafilt(bw, 2);
% Erase top half
[rows, columns] = size(bw);
bw(1:round(rows/2), :) = false;
% Skeletonize
bw = bwskel(bw);
% Find branchpoints.
[bpRows, bpColumns] = find(bwmorph(bw, 'branchpoints'))
% Erase branchpoints.
hold on;
for k = 1 : length(bpRows)
bw(bpRows(k), bpColumns(k)) = false;
plot(bpColumns(k), bpRows(k), 'r.', 'MarkerSize', 50);
end
% Erase any blobs with a centroid below 400.
props = regionprops(bw, 'Centroid');
xy = vertcat(props.Centroid)
% Don't keep the two with the highest centroid.
indexesToKeep = find(xy(:, 2) < 405);
% Extract all but the lowest two.
labeledImage = bwlabel(bw);
bw = ismember(labeledImage, indexesToKeep);
subplot(2, 2, 3);
imshow(bw);
axis('on', 'image');
title('Final Mask', 'FontSize', fontSize);
% Put the branchpoints back in to make each breast just one curve.
for k = 1 : length(bpRows)
bw(bpRows(k), bpColumns(k)) = true;
end
labeledImage = bwlabel(bw);
rp = regionprops('table',bw,'Centroid','Eccentricity','EquivDiameter','MajorAxisLength','MinorAxisLength'); rp.Radii = mean([rp.MajorAxisLength rp.MinorAxisLength],2) / 2;
rp([rp.Eccentricity] > 0.9,:) = []; rp(rp.EquivDiameter < 500 | rp.EquivDiameter > 800,:) = [];
% Find the left breast curve
[yr, xr] = find(labeledImage == 1);
% Find the right breast curve
[yl, xl] = find(labeledImage == 2);
subplot(2, 2, 4);
imshow(grayImage, 'border', 'tight' );
hold all
plot(xr, yr, 'r.', 'MarkerSize', 14);
plot(xl, yl, 'y.', 'MarkerSize', 14);
viscircles(rp.Centroid,rp.Radii,'EdgeColor','b');
% Find the midline
xMiddle = mean([max(xl), min(xr)]);
xline(xMiddle, 'Color', 'm', 'LineWidth', 4);
title('Breast Outlines Overlaid on Original Image', 'FontSize', fontSize);
leftHalf = grayImage(:, 1:xMiddle, :);
rightHalf=grayImage(:, xMiddle+1:end, :);
figure(); imshow(leftHalf);
figure(); imshow(rightHalf);

Accepted Answer

Matt J
Matt J on 13 Oct 2021
Seems to me that you don't need to fit a circle, but rather to find the minimum bounding circle. For that, you could try minboundcircle from this Eile Exchange contribution:
  2 Comments
Beren Ac
Beren Ac on 13 Oct 2021
Thank you for your help. It worked out @Matt J
I'm glad for your help and I can't thank you enough I tried something that you recommend but i couldn't get result because of me . I'm almost new in Matlab Image processing that is why i asked similar questions so many times @Image Analyst

Sign in to comment.

More Answers (1)

Image Analyst
Image Analyst on 13 Oct 2021
You just have to add the circle fitting code like I told you in your duplciate question:
% Find the leftmost point and don't include any points with y values above it.
[xMin, index] = min(xl);
keeperIndexes = yl > yl(index)
xl = xl(keeperIndexes);
yl = yl(keeperIndexes);
% Fit a circle to the left coordinates
[xCenter1, yCenter1, radius1, a1] = circlefit(xl, yl);
% Find the rightmost point and don't include any points with y values above it.
[xMax, index] = max(xr);
keeperIndexes = yr > yr(index)
xr = xr(keeperIndexes);
yr = yr(keeperIndexes);
% Fit a circle to the right coordinates
[xCenter2, yCenter2, radius2, a2] = circlefit(xr, yr);
% View the circles
centers = [xCenter1, yCenter1; xCenter2, yCenter2];
radii = [radius1; radius2];
figure;
imshow(grayImage, []);
xline(xMiddle, 'Color', 'm', 'LineWidth', 4);
viscircles(centers, radii, 'Color', 'g', 'LineWidth', 2)
Attached is the full program.
Obviously it doesn't hug the breasts because the breasts are not perfect circles.
  1 Comment
Beren Ac
Beren Ac on 16 Oct 2021
I can't Thank you enough @Image Analyst. I know but i think that I can union of breast curves and circle fitting but i couldn't do that. How can i union left curve and left circle fitting also right curve and right circle fitting then seperate them from middle line. Like sectinon b and c of image below
C is what i want.
% Find the left breast curve
[yr, xr] = find(labeledImage == 1);
% Find the right breast curve
[yl, xl] = find(labeledImage == 2);
% Find the left breast circle
x=xr;y=yr; hullflag=1;
[centerr,radiusr] = minboundcircle(x, y, hullflag);
x1=xl;y1=yl; hullflag1=1;
[centerl,radiusl] = minboundcircle(x1,y1,hullflag1);
% Find the leftmost point and don't include any points with y values above it.
[xMin, index] = min(xl);
keeperIndexes = yl > yl(index)
xll = xl(keeperIndexes);
yll = yl(keeperIndexes);
% Fit a circle to the left coordinates
[xCenter1, yCenter1, radius1, a1] = circlefit(xll, yll);
% Find the rightmost point and don't include any points with y values above it.
[xMax, index] = max(xr);
keeperIndexes = yr > yr(index)
xrr = xr(keeperIndexes);
yrr = yr(keeperIndexes);
% Fit a circle to the right coordinates
[xCenter2, yCenter2, radius2, a2] = circlefit(xrr, yrr);
% View the circles
center1= [xCenter1, yCenter1];
center2=[xCenter2, yCenter2];
radii = [radius1; radius2];
% Fit a circle to the left coordinates
% [xCenter1, yCenter1, radius1, a1] = circlefit(xl, yl);
% center3 = ((mean(xr)), (mean(yr)));
% radius = hypot(stdm(x, center[1]), stdm(y, center[2]);)
% Fit a circle to the right coordinates
% [xCenter2, yCenter2, radius2, a2] = circlefit(xr, yr);
% View the circles
centerl = [xCenter1, yCenter1];
centerr=[xCenter2, yCenter2];
poly1=polyshape(xCenter1, yCenter1);
poly2=polyshape(xl,yl);
polyout=union(poly1,poly2);
subplot(2, 2, 4);
imshow(grayImage, 'border', 'tight' );
hold all
plot(xr, yr, 'r.', 'MarkerSize', 4);
plot(xl, yl, 'y.', 'MarkerSize', 4);
% viscircles(centerr,radius2, 'Color', 'g', 'LineWidth', 2);
viscircles(center2,radius2, 'Color', 'g', 'LineWidth', 2);
viscircles(center1, radius1, 'Color', 'g', 'LineWidth', 2)
% Find the midline
xMiddle = mean([max(xl), min(xr)]);
xline(xMiddle, 'Color', 'm', 'LineWidth', 4);
title('Breast Outlines Overlaid on Original Image', 'FontSize', fontSize);
%Seperate middle line
Half = grayImage(:, 1:xMiddle, :);
rightHalf=grayImage(:, xMiddle+1:end, :);
figure(); imshow(leftHalf);
figure(); imshow(rightHalf);

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!