MATLAB爱好者论坛-LabFans.com

MATLAB爱好者论坛-LabFans.com (https://www.labfans.com/bbs/index.php)
-   资料存档 (https://www.labfans.com/bbs/forumdisplay.php?f=72)
-   -   查找区域遮罩代表的多边形的角 (https://www.labfans.com/bbs/showthread.php?t=22890)

poster 2019-12-10 16:49

查找区域遮罩代表的多边形的角
 
[INDENT] BW = poly2mask(x, y, m, n)从ROI多边形(由向量x和y表示BW = poly2mask(x, y, m, n)计算二进制感兴趣区域(ROI)掩模BW。 BW的大小为n×n。

poly2mask将BW中多边形(X,Y)内的像素设置为1,并将多边形外的像素设置为0。

[/INDENT][B]问题:[/B]给定这样一个凸四边形的二进制掩码BW ,确定四个角的最有效方法是什么?

例如,

[IMG]https://imgur.com/oxyjj.png[/IMG]

[B]到目前为止最好的解决方案:[/B]使用edge找到边界线,使用霍夫变换在边缘图像中找到4条线,然后找到这4条线的交点,或者在边缘图像上使用拐角检测器。似乎很复杂,我不禁感到这里有一个更简单的解决方案。

顺便说一句, convhull并不总是返回4点(也许有人可以建议使用qhull选项来防止这种情况):它也沿边缘返回了一些点。

[B]编辑:[/B] [URL="https://stackoverflow.com/questions/1711916/find-the-corners-of-a-polygon-represented-by-a-region-mask/1713400#1713400"]Amro的答案[/URL]似乎很优雅和有效。但是,由于每个峰都不是唯一的,因此在每个实际角可能会有多个“角”。我可以基于[B]胃[/B]对它们进行聚类,然后将“角”平均在一个真实的角上,但主要问题是使用order(1:10) 。

10是否足以说明所有角点,还是会排除实际角点的“角”?


回答:
这有点类似于[URL="https://stackoverflow.com/a/1712945/97160"]@AndyL的[/URL]建议。但是我在极坐标而不是切线中使用边界签名。

请注意,我首先提取边缘,获取边界,然后将其转换为签名。最后,我们找到边界上距质心最远的点,这些点构成了找到的角。 (或者,我们也可以检测出拐角处的特征峰)。

以下是完整的实现:

I = imread('oxyjj.png'); if ndims(I)==3 I = rgb2gray(I); end subplot(221), imshow(I), title('org') %%# Process Image %# edge detection BW = edge(I, 'sobel'); subplot(222), imshow(BW), title('edge') %# dilation-erosion se = strel('disk', 2); BW = imdilate(BW,se); BW = imerode(BW,se); subplot(223), imshow(BW), title('dilation-erosion') %# fill holes BW = imfill(BW, 'holes'); subplot(224), imshow(BW), title('fill') %# get boundary B = bwboundaries(BW, 8, 'noholes'); B = B{1}; %%# boudary signature %# convert boundary from cartesian to ploar coordinates objB = bsxfun(@minus, B, mean(B)); [theta, rho] = cart2pol(objB(:,2), objB(:,1)); %# find corners %#corners = find( diff(diff(rho)>0) < 0 ); %# find peaks [~,order] = sort(rho, 'descend'); corners = order(1:10); %# plot boundary signature + corners figure, plot(theta, rho, '.'), hold on plot(theta(corners), rho(corners), 'ro'), hold off xlim([-pi pi]), title('Boundary Signature'), xlabel('\theta'), ylabel('\rho') %# plot image + corners figure, imshow(BW), hold on plot(B(corners,2), B(corners,1), 's', 'MarkerSize',10, 'MarkerFaceColor','r') hold off, title('Corners') [IMG]https://i.stack.imgur.com/oj1lb.png[/IMG][IMG]https://i.stack.imgur.com/AVX7c.png[/IMG]

[B]编辑:[/B]针对雅各布的评论,我应该解释一下,我首先尝试使用一阶/二阶导数来查找签名中的峰,但最终获得了最远的N点。 10只是一个临时值,很难一概而论(我尝试将4个角与4个角相同,但并未涵盖所有角)。我认为将它们聚类以删除重复项的想法值得研究。

据我所知,第一种方法的问题在于,如果不考虑胃而绘制rho ,则会得到不同的形状(不相同的峰),因为我们追踪边界的[I]速度[/I]是不同的,并且取决于曲率。如果我们能弄清楚如何[I]标准化[/I]该效果,则可以使用导数获得更准确的结果。



[url=https://stackoverflow.com/questions/1711916]更多&回答...[/url]


所有时间均为北京时间。现在的时间是 10:27

Powered by vBulletin
版权所有 ©2000 - 2025,Jelsoft Enterprises Ltd.