Python 2 + PIL,没有错误, 313 307字节
from Image import*
I=open(sys.argv[1])
w,h=I.size;D=I.getdata()
B={i%w+i/w*1j for i in range(w*h)if D[i]!=D[0]}
n=d=1;o=v=q=p=max(B,key=abs)
while p-w:
p+=d*1j;e=2*({p}<B)+({p+d}<B)
if e!=2:e%=2;d*=1j-e*2j;p-=d/1j**e
if abs(p-q)>5:
t=(q-v)*(p-q).conjugate();q=p;w=o
if.98*abs(t)>t.real:n+=1;v=p
print n
在命令行上获取图像文件名,然后将结果打印到STDOUT。
给出所有测试的正确结果,圆的n = 28。
说明
该算法的工作原理是沿着多边形的周界走动,然后计算遇到的顶点数量(检测为方向变化)。我们从距原点最远的像素开始,该像素o
保证是顶点,因此与边缘(即,前景像素和背景像素之间的边界)相邻。我们会跟踪位置,p
最近的顶点v
和最新的“检查点” q
,所有这些初始都等于o
。我们还跟踪d
相对于当前像素的边缘方向;d
最初指向东边,这是一个安全的方向,因为我们知道东边有一条边o
,否则它离原点就不会最远。我们沿着边缘,在垂直于的方向上移动d
,从而d
指向我们的左侧,即顺时针方向。每当我们“掉落边缘”时,即在p
多边形外部或左侧像素(即方向d
)上位于多边形内部的任何情况下,我们都会进行调整p
并d
相应地进行恢复。
每当p
最后一个检查点之间的距离q
大于5时,我们都会尝试确定是否在q
和之间的顶点上通过p
:我们比较之间的角度vq
(即,从v
到的向量q
),即角度的大致方向。当到达最后一个检查点时,我们沿着多边形的另一侧行走qp
,最后一个检查点与当前位置之间的位移。如果该角度大于大约10°,则可以得出结论,我们正在沿着多边形的另一侧行走,增加了顶点数量,并将v
当前顶点设置为p
。在每个检查点,无论是否检测到顶点,我们都q
将最后一个检查点更新为p
。我们以这种方式继续,直到返回o
到起点为止,然后返回找到的顶点数量(请注意,顶点计数最初为1,因为起点o
本身就是一个顶点。)
下图显示了检测到的顶点。请注意,p
由于新顶点的位置不是最优的,因此将每个检查点的当前位置作为最优值,因为实际顶点可能位于沿周长的最后一个检查点q
和之间p
。如您所见,除第一个顶点(通常是右下角顶点)以外的所有顶点都略有偏离。修复此问题将花费更多的字节,但这似乎已经足够好了。话虽这么说,要仅用四个测试用例就很难适应。