Python 2 + PIL, kein Fehler, 313 307 Bytes
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
Nimmt einen Bilddateinamen in die Befehlszeile und gibt das Ergebnis an STDOUT aus.
Gibt das korrekte Ergebnis für alle Tests und n = 28 für den Kreis an.
Erläuterung
Der Algorithmus wandert entlang des Umfangs des Polygons und zählt die Anzahl der angetroffenen Scheitelpunkte (die als Richtungsänderungen erkannt wurden). Wir beginnen an dem Pixel, das am weitesten vom Ursprung entfernt ist o, der garantiert ein Scheitelpunkt ist und daher an eine Kante angrenzt (dh an eine Grenze zwischen einem Vordergrundpixel und einem Hintergrundpixel). Wir verfolgen unsere Position, pden neuesten Scheitelpunkt vund den neuesten "Kontrollpunkt", qdie anfangs alle gleich sind o. Wir verfolgen auch die Richtung der Kante drelativ zum aktuellen Pixel. dzeigt zunächst nach Osten, was eine sichere Richtung ist, da wir wissen, dass es östlich von eine Kante gibtooder es wäre nicht am weitesten vom Ursprung entfernt. Wir bewegen uns entlang der Kante in einer Richtung senkrecht zu d, die dnach links zeigt, dh im Uhrzeigersinn. Wann immer wir "vom Rand fallen", dh in jeder Situation, in der psich außerhalb des Polygons befindet, oder in der sich das Pixel links von uns (dh in Richtung von d) innerhalb des Polygons befindet, werden wir uns anpassen pund ddementsprechend vor dem Fortsetzen.
Jedes Mal, wenn der Abstand zwischen pund dem letzten Kontrollpunkt qgrößer als 5 wird, versuchen wir festzustellen, ob wir über einen Scheitelpunkt zwischen qund gefahren sind p: Wir vergleichen den Winkel zwischen vq(dh den Vektor von vbis q), der die allgemeine Richtung von ist Seite des Polygons, entlang dem wir gingen, als wir den letzten Kontrollpunkt erreichten, und qpdie Verschiebung zwischen dem letzten Kontrollpunkt und der aktuellen Position. Wenn der Winkel größer als ungefähr 10 ° ist, schließen wir, dass wir entlang einer anderen Seite des Polygons gehen, die Scheitelpunktanzahl erhöhen und vden aktuellen Scheitelpunkt auf setzen p. Unabhängig davon, ob wir einen Scheitelpunkt erkannt haben oder nicht, aktualisieren wir an jedem Prüfpunkt qden letzten Prüfpunkt aufp. Wir fahren auf diese Weise fort, bis wir ozum Ausgangspunkt zurückkehren und die Anzahl der gefundenen Scheitelpunkte zurückgeben (beachten Sie, dass die Anzahl der Scheitelpunkte anfänglich 1 beträgt, da der Ausgangspunkt oselbst ein Scheitelpunkt ist.)
Die Bilder unten zeigen die erkannten Scheitelpunkte. Beachten Sie, dass pdie aktuelle Position an jedem Kontrollpunkt als Position des neuen Scheitelpunkts nicht optimal ist, da der reale Scheitelpunkt wahrscheinlich irgendwo zwischen dem letzten Kontrollpunkt qund pentlang des Umfangs liegt. Wie Sie sehen können, sind alle Scheitelpunkte außer dem ersten (im Allgemeinen der untere rechte Scheitelpunkt) etwas versetzt. Dies zu beheben würde mehr Bytes kosten, aber dies scheint so gut wie es ist zu funktionieren. Davon abgesehen ist es ein wenig schwierig, nur vier Testfälle nicht zu übertreiben.
