Ile kształtów jest na tym zdjęciu?

10

Dzieci bardzo dobrze klasyfikują i liczą przedmioty. Komputery wydają się mieć więcej problemów. To jest uproszczona wersja tego problemu. Czy potrafisz napisać mały program, który potrafi klasyfikować i liczyć obiekty na obrazie?

Problem: Biorąc pod uwagę obraz zawierający jedno lub więcej okręgów i prostokątów, zwróć 2 liczby całkowite z liczbą okręgów i liczbą prostokątów.

Zasady

  • Obrazem wejściowym będą czarne cyfry na białym tle w dowolnym wybranym formacie bitmapy.
  • Szerokość i wysokość obrazu będzie wynosić od 100 do 1000 pikseli.
  • Ryciny zostaną w całości zawarte w obrazie.
  • Liczby będą miały szerokość linii 1 piksela.
  • Obrazy nie będą używać wygładzania. Będą czarno-białe tylko.
  • Ryciny mogą dotykać, przecinać się lub znajdować się wewnątrz innej figury.
  • Przecinające się figury będą miały maksymalnie 4 wspólne piksele.
  • Koła będą miały średnicę 20 pikseli lub więcej.
  • Boki prostokąta będą miały co najmniej 10 pikseli.
  • Nie możesz używać żadnych wbudowanych bibliotek lub bibliotek, które rozpoznają kształty, ani żadnych innych funkcji, które sprawiają, że to wyzwanie jest trywialne.
  • Zwróć lub wydrukuj 2 liczby całkowite z liczbą okręgów i prostokątów.

Przykład 1

Przykład 1

Odpowiedź: 3 4

Przykład 2:

wprowadź opis zdjęcia tutaj

Odpowiedź: 4 13

Jest to wyzwanie polegające na kodzie golfowym, więc wygra najkrótszy program lub funkcja w każdym języku.

Logic Knight
źródło
Wiem już, że liczenie prostokąta będzie polegało na liczeniu narożników, ale koła będą o wiele trudniejsze.
Bálint

Odpowiedzi:

3

PHP - 355 bajtów

Liczba bajtów nie obejmuje '<image-url>'.

<?php
m('<image-url>');function m($f){$i=imagecreatefrompng($f);$r=f($i,17);$c=f($i,9);echo($c-$r).' '.$r."\n";}function f($i,$k){$w=imagesx($i);$h=imagesy($i);$r=0;for($y=0;$y<$h;$y++)for($x=0;$x<$w;$x++)if(!imagecolorat($i,$x,$y))$r+=g($i,$x,$y,$w,$k);return$r;}function g($i,&$x,$y,$w,$k){$l=$x;while(!imagecolorat($i,$x,$y)&&$x<$w)$x++;return($x-$l>$k)?1/2:0;}

W dwóch przypadkach testowych użyłem adresów URL http://i.stack.imgur.com/qnIFk.pngi http://i.stack.imgur.com/HV9k3.png.

Liczy poziome linie i dzieli przez dwa, aby uzyskać liczbę kształtów. Opiera się na obserwacji, że okręgi mają krótsze odcinki poziome, a prostokąty mają dłuższe odcinki poziome.

Przyjęty hack, nie gwarantuje się, że zadziała w przypadku innych niż przypadki testowe!

Próbowałem obrócić obrazy o ± 45 ° i wykryć linie poziome. Byłoby to równoważne sprawdzeniu linii ukośnych i lepiej wychwyciłoby koła, ale nie mogłem znaleźć algorytmu interpolacji, który pozostawiłby wystarczająco czyste krawędzie do pracy. Na przykład mogą rozmazać linię na dwa rzędy pikseli i zepsuć liczbę.


źródło