Could you please help me to fit 2 circles so as to detect left and right half of breast?
1 次查看(过去 30 天)
显示 更早的评论
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);
0 个评论
采纳的回答
Matt J
2021-10-13
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 个评论
Image Analyst
2021-10-13
This is like the second or third duplicate at least. I already found the outlines and showed him the faq where he could fit the data to a circle but apparently he just didn't want to try that, and decided to repost where he left off before.
更多回答(1 个)
Image Analyst
2021-10-13
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Get Started with Curve Fitting Toolbox 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!