Biorąc pod uwagę obraz kozy, twój program powinien najlepiej spróbować ustalić, czy koza jest do góry nogami, czy nie.
Przykłady
Są to przykłady danych wejściowych. Nie rzeczywiste dane wejściowe
Wejście:
Wynik:
Downgoat
Spec
Twój program powinien mieć maksymalnie 30 000 bajtów
- Dane wejściowe będą zawierać pełną kozę
- Zdjęcie zawsze będzie zawierać kozę
- Jeśli koza jest odwrócona, wyjdź
Downgoat
, w przeciwnym razieUpgoat
Wejście będzie jednak można wziąć obraz jako wejście (nazwa pliku, base64 obrazu itp.)
Nie należy polegać na nazwie obrazu lub innych metadanych zawierających „Upgoat” lub „Downgoat”, ponieważ nazwy plików GIST służą wyłącznie jako odniesienie.
Proszę nie kodować na stałe . To nudne, nie mogę tego całkowicie egzekwować, ale mogę ładnie zapytać.
Przypadki testowe
Gist ze zdjęciami . obrazy zaczynające się od downgoat
mają Downgoat
wyjście, a obrazy zaczynające się od upgoat
mają Upgoat
wyjście.
Druga partia przypadków testowych
Pamiętaj, aby przetestować swoje zdjęcia na wszystkich przypadkach testowych. Te obrazy są jpg
s. Rozmiary obrazów różnią się, ale nie tak bardzo.
Uwaga: Przed zaakceptowaniem odpowiedzi można dodać kilka przypadków testowych, aby uniknąć odpowiedzi na kod i sprawdzić ogólną wydajność programu.
Punkty bonusowe za poprawienie mojego awatara: P
Punktacja
Wynik to procent, który można obliczyć przez: (number_correct / total) * 100
źródło
Odpowiedzi:
Mathematica, 100%, 141 bajtów
Cóż, to coś więcej niż oszustwo. Jest również niezwykle powolny, a także bardzo głupi. Funkcja z
f
grubsza widzi, jak wysoko można ustawić próg rozpoznawania w jednym z wbudowanych komputerowych systemów wizyjnych Mathematiki, i nadal rozpoznaje obraz jako kozę.Następnie sprawdzamy, czy obraz lub odwrócony obraz jest bardziej kozi. Działa tylko na Twoim zdjęciu profilowym, ponieważ remis jest zerwany na korzyść downgoat. Prawdopodobnie istnieje wiele sposobów, które można by ulepszyć, w tym pytanie, czy obraz przedstawia Bovids lub inne uogólnienia rodzaju bydła koziego.
Odpowiedz jako pisemne wyniki 100% dla pierwszego zestawu testowego i 94% dla drugiego zestawu testowego, ponieważ algorytm daje niejednoznaczny wynik dla kozy 1. Można to zwiększyć do 100% kosztem jeszcze dłuższego czasu obliczeniowego o testowanie większej liczby wartości
RecognitionThreshold
. Podnoszenie z100
do1000
sufficies; z jakiegoś powodu Mathematica uważa, że to bardzo nieprzyjemny obraz! Wydaje się, że zmiana jednostki rozpoznającej z kozy na Kopytny Ssak również działa.Nie golfowany:
Alternatywne rozwiązanie, 100% + bonus
Ten wykorzystuje tę samą strategię jak poprzednio, ale z wyszukiwaniem binarnym powyżej progu. W grę wchodzą dwie funkcje:
g[t]
zwraca, czy jego argumentem jest obraz kozi z progiemt
.f
przyjmuje trzy parametry: obraz oraz górną i dolną granicę progu. Jest rekurencyjny; działa poprzez testowanie progum
między górnym a dolnym progiem (odchylonym w kierunku dolnego). Jeśli obraz i obraz odbity są zarówno kozie, jak i nie-kozie, eliminuje odpowiednio dolną lub górną część zakresu i wywołuje się ponownie. W przeciwnym razie, jeśli jeden obraz jest kozi, a drugi nie jest kozi, zwraca,Upgoat
jeśli pierwszy obraz jest kozi, a wDowngoat
przeciwnym razie (jeśli drugi obraz odbity jest kozi).Definicje funkcji zasługują na małe wyjaśnienie. Po pierwsze, aplikacja funkcji jest lewostronna. Oznacza to, że coś podobnego
g[x][y]
jest interpretowane jako(g[x])[y]
; „wynikg[x]
zastosowania doy
”.Po drugie, przypisanie w Mathematica jest w przybliżeniu równoznaczne ze zdefiniowaniem reguły zastępowania. Oznacza to,
f[x_] := x^2
że nie oznacza „zadeklaruj funkcję o nazwief
z parametrem,x
który zwracax^2
;” jego znaczenie jest bliższe: „za każdym razem, gdy zobaczysz coś takiegof[ ... ]
, zadzwoń do środkax
i zastąp tox^2
”.Zestawiając te dwa elementy, widzimy, że definicja
g
mówi Mathematica, aby zastąpić dowolne wyrażenie formularza(g[ ... ])[ ... ]
prawą stroną zadania.Kiedy Mathematica napotka wyrażenie
g[m]
(w drugim wierszuf
), zobaczy, że wyrażenie nie pasuje do żadnych znanych reguł i pozostawia je bez zmian. Następnie dopasowujeMap
operator/@
, którego argumentami są,g[m]
i listę{i, ImageReflect@i}
. (/@
to notacja infiksowa; to wyrażenie jest dokładnie równoważne zMap[g[m], { ... }]
.)Map
Zastępuje się przez zastosowanie pierwszego argumentu do każdego elementu jego drugiego argumentu, więc otrzymujemy{(g[m])[i], (g[m])[ ... ]}
. Teraz Mathematica widzi, że każdy element pasuje do definicjig
i zastępuje.W ten sposób musimy
g
zachowywać się jak funkcja, która zwraca inną funkcję; to znaczy działa mniej więcej tak, jak napisaliśmy:(Z wyjątkiem tego przypadku
g[t]
samo ocenia na aFunction
, podczas gdy wcześniejg[t]
samo w ogóle nie zostało przekształcone).Ostatnią sztuczką, której używam, jest opcjonalny wzór. Wzorzec
l_ : 0
oznacza „dopasuj dowolne wyrażenie i udostępnij je jakol
, lub nie dopasowuj niczego i0
udostępnij jakol
”. Tak więc, jeśli wywołujeszf[i]
z jednym argumentem (obrazem do przetestowania), to tak jakbyś zadzwoniłf[i, 0, 1]
.Oto uprząż testowa, której użyłem:
źródło
JavaScript, 93,9%
Wyjaśnienie
Prosta implementacja pomysłu @BlackCap polegającego na sprawdzeniu, skąd pochodzi światło.
Większość kóz znajduje się pośrodku swoich wizerunków, a ich brzuchy są zawsze ciemniejsze niż grzbiety z powodu światła słonecznego. Program rozpoczyna się na środku obrazu i zapisuje kolor. Następnie uzyskuje średnią jasność pikseli powyżej i poniżej środka aż do miejsca, w którym kolor różni się od koloru w środku (kiedy ciało kozy kończy się i zaczyna się tło). Która strona jest lżejsza, określa, czy jest to upgoat czy downgoat.
Nie powiodło się dla downgoat 9 i upgoats 7 i 9 w drugim przypadku testowym.
źródło
Python, 100%, 225 bajtów
Użyj kozła do wyszukiwania wstecznego. Jeśli strona zwraca satysfakcjonującą liczbę wyników, prawdopodobnie jest to koza w górę. To rozwiązanie prawdopodobnie nie będzie działać na ręcznie rysowane kozy lub jeśli Bing kiedykolwiek zostanie uszkodzony.
źródło
Java,
93,9%100%Działa to poprzez określenie kontrastu wiersza w górnej i dolnej części obrazu. Zakładam, że kontrast w dolnej połowie obrazu jest większy z 2 powodów:
Określam kontrast dla każdego wiersza, obliczając różnicę wartości sąsiednich pikseli, kwadrat różnicę i sumując wszystkie kwadraty.
Aktualizacja
Niektóre obrazy z drugiej partii powodowały problemy z oryginalnym algorytmem.
upgoat3.jpg
Ten obraz używa przezroczystości, która była wcześniej ignorowana. Istnieje kilka możliwości rozwiązania tego problemu, ale po prostu wybrałem renderowanie wszystkich obrazów na czarnym tle o wymiarach 400 x 400. Ma to następujące zalety:
downgoat8.jpg / upgoat8.jpg
Te obrazy mają przesadzone szczegóły w ciele kozy. Rozwiązaniem było rozmycie obrazu tylko w kierunku pionowym. Powodowało to jednak problemy z obrazami z pierwszej partii, które mają pionowe struktury w tle. Rozwiązaniem tutaj było po prostu policzenie różnic przekraczających określony próg i zignorowanie rzeczywistej wartości różnicy.
Krótko mówiąc, zaktualizowany algorytm szuka obszarów z wieloma różnicami w obrazach, które wyglądają następująco:
źródło
Python 3, 91,6%
-edytowane w nowych przypadkach testowych
ustaw nazwę pliku na obraz kozy, który chcesz przetestować. Używa jądra, aby obraz był asymetryczny u góry / u dołu. Próbowałem operatora sobel, ale było lepiej.
źródło
pip install Pillow
OpenCV z transformacją Hougha, 100%
Moim pierwotnym pomysłem było wykrycie pionowych linii nóg kozła i określenie jego pozycji pionowej względem ciała i horyzontu.
Jak się okazuje, na wszystkich obrazach ziemia jest bardzo głośna, co powoduje wiele detekcji krawędzi Canny'ego i odpowiadających wykrytych linii z transformacji Hougha. Moją strategią było następnie ustalenie, czy linie poziome leżą w górnej czy dolnej połowie obrazu, co wystarczyło do rozwiązania problemu.
Oto cała funkcja bez wysyłania obrazów:
Krawędzie Downgoat1:
Downgoat1 linii:
Krawędzie i linie Upgoat2:
Metoda działała nawet dobrze na szczególnie hałaśliwych obrazach. Oto krawędzie i linie downgoat3:
Uzupełnienie
Okazuje się, że mediana rozmycia i adaptacyjne progi Gaussa przed transformacją Hougha działają znacznie lepiej niż wykrywanie krawędzi Canny'ego, głównie dlatego, że mediana rozmycia jest dobra w hałaśliwych obszarach. Jednak problemy z moim pierwotnym podejściem od razu są jasne: na niektórych zdjęciach wykrywane są wyraźne linie tła, a także twarz kozy.
Oto downgoat8:
Kontury (nie pokazano kodu) dość dobrze wykrywają górną krawędź kozy (kręgosłupa), ale nie uzyskują całego kształtu.
Dalsze badania: OpenCV ma funkcję wykrywania obiektów opartą na haarze, która jest zwykle używana do rzeczy takich jak samochody i twarze, ale prawdopodobnie mogłaby również działać na kozy, biorąc pod uwagę ich charakterystyczny kształt.
Rozpoznawanie funkcji 2D wygląda obiecująco (dopasowywanie szablonów nie będzie działać z powodu skalowania i obrotu), ale jestem zbyt leniwy, by wymyślić OpenCV dla C ++.
źródło
Python 3, numpy, scikit, 100%
Ten kod uruchamia przeszkolony kozi klasyfikator obrazów dla pojedynczej nazwy pliku, wypisując „Upgoat” lub „Downgoat”. Sam kod to jedna linia python3, poprzedzona pojedynczym gigantycznym łańcuchem i linia importu. Olbrzymi ciąg jest tak naprawdę klasyfikatorem wyszkolonym przez kozy, który jest rozpakowywany w czasie wykonywania i otrzymuje obraz wejściowy do klasyfikacji.
Klasyfikator został stworzony przy użyciu systemu TPOT, autorstwa Randala Olsona i zespołu z University of Pennsylvania. TPOT pomaga ewoluować potoki uczenia maszynowego za pomocą programowania genetycznego. Zasadniczo używa sztucznego wyboru do wybierania różnych parametrów i rodzajów klasyfikacji, aby najlepiej działać z danymi wejściowymi, które mu podajesz, więc nie musisz wiele wiedzieć o uczeniu maszynowym, aby uzyskać całkiem dobrą konfigurację potoku. https://github.com/EpistasisLab/tpot . TPOT biegnie na górze scikit-learn, z INRIA et al, http://scikit-learn.org/stable/
Dałem TPOT około stu kozich zdjęć, które znalazłem w Internecie. Wybrałem te, które wyglądały stosunkowo podobnie do kóz w teście, tj. „W polu”, z boku, bez większego znaczenia na obrazie. Rezultatem tego procesu TPOT był w zasadzie obiekt ExtraTreesClassifier do nauki scikit. Ten klasyfikator obrazów, po wytrenowaniu (lub „dopasowaniu”) u moich kóz, został wytrawiony w ogromny sznurek. Łańcuch zawiera zatem nie tylko kod klasyfikacyjny, ale „odcisk” treningu wszystkich obrazów kozłów, na których był trenowany.
Lekko oszukiwałem podczas treningu, umieszczając obraz testowy „kozy stojącej na kłodzie” na obrazach treningowych, ale nadal działa całkiem dobrze na ogólnych obrazach kozy w polu. Wygląda na to, że istnieje kompromis - im dłużej pozwalam TPOT na działanie, tym lepszy jest klasyfikator. Jednak lepsze klasyfikatory również wydają się „większe” i ostatecznie przekraczają limit 30 000 bajtów podany przez @Downgoat w grze w golfa. Ten program w obecnej postaci ma obecnie około 27 KB. Pamiętaj, że „druga grupa” zdjęć testowych jest zepsuta, podobnie jak „łącze zapasowe”, więc nie jestem pewien, jak by to zrobiło. Gdyby miały zostać naprawione, prawdopodobnie zacznę od nowa, uruchomię ponownie TPOT i załaduję kilka nowych obrazów i zobaczę, czy mogę utworzyć nowy klasyfikator o wielkości poniżej 30 000 bajtów.
Dzięki
aktualizacja: na żądanie tutaj są dane szkoleniowe, zmienione na 24x12 i połączone w jeden obraz w celu ułatwienia przesyłania / prezentacji. to ponad sto zdjęć. http://deeplearning.net/datasets/ , http://www.vision.caltech.edu/Image_Datasets/Caltech256/ , wyszukiwanie obrazów duckduckgo, wyszukiwanie obrazów google itp
źródło
Scikit-learn with Random Forests, 100%
Wypróbowanym i sprawdzonym podejściem są sieci, ale losowe lasy mogą działać bardzo dobrze od razu po wyjęciu z pudełka (kilka parametrów do dostrojenia). Tutaj pokazuję kilka ogólnych technik w zadaniach klasyfikacji obrazów.
Zacząłem od 100 zdjęć kóz do treningu, które znalazłem za pośrednictwem Google Images (AFAIK żaden z danych treningowych nie pasuje do danych testowych). Każdy obraz jest przeskalowywany do 20x16 w skali szarości, a następnie układ jest spłaszczany w celu utworzenia jednego wiersza w układzie 2D. Odwrócona wersja obrazu jest również dodawana jako wiersz danych treningowych. Nie musiałem używać żadnych technik powiększania danych .
Następnie wprowadzam tablicę 2D do losowego klasyfikatora lasu i wywołuję prognozę, aby wygenerować 50 drzew decyzyjnych. Oto (niechlujny) kod:
Oto pierwsze drzewo decyzyjne (chociaż ponieważ model jest w zespole, nie jest szczególnie użyteczny )
źródło