Dans l’optique d’une image de chèvre, votre programme devrait au mieux essayer de déterminer si la chèvre est à l’envers ou non.
Exemples
Ce sont des exemples de ce que l’entrée peut être. Pas d'entrées réelles
Contribution:
Sortie:
Downgoat
Spec
Votre programme ne devrait pas dépasser 30 000 octets.
- L'entrée contiendra la chèvre complète
- La photo contiendra toujours une chèvre
- Si la chèvre est à l'envers, sortie
Downgoat
, sinonUpgoat
L'entrée sera toutefois vous pouvez prendre une image en tant qu'entrée (nom de fichier, base64 de l'image, etc.)
Ne vous fiez pas au nom de l’image ou à d’autres métadonnées pour contenir «Upgoat» ou «Downgoat», car les noms de fichier de référence sont juste pour référence.
S'il vous plaît ne pas hardcode . C'est ennuyeux, je ne peux pas l'appliquer complètement mais je peux demander gentiment.
Cas de test
Gist avec des images . les images commençant par downgoat
ont une Downgoat
sortie et les images commençant par upgoat
ont une Upgoat
sortie.
Deuxième lot de cas de test
Assurez-vous de tester vos images sur tous les cas de test. Ces images sont un jpg
s. Les tailles d'image ne varient mais pas par ce que beaucoup.
Remarque: Quelques cas de test peuvent être ajoutés avant d'accepter une réponse afin d'éviter les réponses codées en dur et de vérifier les performances générales du programme.
Points bonus pour obtenir mon avatar correct: P
Notation
Le score est un pourcentage qui peut être calculé par: (number_correct / total) * 100
la source
Réponses:
Mathematica, 100%, 141 octets
Eh bien, cela ressemble plus à de la triche. C'est aussi incroyablement lent et très bête. Function
f
voit à peu près à quelle hauteur vous pouvez définir le seuil de reconnaissance dans l’un des systèmes intégrés de vision par ordinateur de Mathematica tout en reconnaissant l’image comme un animal caprin.Nous voyons alors si l'image ou l'image retournée est plus boueuse. Ne fonctionne que sur l’image de votre profil car l’égalité est brisée au profit de downgoat. Il y a probablement beaucoup de façons d'améliorer cela, notamment de lui demander si l'image représente des bovidés ou d'autres généralisations du type d'entité Caprine.
La réponse sous forme écrite marque 100% pour le premier ensemble de tests et 94% pour le second ensemble de tests, car l'algorithme donne un résultat non concluant pour la chèvre 1. Ce résultat peut être remonté à 100% au prix d'un temps de calcul encore plus long. tester plus de valeurs de
RecognitionThreshold
. Ressuscitant100
à1000
sufficies; Pour une raison quelconque, Mathematica pense que c'est une image très inconsistante! Changer l'entité de reconnaissance d'un animal caprin à un mammifère sabot semble également fonctionner.Ungolfed:
Solution alternative, bonus de 100% +
Celui-ci utilise la même stratégie qu'auparavant, mais avec une recherche binaire au dessus du seuil. Il y a deux fonctions impliquées ici:
g[t]
retourne si son argument est une image de chèvre avec seuilt
.f
prend trois paramètres: une image et une limite supérieure et inférieure sur le seuil. C'est récursif; cela fonctionne en testant un seuilm
entre les seuils haut et bas (biaisé vers le bas). Si l'image et l'image réfléchie sont toutes deux bougeuses ou non, cela élimine la partie inférieure ou supérieure de la plage, selon le cas, et se rappelle. Sinon, si une image est chèvre et que l'autre n'est pas chèvre, elle est retournéeUpgoat
si la première image est chèvre etDowngoat
sinon (si la seconde, l'image réfléchie est chèvre).Les définitions de fonctions méritent une petite explication. Tout d'abord, l'application de la fonction est associative à gauche. Cela signifie que quelque chose comme
g[x][y]
est interprété comme(g[x])[y]
; "le résultat deg[x]
appliqué ày
."Deuxièmement, l'attribution dans Mathematica équivaut à peu près à définir une règle de remplacement. Autrement dit,
f[x_] := x^2
ne signifie pas "déclarer une fonction nomméef
avec le paramètrex
qui retournex^2
;" sa signification est plus proche de, "chaque fois que vous voyez quelque chose commef[ ... ]
, appelez la chose à l'intérieurx
et remplacez la chose entière parx^2
".En réunissant ces deux éléments, nous pouvons voir que la définition de
g
indique à Mathematica de remplacer toute expression de la forme(g[ ... ])[ ... ]
par la partie droite de la tâche.Lorsque Mathematica rencontre l'expression
g[m]
(dans la deuxième ligne def
), il voit que l'expression ne correspond à aucune règle connue et la laisse inchangée. Ensuite, il correspond à l'Map
opérateur/@
, dont les arguments sontg[m]
et à la liste{i, ImageReflect@i}
. (/@
est une notation infixe; cette expression est exactement équivalente àMap[g[m], { ... }]
.) LeMap
est remplacé par l'application de son premier argument à chaque élément de son second argument, nous obtenons donc{(g[m])[i], (g[m])[ ... ]}
. Mathematica voit maintenant que chaque élément correspond à la définition deg
et effectue le remplacement.De cette manière, nous devons
g
agir comme une fonction qui renvoie une autre fonction. c'est-à-dire qu'il agit à peu près comme nous l'avons écrit:(Sauf dans ce cas, cela
g[t]
équivaut à unFunction
, alors qu'avantg[t]
, il n'était pas transformé du tout.)Le dernier tour que j'utilise est un motif optionnel. Le modèle
l_ : 0
signifie "correspond à n'importe quelle expression et le rend disponible en tant quel
, ou ne correspond à rien et le rend0
disponiblel
". Donc, si vous appelezf[i]
avec un seul argument (l’image à tester), c’est comme si vous aviez appeléf[i, 0, 1]
.Voici le harnais de test que j'ai utilisé:
la source
JavaScript, 93,9%
Explication
Mise en œuvre simple de l 'idée de @BlackCap de vérifier d' où vient la lumière.
La plupart des chèvres sont au centre de leurs images et leur ventre est toujours plus sombre que leur dos à cause de la lumière du soleil. Le programme commence au milieu de l'image et note la couleur. La luminosité moyenne des pixels situés au-dessus et au-dessous du centre est alors atteinte jusqu'à ce que la couleur soit différente de la couleur au centre (lorsque le corps de la chèvre se termine et l'arrière-plan commence). Le côté le plus léger détermine s'il s'agit d'une hausse ou d'une baisse.
Échec pour les commandes descendantes 9 et ascendantes 7 et 9 dans le deuxième cas test.
la source
Python, 100%, 225 octets
Utilisez la recherche d'images inversée sur la chèvre. Si la page renvoie une quantité satisfaisante de résultats, il s'agit probablement d'une chèvre ascendante. Cette solution ne fonctionnera probablement pas sur les chèvres dessinées à la main ou si Bing est corrompu.
la source
Java,
93,9%100%Cela fonctionne en déterminant le contraste des lignes dans la partie supérieure et inférieure de l'image. Je suppose que le contraste dans la moitié inférieure de l'image est plus important pour 2 raisons:
Je détermine le contraste pour chaque ligne en calculant la différence entre les valeurs de pixels voisins, en quadrillant la différence et en faisant la somme de tous les carrés.
Mise à jour
Certaines images du deuxième lot ont posé des problèmes avec l'algorithme d'origine.
upgoat3.jpg
Cette image utilisait une transparence qui avait été ignorée auparavant. Il existe plusieurs possibilités pour résoudre ce problème, mais j’ai simplement choisi de rendre toutes les images sur un fond noir 400x400. Cela présente les avantages suivants:
downgoat8.jpg / upgoat8.jpg
Ces images ont des détails exagérés dans le corps de la chèvre. La solution ici était de rendre l’image floue dans le sens vertical uniquement. Cependant, cela a généré des problèmes avec les images du premier lot, qui ont des structures verticales en arrière-plan. La solution ici consistait simplement à compter les différences dépassant un certain seuil et à ignorer la valeur réelle de la différence.
En bref, l’algorithme mis à jour recherche les zones avec de nombreuses différences dans les images qui, après le prétraitement, ressemblent à ceci:
la source
Python 3, 91,6%
-edited avec les nouveaux cas de test
Définissez le nom de fichier sur l'image de chèvre que vous souhaitez tester. Il utilise un noyau pour rendre une image asymétrique haut / bas.J'ai essayé l'opérateur sobel, mais c'était mieux.
la source
pip install Pillow
OpenCV avec transformation de Hough, 100%
Mon idée de départ était de détecter les lignes verticales des pattes de la chèvre et de déterminer sa position verticale par rapport au corps et à l'horizon.
Il s'avère que, dans toutes les images, le sol est extrêmement bruyant, ce qui génère de nombreuses sorties de détection de bord Canny et les lignes détectées correspondantes de la transformation de Hough. Ma stratégie consistait alors à déterminer si les lignes horizontales se trouvaient dans la moitié supérieure ou inférieure de l'image, ce qui était suffisant pour résoudre le problème.
Voici la fonction entière sans sortie d'images:
Bords descendants:
Lignes Downgoat1:
Upgoat2 bords et lignes:
La méthode a même bien fonctionné sur des images particulièrement bruyantes. Voici les arêtes et les lignes de downgoat3:
Addenda
Il s'avère que le flou médian et le seuillage gaussien adaptatif avant que la transformation de Hough fonctionne bien mieux que la détection de bord Canny, surtout depuis que le flou médian est bon dans les zones bruyantes. Cependant, les problèmes de mon approche initiale sont immédiatement clairs: des lignes de fond bien visibles sont détectées, ainsi que le visage du bouc sur certaines images.
Voici downgoat8:
Les contours (code non illustré) détectent assez bien le bord supérieur de la chèvre (colonne vertébrale) mais ne permettent pas d'obtenir la forme complète.
Recherche complémentaire: OpenCV utilise la détection d’objets basée sur les fonctionnalités Haar, qui est généralement utilisée pour des objets tels que les voitures et les visages, mais elle pourrait probablement aussi fonctionner pour les chèvres, étant donné leur forme particulière.
La reconnaissance des fonctionnalités 2D semble prometteuse (la correspondance des modèles ne fonctionnera pas à cause de la mise à l'échelle et de la rotation) mais je suis trop paresseux pour comprendre OpenCV pour C ++.
la source
Python 3, Numpy, Scikit, 100%
Ce code exécute un classifieur d'images formé par des chèvres sur un seul nom de fichier, en imprimant "Upgoat" ou "Downgoat". Le code lui-même est une ligne de python3, précédée d’une simple chaîne gigantesque et d’une ligne d’importation. La chaîne géante est en fait le classifieur formé par les chèvres, qui n'est pas piqué au moment de l'exécution et qui reçoit l'image d'entrée pour la classification.
Le classificateur a été créé à l’aide du système TPOT de Randal Olson et de l’équipe de l’Université de Pennsylvanie. TPOT aide à faire évoluer les pipelines de classificateur d'images d'apprentissage automatique en utilisant la programmation génétique. Fondamentalement, il utilise une sélection artificielle pour choisir divers paramètres et types de classification afin de fonctionner au mieux avec les données d'entrée que vous lui donnez. Vous n'avez donc pas besoin de beaucoup d'informations sur l'apprentissage automatique pour obtenir une configuration de pipeline assez bonne. https://github.com/EpistasisLab/tpot . TPOT fonctionne sur scikit-learn, sur INRIA et al, http://scikit-learn.org/stable/
J'ai donné à TPOT une centaine d'images de chèvres trouvées sur Internet. J'ai choisi celles qui ressemblaient relativement aux chèvres dans Test, c'est-à-dire "dans un champ", de côté, sans plus rien de plus dans l'image. La sortie de ce processus TPOT était essentiellement un objet ExtraTreesClassifier de scikit-learn. Ce classificateur d'images, après avoir été formé (ou «en forme») sur mes chèvres, a été conservé dans l'immense chaîne. La chaîne ne contient donc pas simplement du code de classificateur, mais aussi "l'empreinte" de la formation de toutes les images de chèvre sur lesquelles elle a été formée.
J'ai légèrement triché pendant l'entraînement en incluant l'image de test 'chèvre debout sur un journal' dans les images d'entraînement, mais cela fonctionne quand même assez bien avec des images génériques de chèvre dans un champ. Il semble y avoir un compromis - plus je laisse TPOT fonctionner longtemps, plus le classifieur qu'il crée est performant. Cependant, les meilleurs classificateurs semblent aussi être «plus gros» et finalement se heurter à la limite de 30 000 octets donnée par @Downgoat dans le jeu de golf. Ce programme est actuellement à environ 27ko. Veuillez noter que le "deuxième groupe" d'images de test est cassé, de même que le "lien de sauvegarde". Je ne sais donc pas comment cela se passerait. Si elles devaient être réparées, je recommencerais probablement, réexécutais TPOT et lui transmettais un tas de nouvelles images, et voyais si je pouvais créer un nouveau classifieur de moins de 30 000 octets.
Merci
update: par demande, voici les données de formation redimensionnées au format 24x12 et combinées en une seule image pour faciliter le téléchargement / la présentation. c'est plus d'une centaine d'images. http://deeplearning.net/datasets/ , http://www.vision.caltech.edu/Image_Datasets/Caltech256/ , recherche d'images duckduckgo, recherche d'images Google, etc.
la source
Scikit-learn avec Random Forests, 100%
L’approche éprouvée consiste à utiliser des réseaux de connexion, mais les forêts aléatoires peuvent très bien fonctionner prêtes à l’emploi (peu de paramètres à ajuster). Ici, je montre quelques techniques générales dans les tâches de classification des images.
J'ai commencé avec 100 images de chèvres pour l'entraînement, découvertes dans Google Images (aucun résultat AFAIK dans les données d'entraînement ne correspond aux données de test). Chaque image est redimensionnée à 20x16 en niveaux de gris, puis le tableau est aplati pour produire une ligne dans un tableau 2D. Une version retournée de l'image est également ajoutée en tant que ligne pour les données d'apprentissage. Je n'ai eu besoin d'aucune technique d'augmentation de données .
Ensuite, je nourris le tableau 2D dans le classifieur de forêt aléatoire et appelle prédire pour produire 50 arbres de décision. Voici le code (désordonné):
Voici le premier arbre de décision (mais comme le modèle est dans un ensemble, il n'est pas particulièrement utile )
la source