Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
基于MATLAB的非凸多边形角点坐标顺时针检测_Matlab_Image Processing_Polygon_Corner Detection_Non Convex - Fatal编程技术网

基于MATLAB的非凸多边形角点坐标顺时针检测

基于MATLAB的非凸多边形角点坐标顺时针检测,matlab,image-processing,polygon,corner-detection,non-convex,Matlab,Image Processing,Polygon,Corner Detection,Non Convex,我有一些包括凸多边形和非凸多边形的图像。每个图像只包含一个多边形。我需要检测角点坐标,并需要按时钟顺序或逆时针顺序对它们进行排序。对于凸多边形,我用于检测角点和对点进行排序。但我不知道如何对非凸多边形排序。由于我的输入是图像,我认为一些图像处理技术可能有助于通过沿多边形边缘移动来对它们进行排序。有没有哪种方法最简单 示例图像: 我随机地给这些角落命名 预期输出: 我希望角坐标是这个顺序 13594287610或11067824953。您可以从任意点开始,不一定是1 编辑1: 在对所有凸多边形和

我有一些包括凸多边形和非凸多边形的图像。每个图像只包含一个多边形。我需要检测角点坐标,并需要按时钟顺序或逆时针顺序对它们进行排序。对于凸多边形,我用于检测角点和对点进行排序。但我不知道如何对非凸多边形排序。由于我的输入是图像,我认为一些图像处理技术可能有助于通过沿多边形边缘移动来对它们进行排序。有没有哪种方法最简单

示例图像:

我随机地给这些角落命名

预期输出:

我希望角坐标是这个顺序
13594287610
11067824953
。您可以从任意点开始,不一定是
1

编辑1:

在对所有凸多边形和一些非凸多边形都有效的解之后,有一些非凸多边形与他的算法不匹配

以下是一个示例


这是图像处理中的一个常见问题。典型的答案是找到形状的质心,并找到质心和每个角点之间的角度。您应确保角度的表示范围在
[0360)
度之间。完成此操作后,您将对角度进行排序,然后使用生成的顺序确定点的顺序

你展示的图像需要一点预处理,这样我就可以开始处理了。我直接从StackOverflow读取图像,然后反转图像,使黑星变成白色。我还需要删除数字,所以我会删除任何小的文本区域。完成后,我会对该图像执行角点检测图像通过,我将
QualityFactor
设置为0.3,这样我可以检测10个角。非常具体:

%// Read image from StackOverflow
im = rgb2gray(imread('http://i.stack.imgur.com/dpbpP.jpg'));

%// Threshold the image and area open it
im_thresh = im <= 100;
im_open = bwareaopen(im_thresh, 50);

%// Detect corner points
out = corner(im_open, 'QualityLevel', 0.3);

%// Show the image with the corner points
imshow(im_open);
hold on
plot(out(:,1), out(:,2), 'r.')
cenX
cenY
包含图像质心的
(x,y)
位置。为了确保我们的图像正确:

imshow(im_open);
hold on;
plot(cenX, cenY, 'r.', 'MarkerSize', 18);
我们得到:

非常好。现在,
out
在前面的代码中包含
(x,y)
角点的点。您所要做的就是确定从质心到每个角点的角度,然后对角度进行排序。您可以使用此排序顺序重新排列角点,以获得排列的点。如果您希望顺时针,则需要以升序对值进行排序呃。如果你想逆时针排序,你需要按降序排序。我会让你自己决定你想做什么,但我会编写代码让你同时做这两件事。因此,只需这样做:

%// Determine angles (in degrees)
angles = atan2d(out(:,2) - cenY, out(:,1) - cenX);

%// Any negative angles, add 360 degrees to convert to positive
angles(angles < 0) = 360 + angles(angles < 0);

%// Sort the angles
[~,ind] = sort(angles); %// clockwise
%[~,ind] = sort(angles, 'descend'); %// counter-clockwise

%// Re-arrange the corner points to respect the order
out_reorder = out(ind,:);
我们得到:

看起来不错!因此,
out\u reorder
会为您提供角点,使其遵循顺时针或逆时针顺序。您连续遇到的每一行都会为您提供下一个自然遵循顺时针或逆时针顺序的点


还要注意编号的起始位置。0的角度是由一条水平线定义的,该水平线相对于质心指向东方。因此,当我们以升序开始时,距离0最近的点是数字1的位置。在1之后,你会看到它以顺时针顺序扫掠,直到我们用完角点为止

另一种方法是根据角点沿边的距离来确定角点的顺序。这适用于任何可以检测到连续边的多边形

我们首先从堆栈溢出加载图像,并将其转换为黑白图像,以便更容易找到边缘

A = imread('http://i.stack.imgur.com/dpbpP.jpg');
A_bw = im2bw(A,100/255);  %binary image
A_bw1 = imcomplement(A_bw);   %inverted binary image
bwmorph
函数提供了许多用于处理黑白图像的选项。我们将使用
remove
选项查找多边形的边缘,但如果愿意,您也可以使用另一个边缘检测器

%Find the edges
A_edges = bwmorph(A_bw, 'remove');
[edge_x, edge_y] = find(A_edges');
让我们将检测到的边缘可视化

figure; imshow(A_edges);

好的,我们有一个非常清晰的连续边。现在让我们找到角点。我使用
角点
,但您可以替换您最喜欢的角点检测器

A_corners = corner(A_bw1, 'QualityLevel',.3);
让我们想象一下我们最初的角落订购

figure; imshow(A_bw1);
hold on
plot(A_corners(:,1), A_corners(:,2), 'r.', 'MarkerSize', 18)
text(A_corners(:,1), A_corners(:,2), strsplit(num2str(1:length(A_corners))), 'Color', 'g', 'FontSize', 24);
hold off

另一件你可能没有注意到的事情是,它们并不直接位于边上。我将首先沿着边找到距离每个角点最近的点,然后我将以红色显示角,以绿色显示最近的边点

[~, ind] = min(pdist2(A_corners, [edge_x, edge_y]), [], 2);
A_edge_corners = [edge_x(ind), edge_y(ind)];

figure; imshow(A_edges);
hold on;
plot(A_corners(:,1), A_corners(:,2), 'r.', 'MarkerSize', 18)
plot(A_edge_corners(:,1), A_edge_corners(:,2),'g.', 'MarkerSize', 18)
hold off;

要计算每个角点的边缘距离,我们将使用角点近似值,即边上的
A_边_角
(绿点),而不是角点本身
A_角
(红点)

现在我们有了所有需要使用的片段。这个函数可以为黑白图像中的每个非零像素找到到种子点的距离。我们感兴趣的是从初始角点到边缘上每个点的距离。让我们试试

% Calculate distance from seed corner
first_corner = A_edge_corners(1,:);
D = bwdistgeodesic(A_edges, first_corner(1), first_corner(2));
figure; imagesc(D);

我们从最右边的角点开始,从角点移开的像素值增加。但这不是我们想要的。如果我们使用这些值对角点进行排序,我们最终会得到距离初始点的排序

[~, corner_order] = sort(D(sub2ind(size(D), A_edge_corners(:,2), A_edge_corners(:,1))));
A_corners_reorder1 = A_corners(corner_order, :);

figure; imshow(A_bw1);
hold on
plot(A_corners_reorder1(:,1), A_corners_reorder1(:,2),'r.', 'MarkerSize', 18)
text(A_corners_reorder1(:,1), A_corners_reorder1(:,2), strsplit(num2str(1:length(A_corners))), 'Color', 'g', 'FontSize', 24);
hold off

为了解决这个问题,我们只需要打断边,使排序从初始点开始只沿一个方向进行。如果您对顺时针或逆时针排序感兴趣,则需要根据边的方向根据一组规则打断边。如果方向无关紧要,您可以找到与初始角点相邻的像素,并在那里打断边缘

%Break the edge into one path by removing a pixel adjacent to first corner
%If the corner is near the edge of the image, you would need to check for
%edge conditions
window = A_edges(first_corner(2)-1:first_corner(2)+1, first_corner(1)-1:first_corner(1)+1);
window(2,2) = 0; %Exclude the corner itself
[x, y] = find(window, 1);
A_edges(first_corner(2)+x-2, first_corner(1)+y-2) = 0;  

figure; imshow(A_edges);
hold on;
plot(first_corner(1), first_corner(2), 'r.', 'MarkerSize', 18)
hold off;

现在,沿边与初始点的距离只能沿着一条路径
[~, corner_order] = sort(D(sub2ind(size(D), A_edge_corners(:,2), A_edge_corners(:,1))));
A_corners_reorder1 = A_corners(corner_order, :);

figure; imshow(A_bw1);
hold on
plot(A_corners_reorder1(:,1), A_corners_reorder1(:,2),'r.', 'MarkerSize', 18)
text(A_corners_reorder1(:,1), A_corners_reorder1(:,2), strsplit(num2str(1:length(A_corners))), 'Color', 'g', 'FontSize', 24);
hold off
%Break the edge into one path by removing a pixel adjacent to first corner
%If the corner is near the edge of the image, you would need to check for
%edge conditions
window = A_edges(first_corner(2)-1:first_corner(2)+1, first_corner(1)-1:first_corner(1)+1);
window(2,2) = 0; %Exclude the corner itself
[x, y] = find(window, 1);
A_edges(first_corner(2)+x-2, first_corner(1)+y-2) = 0;  

figure; imshow(A_edges);
hold on;
plot(first_corner(1), first_corner(2), 'r.', 'MarkerSize', 18)
hold off;
%Find order the pixels along edge
D = bwdistgeodesic(A_edges, first_corner(1), first_corner(2));
figure; imagesc(D);
[~, corner_order] = sort(D(sub2ind(size(D), A_edge_corners(:,2), A_edge_corners(:,1))));
A_corners = A_corners(corner_order, :);

figure; imshow(A_bw1);
hold on
plot(A_corners(:,1), A_corners(:,2),'r.', 'MarkerSize', 18)
text(A_corners(:,1), A_corners(:,2), strsplit(num2str(1:length(A_corners))), 'Color', 'g', 'FontSize', 24);
hold off