I want to connect the ends of the white contour in the image to form a complete circle, eliminating the gaps.
    6 visualizaciones (últimos 30 días)
  
       Mostrar comentarios más antiguos
    
    FLOREA
 el 18 de Mzo. de 2025
  
    
    
    
    
    Comentada: Image Analyst
      
      
 el 19 de Mzo. de 2025
            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 comentarios
Respuesta aceptada
  Image Analyst
      
      
 el 18 de Mzo. de 2025
        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 comentarios
  Image Analyst
      
      
 el 19 de Mzo. de 2025
				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?
Más respuestas (1)
  Mathieu NOE
      
 el 18 de Mzo. de 2025
        
      Editada: Mathieu NOE
      
 el 18 de Mzo. de 2025
  
      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 comentarios
  Image Analyst
      
      
 el 18 de Mzo. de 2025
				Why not?  Is it because you insist on using bwskel?  If so, then why do you have to use that function?
Ver también
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!


