Wenn Sie ein Bild von einer Ziege haben, sollte Ihr Programm am besten versuchen, festzustellen, ob die Ziege auf dem Kopf steht oder nicht.
Beispiele
Dies sind Beispiele für mögliche Eingaben. Keine tatsächlichen Eingaben
Eingang:
Ausgabe:
Downgoat
Spec
Ihr Programm sollte höchstens 30.000 Bytes umfassen
- Die Eingabe wird die volle Ziege enthalten
- Das Bild enthält immer eine Ziege
- Wenn die Ziege auf dem Kopf steht, geben Sie sie
Downgoat
ansonsten ausUpgoat
Die Eingabe erfolgt, Sie können jedoch ein Bild als Eingabe verwenden (Dateiname, Base64 des Bildes usw.).
Verlassen Sie sich nicht auf den Bildnamen oder andere Metadaten, um "Upgoat" oder "Downgoat" zu enthalten, da die Namen der Hauptdateien nur als Referenz dienen.
Bitte nicht fest codieren . Es ist langweilig, ich kann es nicht vollständig durchsetzen, aber ich kann nett fragen.
Testfälle
Das Wesentliche mit Bildern . Bilder, die mit beginnen, downgoat
werden Downgoat
ausgegeben, und Bilder, die mit beginnen, upgoat
werden Upgoat
ausgegeben.
Zweiter Stapel von Testfällen Stellen
Sie sicher, dass Sie Ihre Bilder in allen Testfällen testen. Diese Bilder sind a jpg
s. Die Bildgrößen variieren, aber nicht so sehr.
Hinweis: Es können einige Testfälle hinzugefügt werden, bevor eine Antwort akzeptiert wird, um Antworten zu vermeiden, die fest codiert sind, und um die allgemeine Leistung des Programms zu überprüfen.
Bonuspunkte, um meinen Avatar korrekt zu machen: P
Wertung
Die Punktzahl ist ein Prozentwert, der berechnet werden kann durch: (number_correct / total) * 100
quelle
Antworten:
Mathematica, 100%, 141 Bytes
Nun, das fühlt sich mehr als ein bisschen nach Schummeln an. Es ist auch unglaublich langsam und sehr albern. Die Funktion ermittelt
f
ungefähr, wie hoch Sie den Erkennungsschwellenwert in einer der in Mathematica integrierten Funktionen für die Computervision einstellen können, und erkennt das Bild dennoch als Ziegentier.Wir sehen dann, ob das Bild oder das gespiegelte Bild zickiger ist. Funktioniert nur mit Ihrem Profilbild, da die Krawatte zugunsten von Downgoat unterbrochen ist. Es gibt wahrscheinlich eine Menge Möglichkeiten, wie dies verbessert werden könnte, einschließlich der Frage, ob das Bild Bovids oder andere Verallgemeinerungen des Entitätstyps Caprine darstellt.
Die schriftliche Beantwortung ergibt 100% für den ersten Testsatz und 94% für den zweiten Testsatz, da der Algorithmus für Ziege 1 ein nicht schlüssiges Ergebnis liefert. Dies kann auf Kosten einer noch längeren Rechenzeit von auf 100% zurückgesetzt werden Testen Sie mehr Werte von
RecognitionThreshold
. Auferwecken von100
zu1000
genügen; Aus irgendeinem Grund glaubt Mathematica, dass dies ein sehr schlechtes Bild ist! Es scheint auch zu funktionieren, die Erkennungsentität von Ziegen- zu Hufsäugetier zu ändern.Ungolfed:
Alternative Lösung, 100% + Bonus
Dieser verwendet die gleiche Strategie wie zuvor, jedoch mit einer binären Suche über dem Schwellenwert. Hierbei handelt es sich um zwei Funktionen:
g[t]
Gibt zurück, ob es sich bei dem Argument um ein Ziegenbild mit Schwellenwert handeltt
.f
Es werden drei Parameter verwendet: ein Bild und eine obere und untere Grenze für den Schwellenwert. Es ist rekursiv; Dies funktioniert durch Testen eines Schwellenwertsm
zwischen dem oberen und dem unteren Schwellenwert (nach unten gerichtet). Wenn das Bild und das reflektierte Bild sowohl ziegenartig als auch nicht ziegenartig sind, wird der untere oder obere Teil des Bereichs entsprechend entfernt und erneut aufgerufen. Wenn andernfalls ein Bild ziegenartig und das andere nicht ziegenartig ist, wird es zurückgegeben,Upgoat
wenn das erste Bild ziegenartig ist, undDowngoat
ansonsten (wenn das zweite, reflektierte Bild ziegenartig ist).Die Funktionsdefinitionen verdienen eine kleine Erklärung. Erstens ist die Funktionsanwendung linksassoziativ. Dies bedeutet, dass so etwas
g[x][y]
interpretiert wird als(g[x])[y]
; "das Ergebnisg[x]
angewendet aufy
."Zweitens entspricht die Zuweisung in Mathematica in etwa der Definition einer Ersetzungsregel. Dies
f[x_] := x^2
bedeutet nicht , dass eine Funktionf
mit dem Parameter deklariert wirdx
, der zurückgibtx^2
. Seine Bedeutung ist näher dran: "Wenn du etwas siehstf[ ... ]
, rufe das Ding in dir aufx
und ersetze das Ganze durchx^2
."Wenn wir diese beiden zusammenfassen, sehen wir, dass die Definition von
g
Mathematica anweist, jeden Ausdruck des Formulars(g[ ... ])[ ... ]
durch die rechte Seite der Zuweisung zu ersetzen .Wenn Mathematica auf den Ausdruck
g[m]
(in der zweiten Zeile vonf
) stößt , stellt es fest, dass der Ausdruck keinen bekannten Regeln entspricht, und lässt ihn unverändert. Dann entspricht es demMap
Operator/@
, dessen Argumenteg[m]
und die Liste sind{i, ImageReflect@i}
. (/@
Ist eine Infixnotation; dieser Ausdruck ist genau gleichbedeutend mitMap[g[m], { ... }]
.) DasMap
wird ersetzt, indem das erste Argument auf jedes Element des zweiten Arguments angewendet wird{(g[m])[i], (g[m])[ ... ]}
. Jetzt sieht Mathematica, dass jedes Element der Definition von entsprichtg
und ersetzt.Auf diese Weise müssen wir uns
g
wie eine Funktion verhalten, die eine andere Funktion zurückgibt. Das heißt, es verhält sich ungefähr so, wie wir es geschrieben haben:(Ausgenommen in diesem Fall
g[t]
ergibt sich für sich alleine eineFunction
, während zuvorg[t]
für sich alleine überhaupt keine Transformation erfolgte.)Der letzte Trick, den ich benutze, ist ein optionales Muster. Das Muster
l_ : 0
bedeutet "Jedem Ausdruckl
zuordnen und0
als verfügbar machen oder nichts zuordnen und als verfügbar machenl
". Wenn Sie alsof[i]
mit einem Argument (dem zu testenden Bild) aufrufen , ist dies so, als hätten Sie angerufenf[i, 0, 1]
.Hier ist das Testgeschirr, das ich verwendet habe:
quelle
JavaScript, 93,9%
Erläuterung
Einfache Implementierung der Idee von @BlackCap , zu überprüfen, woher das Licht kommt.
Die meisten Ziegen sind in der Mitte ihrer Bilder und ihre Bäuche sind wegen des Sonnenlichts immer dunkler als ihr Rücken. Das Programm startet in der Mitte des Bildes und notiert die Farbe. Dann wird die durchschnittliche Helligkeit der Pixel über und unter der Mitte ermittelt, bis die Farbe von der Farbe in der Mitte abweicht (wenn der Körper der Ziege endet und der Hintergrund beginnt). Welche Seite leichter ist, entscheidet darüber, ob es sich um einen Aufwärts- oder einen Abwärtsbock handelt.
Schlägt für den Downgoat 9 und die Upgoats 7 und 9 im zweiten Testfall fehl.
quelle
Python, 100%, 225 Bytes
Verwenden Sie die Rückwärtsbildsuche für die Ziege. Wenn die Seite zufriedenstellende Ergebnisse liefert, handelt es sich wahrscheinlich um eine Ziege nach oben. Diese Lösung funktioniert wahrscheinlich nicht bei handgezeichneten Ziegen oder wenn Bing jemals beschädigt wird.
quelle
Java,
93,9%100%Dies funktioniert, indem der Zeilenkontrast im oberen und unteren Teil des Bildes bestimmt wird. Ich gehe davon aus, dass der Kontrast in der unteren Bildhälfte aus zwei Gründen größer ist:
Ich bestimme den Kontrast für jede Zeile, indem ich die Differenz benachbarter Pixelwerte berechne, die Differenz quadriere und alle Quadrate summiere.
Aktualisieren
Einige Bilder aus dem zweiten Stapel verursachten Probleme mit dem ursprünglichen Algorithmus.
upgoat3.jpg
Dieses Bild verwendete Transparenz, die zuvor ignoriert wurde. Es gibt verschiedene Möglichkeiten, um dieses Problem zu lösen, aber ich habe einfach beschlossen, alle Bilder auf einem schwarzen Hintergrund von 400 x 400 zu rendern. Dies hat folgende Vorteile:
downgoat8.jpg / upgoat8.jpg
Diese Bilder haben Details im Körper der Ziege übertrieben. Die Lösung bestand darin, das Bild nur in vertikaler Richtung zu verwischen. Dies führte jedoch zu Problemen mit Bildern aus dem ersten Stapel, die vertikale Strukturen im Hintergrund aufweisen. Die Lösung bestand darin, einfach Differenzen zu zählen, die einen bestimmten Schwellenwert überschreiten, und den tatsächlichen Wert der Differenz zu ignorieren.
Kurz gesagt, der aktualisierte Algorithmus sucht nach Bereichen mit vielen Bildunterschieden, die nach der Vorverarbeitung folgendermaßen aussehen:
quelle
Python 3, 91,6%
-mit den neuen Testfällen bearbeitet
Stellen Sie den Dateinamen auf das Ziegenbild ein, das Sie testen möchten. Es verwendet einen Kernel, um ein Bild oben / unten asymmetrisch zu machen. Ich habe den Sobel-Operator ausprobiert, aber das war besser.
quelle
pip install Pillow
OpenCV mit Hough Transform, 100%
Meine ursprüngliche Idee war es, die vertikalen Linien der Ziegenbeine zu erkennen und ihre vertikale Position in Bezug auf den Körper und den Horizont zu bestimmen.
Wie sich herausstellt, ist der Boden in allen Bildern extrem verrauscht, wodurch eine Vielzahl von Canny-Kantenerkennungsausgaben und die entsprechenden erkannten Linien aus der Hough-Transformation erzeugt werden. Meine Strategie bestand darin, festzustellen, ob die horizontalen Linien in der oberen oder unteren Bildhälfte liegen, was ausreichte, um das Problem zu lösen.
Hier ist die gesamte Funktion ohne Ausgabe von Bildern:
Downgoat1 Kanten:
Downgoat1 Zeilen:
Upgoat2 Kanten und Linien:
Die Methode hat sich sogar bei besonders verrauschten Bildern bewährt. Hier ist downgoat3 Kanten und Linien:
Nachtrag
Es stellt sich heraus, dass die mittlere Unschärfe und die adaptive Gauß-Schwelle vor der Hough-Transformation viel besser funktionieren als die Canny-Kantenerkennung, vor allem, weil die mittlere Unschärfe in verrauschten Bereichen gut ist. Die Probleme meiner ursprünglichen Herangehensweise sind jedoch sofort klar: Auf einigen Bildern werden markante Hintergrundlinien sowie das Gesicht der Ziege erkannt.
Hier ist downgoat8:
Konturen (Code nicht gezeigt) erkennen die Oberkante der Ziege (Wirbelsäule) ziemlich gut, erhalten jedoch nicht die gesamte Form.
Weitere Forschung: OpenCV verfügt über eine Haar-Feature-basierte Objekterkennung, die normalerweise für Autos und Gesichter verwendet wird. Aufgrund ihrer besonderen Form könnte sie jedoch auch für Ziegen funktionieren.
Die Erkennung von 2D-Features sieht vielversprechend aus (der Template-Abgleich funktioniert aufgrund von Skalierung und Drehung nicht), aber ich bin zu faul, um OpenCV für C ++ herauszufinden.
quelle
Python 3, numpy, scikit, 100%
Dieser Code führt einen von Ziegen geschulten Bildklassifizierer gegen einen einzelnen Dateinamen aus und gibt "Upgoat" oder "Downgoat" aus. Der Code selbst ist eine Zeile von python3, der eine einzelne gigantische Zeichenfolge und eine Importzeile vorangestellt sind. Die Riesenschnur ist eigentlich der von der Ziege trainierte Klassifikator, der zur Laufzeit entfernt und mit dem Eingabebild zur Klassifizierung versehen wird.
Der Klassifikator wurde unter Verwendung des TPOT-Systems von Randal Olson und Team von der University of Pennsylvania erstellt. TPOT hilft dabei, maschinell erlernte Bildklassifizierungs-Pipelines mithilfe genetischer Programmierung zu entwickeln. Grundsätzlich wird eine künstliche Auswahl verwendet, um verschiedene Parameter und Klassifizierungstypen auszuwählen, die am besten mit den von Ihnen angegebenen Eingabedaten funktionieren. Sie müssen also nicht viel über maschinelles Lernen wissen, um eine recht gute Pipeline-Konfiguration zu erhalten. https://github.com/EpistasisLab/tpot . TPOT läuft auf scikit-learn, von INRIA et al., Http://scikit-learn.org/stable/
Ich habe TPOT ungefähr hundert Ziegenbilder gegeben, die ich im Internet gefunden habe. Ich habe diejenigen ausgewählt, die den Ziegen im Test relativ ähnlich sahen, dh "auf einem Feld", von der Seite, ohne dass sonst im Bild viel los war. Die Ausgabe dieses TPOT-Prozesses war im Grunde genommen ein ExtraTreesClassifier-Objekt, mit dem Sie scikit-lernen können. Dieser Bildklassifikator wurde, nachdem er auf meinen Ziegen trainiert (oder "fit") war, in die riesige Schnur eingelegt. Die Zeichenfolge enthält also nicht nur den Klassifikatorcode, sondern den "Abdruck" des Trainings aller Ziegenbilder, auf die sie trainiert wurde.
Ich habe während des Trainings ein wenig geschummelt, indem ich das Testbild "Ziege steht auf einem Baumstamm" in die Trainingsbilder aufgenommen habe, aber es funktioniert immer noch ziemlich gut bei allgemeinen Bildern von Ziegen auf dem Feld. Es scheint einen Kompromiss zu geben - je länger ich TPOT laufen lasse, desto besser wurde der Klassifikator erstellt. Bessere Klassifikatoren scheinen jedoch auch "größer" zu sein und stoßen schließlich auf das von @Downgoat im Golfspiel festgelegte Limit von 30.000 Bytes. Das aktuelle Programm hat derzeit eine Größe von ca. 27 KB. Bitte beachten Sie, dass die 'zweite Gruppe' von Testbildern sowie der 'Backup-Link' defekt sind. Ich bin mir also nicht sicher, wie sie darauf reagieren würden. Wenn sie repariert würden, würde ich wahrscheinlich von vorne anfangen, TPOT erneut ausführen und ihm eine Reihe neuer Bilder zuführen und sehen, ob ich einen neuen Klassifizierer unter 30 KB erstellen könnte.
Vielen Dank
Update: Auf Anfrage werden hier die Trainingsdaten in der Größe 24x12 angezeigt und zur Vereinfachung des Uploads / der Präsentation in einem einzigen Bild zusammengefasst. Es sind über hundert Bilder. http://deeplearning.net/datasets/ , http://www.vision.caltech.edu/Image_Datasets/Caltech256/ , duckduckgo image search, google image search usw
quelle
Scikit-Lernen mit zufälligen Wäldern, 100%
Der bewährte Ansatz sind Convnets, aber zufällige Gesamtstrukturen können eine hervorragende Leistung erzielen (nur wenige Parameter müssen angepasst werden). Hier zeige ich einige allgemeine Techniken bei Bildklassifizierungsaufgaben.
Ich habe mit 100 Bildern von Ziegen für das Training begonnen, die ich über Google Images gefunden habe (AFAIK: Keines in den Trainingsdaten stimmt mit den Testdaten überein). Jedes Bild wird in Graustufen auf 20 x 16 skaliert. Anschließend wird das Array abgeflacht, um eine Zeile in einem 2D-Array zu erstellen. Eine gespiegelte Version des Bildes wird auch als Zeile für die Trainingsdaten hinzugefügt. Ich brauchte keine Techniken zur Datenvergrößerung .
Dann füttere ich das 2D-Array mit dem zufälligen Waldklassifikator und rufe predict auf, um 50 Entscheidungsbäume zu erzeugen. Hier ist der (chaotische) Code:
Hier ist der erste Entscheidungsbaum (obwohl das Modell, da es sich in einem Ensemble befindet, nicht besonders nützlich ist )
quelle