手动从图像中提取边界并防止所选点重叠

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

我正在尝试将图像边界导入 CAD 建模软件。为此,我手动从 this image 中选择边界。我使用的代码如下:

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];

选择边界上的点,如此 image give the following outcome in CAD software model 所示。边界重叠是因为在CAD软件中绘制线条的方式如下所示:

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))

有没有办法通过暂停选择来防止选择过程中的重叠?或者关于如何有效制作模型的任何其他建议?我曾尝试使用图像处理来确定边界。但是我无法考虑将图像坐标转换为 CAD 软件模型。

可能的解决方案是用选定的点创建一个多边形,如果有线交叉,则不将选定的点添加到 x_ny_n

代码使用 polyshape 函数创建多边形对象:

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];