Python 2 + PIL, tidak ada kesalahan, 313 307 byte
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
Mengambil nama file gambar pada baris perintah, dan mencetak hasilnya ke STDOUT.
Memberikan hasil yang benar untuk semua tes, dan n = 28 untuk lingkaran.
Penjelasan
Algoritma ini bekerja dengan berjalan di sepanjang perimeter poligon, dan menghitung jumlah simpul yang ditemui (terdeteksi sebagai perubahan arah). Kita mulai pada piksel yang paling jauh dari asalnya,, oyang dijamin sebagai titik, dan oleh karena itu, berdekatan dengan tepi (yaitu, batas antara piksel latar depan dan piksel latar belakang). Kami melacak posisi kami,, ptitik terbaru v, dan "pos pemeriksaan" terbaru q, yang semuanya awalnya sama dengan o. Kami juga melacak arah tepi d,, relatif terhadap piksel saat ini; dawalnya menunjuk ke timur, yang merupakan arah yang aman, karena kita tahu ada ujung ke timuro, atau yang tidak akan terjauh dari asalnya. Kami bergerak di sepanjang tepi, dalam arah yang tegak lurus d, sehingga dmengarah ke kiri, yaitu, dalam arah searah jarum jam. Setiap kali kita "jatuh dari tepi", yaitu, dalam situasi apa pun di pluar poligon, atau di mana piksel di sebelah kiri kita (yaitu, ke arah d) ada di dalam poligon, kami menyesuaikan pdan dsesuai sebelum melanjutkan.
Setiap kali jarak antara pdan pos pemeriksaan terakhir q,, menjadi lebih besar dari 5, kami mencoba menentukan apakah kami melewati titik di antara qdan p: Kami membandingkan sudut antara vq(yaitu, vektor dari vke q), yang merupakan arah umum dari sisi poligon kami berjalan bersama ketika kami mencapai pos pemeriksaan terakhir, dan qp, perpindahan antara pos pemeriksaan terakhir dan posisi saat ini. Jika sudut lebih besar dari sekitar 10 °, kami menyimpulkan bahwa kami berjalan di sisi yang berbeda dari poligon, menambah jumlah titik, dan mengatur v, titik saat ini, untuk p. Di setiap pos pemeriksaan, terlepas dari apakah kami mendeteksi titik atau tidak, kami memperbarui q, pos pemeriksaan terakhir, kep. Kami melanjutkan dengan cara ini sampai kami tiba kembali di o, titik awal, dan mengembalikan jumlah simpul yang ditemukan (perhatikan bahwa jumlah titik awalnya 1, karena titik awal o, itu sendiri merupakan titik.)
Gambar di bawah ini menunjukkan simpul yang terdeteksi. Perhatikan bahwa pengambilan p, posisi saat ini di setiap pos pemeriksaan, karena posisi titik baru tidak optimal, karena titik sebenarnya mungkin berada di antara titik pemeriksaan terakhir q,, dan p, di sepanjang perimeter. Seperti yang Anda lihat, semua simpul selain yang pertama (umumnya, simpul kanan-bawah) sedikit tidak aktif. Memperbaiki ini akan membutuhkan lebih banyak byte, tetapi ini tampaknya bekerja dengan cukup baik. Meski begitu, agak sulit untuk tidak berpakaian dengan hanya empat test case.
