I want to connect the ends of the white contour in the image to form a complete circle, eliminating the gaps.
조회 수: 14 (최근 30일)
이전 댓글 표시
Hi!
In this image, I want to connect the ends of the white contour to form a complete circle. Currently, there is a break in its structure, and my goal is to detect the endpoints and link them to obtain a closed shape. I want to use the bwskel function in MATLAB.

img = imread('imag5_Seg.png');
bw = imbinarize(img);
bw = logical(bw);
schelet = bwskel(bw);
figure();
imshow(schelet);
댓글 수: 0
채택된 답변
Image Analyst
2025년 3월 18일
Here's another way:
%-----------------------------------------------------------------
% Read in and prepare the sample image.
binaryImage = imread('ring gap.png');
[rows, columns, numberOfColorChannels] = size(binaryImage)
% It's RGB so convert to binary.
if numberOfColorChannels > 1
binaryImage = binaryImage(:, :, 1) > 0;
end
% The first 11 lines in the supplied sample image are not zero for some reason. Erase them.
binaryImage(1:11, :) = false;
% Save the original binary image.
originalBinaryImage = binaryImage;
% Erase bottom half to give us two blobs
binaryImage(round(columns/2) : end, :) = false;
% Make sure there are only two blobs. Take the biggest 2.
binaryImage = bwareafilt(binaryImage, 2);
% Label the image so that each blob has a unique ID %
[labeledImage, numBlobs] = bwlabel(binaryImage);
imshow(labeledImage, []);
axis('on', 'image');
%-----------------------------------------------------------------
% EDGE LINKING CODE
% Find the rows and columns of blob #1
[rows1, cols1] = find(ismember(labeledImage, 1));
% Find the rows and columns of blob #2
[rows2, cols2] = find(ismember(labeledImage, 2));
% Find the distance between all pixels in blob1 and all pixels in blob2
distances = pdist2([cols1, rows1], [cols2, rows2]);
% Find the min distance
minDistance = min(distances, [], 'all')
% Find the index where the min distance occurs
[mRow, mCol] = find(distances == minDistance)
% Get the coordinates of where that is.
x1 = cols1(mRow)
y1 = rows1(mRow)
hold on;
% plot(x1, y1, 'm.', 'MarkerSize', 30) % Plot magenta spot at the first point.
x2 = cols2(mCol)
y2 = rows2(mCol)
% plot(x2, y2, 'c.', 'MarkerSize', 30) % Plot cyan spot at the second point.
% Draw a line in the overlay between the endpoints.
plot([x1, x2], [y1, y2], 'r-', 'LineWidth', 3)
%-----------------------------------------------------------------
% BURN LINE INTO ORIGINAL IMAGE.
% If you have the Computer Vision Toolbox, use insertLine.
% If you don't, use linspace to get the 9-connected coordinates and then a loop to burn in the pixels.
numPixels = round(minDistance * 1.5); % Make sure we have enough sample points to not have any gaps.
x = round(linspace(x1, x2, numPixels));
y = round(linspace(y1, y2, numPixels));
% Loop over them, setting pixels in the original image.
for k = 1 : numPixels
originalBinaryImage(y(k), x(k)) = true;
end
% Display the final image.
figure;
imshow(originalBinaryImage);
title('Final Edge L:inked Image', 'FontSize', 20);
Sorry it doesn't look connected here in the web browser, but trust me, it really is. If you do it in MATLAB and then zoom in, you'll see the line connecting the gap is a continuous 8-connected line of pixels.
If you want the line a lot thicker, then write the line to a totally blank image, use imdilate to thicken it as much as you want, and then OR that back in to your original image.
댓글 수: 2
Image Analyst
2025년 3월 19일
I'm not sure why the skull region must be closed. Why should whether it's closed or not affect your segmentation of the brain matter and the bright or dark region at the center of the brain?
추가 답변 (1개)
Mathieu NOE
2025년 3월 18일
편집: Mathieu NOE
2025년 3월 18일
hello
sorry , this is a "no image processing" code - it may or may not correspond to your needs , but it does the job !
hope it helps
you will have to download this Fex submission for smoothing (I like it very much) but yiu ca of course use another smoother
result :

code :
%% load file
file_name='image.png';
img=imread(file_name);
if size(img,3)==3
img=rgb2gray(img);
end
% binarize image
outpic = zeros(size(img));
ind = find(img>128);
outpic(ind) = 1;
[y,x] = ind2sub(size(img),ind); % get x,y points coordinates of the white area
%% method 1
centroid_x = mean(x);
centroid_y = mean(y);
[theta,r] = cart2pol(x-centroid_x,y-centroid_y);
% sort theta in ascending order
[theta,ind] = sort(theta);
r = r(ind);
% remove duplicates
[theta,IA,IC] = unique(theta);
r = r(IA);
% take the average of r within an angle of range dt (if no data then NaN output)
Npoints = 100;
theta_new = linspace(min(theta),max(theta),Npoints);
dt = mean(diff(theta_new));
for k = 1:Npoints
ind = (theta>=theta_new(k)-dt/2) & (theta<theta_new(k)+dt/2);
if isempty(ind)
r_new(k) = NaN;
else
r_new(k) = mean(r(ind));
end
end
% replace / interpolate the NaN values
r_new = fillmissing(r_new,'spline');
% convert to cartesian
[xn,yn] = pol2cart(theta_new,r_new);
% add back centroid info
xn = xn + centroid_x;
yn = yn + centroid_y;
% smoothing (if needed)
Y = {xn,yn};
[zz,s,exitflag] = smoothn(Y,10);
xn = zz{1};
yn = zz{2};
% closing the curve
xn(end+1) = xn(1);
yn(end+1) = yn(1);
%% final plot
figure(1),
imshow(outpic)
hold on
plot(xn,yn,'r','linewidth',2);
hold off
댓글 수: 2
Image Analyst
2025년 3월 18일
Why not? Is it because you insist on using bwskel? If so, then why do you have to use that function?
참고 항목
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!