Search code examples
matlabimage-processingmatlab-cvst

Extracting boundaries from an image manually and preventing overlap of points selected


I am trying to import the image boundaries into CAD modeling software. For doing that I am manually selecting the boundaries from this image. The code I am using is the following:

I = imread('image.jpg'); %image file name
imshow(I);
uiwait(msgbox('Left click to choose points. Right click to exit')); 

n = 0;
while true
   [x, y, button] = ginput(1);hold on;
   if isempty(x) || button(1) ~= 1; break; end
   n = n+1;
   x_n(n) = x; % save all points you continue getting
   y_n(n) = y;
   plot(x,y,'-o',...
    'LineWidth',2,...
    'MarkerEdgeColor','k',...
    'MarkerFaceColor',[.49 1 .63],...
    'MarkerSize',10);
end
figure;
x_n=x_n';
y_n=y_n';
plot(x_n,y_n);
A=[x_n,y_n];

Selecting points on the boundaries as shown by this image give the following outcome in CAD software model. The overlap in the boundaries is because of the way lines are drawn in CAD software as shown below:

s1.Line(point1=(-0.131218,39.556604),point2=(1.762436,40.503431))
s1.Line(point1=(1.762436,40.503431),point2=(4.602916,38.136364))
s1.Line(point1=(4.602916,38.136364),point2=(9.337050,31.035163))
s1.Line(point1=(9.337050,31.035163),point2=(11.230703,23.460549))
s1.Line(point1=(11.230703,23.460549),point2=(14.544597,17.779588))
s1.Line(point1=(14.544597,17.779588),point2=(15.491424,12.572041))
s1.Line(point1=(15.491424,12.572041),point2=(16.438250,6.417667))
s1.Line(point1=(16.438250,6.417667),point2=(17.385077,2.156947))
s1.Line(point1=(17.385077,2.156947),point2=(21.645798,5.944254))
s1.Line(point1=(21.645798,5.944254),point2=(26.853345,8.784734))
s1.Line(point1=(26.853345,8.784734),point2=(31.114065,11.625214))
s1.Line(point1=(31.114065,11.625214),point2=(35.848199,13.045455))
s1.Line(point1=(35.848199,13.045455),point2=(40.582333,14.939108))

Is there a way where I can prevent the overlapping during selection by pausing the selection? Or any other suggestion on how to get the model made efficiently? I had tried using image processing to determine the boundaries. But it was beyond me to think something about converting the image coordinates into a CAD software model.


Solution

  • Possible solution is creating a polygon out of the selected points, and not adding selected point to x_n, y_n if there are lines crossings.

    The code uses polyshape function for creating a polygon object:

    clearvars
    
    I = imread('image.jpg'); %image file name
    imshow(I);
    uiwait(msgbox('Left click to choose points. Right click to exit')); 
    
    warning('Off', 'MATLAB:polyshape:repairedBySimplify'); %Disable warning "Polyshape has duplicate vertices, intersections..."
    
    n = 0;
    h_pgon = [];
    while true
        [x, y, button] = ginput(1);hold on;
        if isempty(x) || button(1) ~= 1; break; end
    
        n = n+1;
    
        %Save points to temporary arrays
        tmp_x_n(n) = x; % save all points you continue getting
        tmp_y_n(n) = y;
    
        is_overlapping = false;
    
        if n > 2
            %Check if there is "overlapping during selection":
    
            %Creates a polygon object
            pgon = polyshape(tmp_x_n, tmp_y_n);
    
            if (pgon.NumRegions > 1) || (pgon.NumHoles > 0)
                %There are intersections, so don't add the new x, y to x_n, y_n.
                disp('Overlapping!'); %Print "Overlapping!" for testing.
                is_overlapping = true;
                n = n - 1;
            end
        end
    
        if ~is_overlapping
            %There is no overlapping - copy tmp_x_n, tmp_y_n to x_n, y_n.
            x_n = tmp_x_n;
            y_n = tmp_y_n;
    
            plot(x,y,'-o',...
                'LineWidth',2,...
                'MarkerEdgeColor','k',...
                'MarkerFaceColor',[.49 1 .63],...
                'MarkerSize',10);        
    
            %Plot polygon for testing
            if n > 2
                if isobject(h_pgon), delete(h_pgon);end %Delete previouse polygon.
                h_pgon = plot(pgon);
            end
        end   
    end
    
    figure;
    x_n=x_n';
    y_n=y_n';
    plot(x_n,y_n);
    A=[x_n,y_n];