Dada a imagem de uma cabra, seu programa deve tentar identificar se a cabra está de cabeça para baixo ou não.
Exemplos
Estes são exemplos do que a entrada pode ser. Entradas não reais
Entrada:
Resultado:
Downgoat
Spec
Seu programa deve ter no máximo 30.000 bytes
- A entrada conterá a cabra completa
- A imagem sempre conterá uma cabra
- Se a cabra estiver de cabeça para baixo, produza
Downgoat
, caso contrárioUpgoat
A entrada será, no entanto, você poderá capturar uma imagem como entrada (nome do arquivo, base64 da imagem etc.)
Não confie no nome da imagem ou em outros metadados para conter "Upgoat" ou "Downgoat", pois os nomes dos arquivos de essência são apenas para referência.
Por favor, não codifique . É chato, não posso aplicá-lo completamente, mas posso pedir bem.
Casos de teste
Gist com imagens . imagens começando com downgoat
têm Downgoat
saída e imagens começando com upgoat
têmUpgoat
saída.
Segundo lote de casos de teste
Certifique-se de testar suas imagens em todos os casos de teste. Essas imagens são um jpg
s. Os tamanhos de imagem variam, mas não pelo que muito.
Nota: Alguns casos de teste podem ser adicionados antes de aceitar uma resposta para evitar respostas que codificam o código e verificar o desempenho geral do programa.
Pontos de bônus por corrigir meu avatar: P
Pontuação
A pontuação é uma porcentagem que pode ser calculada por: (number_correct / total) * 100
fonte
Respostas:
Mathematica, 100%, 141 bytes
Bem, isso parece mais do que um pouco como trapaça. Também é incrivelmente lento, além de ser muito bobo. A função
f
vê aproximadamente o quão alto você pode definir o limite de reconhecimento em um dos recursos integrados de visão computacional do Mathematica e ainda reconhece a imagem como um animal caprino.Depois, vemos se a imagem ou a imagem invertida é mais caprichosa. Funciona na sua imagem de perfil apenas porque o empate está quebrado em favor do downgoat. Provavelmente, existem várias maneiras de melhorar isso, incluindo perguntar se a imagem representa os bovinos ou outras generalizações do tipo de entidade animal caprina.
Responda como escores escritos 100% para o primeiro conjunto de testes e 94% para o segundo conjunto de testes, pois o algoritmo produz um resultado inconclusivo para a cabra 1. Isso pode ser aumentado de volta para 100% às custas de um tempo computacional ainda mais longo. testando mais valores de
RecognitionThreshold
. Aumentar de100
para1000
suficiências; por alguma razão, o Mathematica acha que essa é uma imagem muito desagradável! Mudar a entidade de reconhecimento de Caprino para Hoofed Mammal também parece funcionar.Ungolfed:
Solução alternativa, 100% + bônus
Este usa a mesma estratégia de antes, mas com uma pesquisa binária acima do limite. Há duas funções envolvidas aqui:
g[t]
retorna se seu argumento é ou não uma imagem de cabra com limitet
.f
usa três parâmetros: uma imagem e um limite superior e inferior no limite. É recursivo; funciona testando um limitem
entre os limites superior e inferior (inclinado para o inferior). Se a imagem e a imagem refletida forem de cabra ou não de cabra, ela eliminará a parte inferior ou superior do intervalo conforme apropriado e se chamará novamente. Caso contrário, se uma imagem for de cabra e a outra não de cabra, ela retornaráUpgoat
se a primeira imagem for de cabra eDowngoat
caso contrário (se a segunda imagem refletida for de cabra).As definições de função merecem uma pequena explicação. Primeiro, a aplicação da função é associativa à esquerda. Isso significa que algo como
g[x][y]
é interpretado como(g[x])[y]
; "o resultado deg[x]
aplicado ay
."Segundo, a atribuição no Mathematica é aproximadamente equivalente à definição de uma regra de substituição. Isto é,
f[x_] := x^2
se não significa "declarar uma função chamadaf
com o parâmetrox
que retornax^2
"; seu significado está mais próximo de "sempre que vir algo assimf[ ... ]
, chame a coisa por dentrox
e substitua por tudox^2
".Juntando esses dois, podemos ver que a definição de
g
está dizendo ao Mathematica para substituir qualquer expressão do formulário(g[ ... ])[ ... ]
pelo lado direito da tarefa.Quando o Mathematica encontra a expressão
g[m]
(na segunda linha def
), vê que a expressão não corresponde a nenhuma regra que conhece e a deixa inalterada. Em seguida, ele corresponde aoMap
operador/@
, cujos argumentos sãog[m]
e a lista{i, ImageReflect@i}
. (/@
é uma notação infix; essa expressão é exatamente equivalente aMap[g[m], { ... }]
.) AMap
é substituída pela aplicação de seu primeiro argumento a cada elemento do seu segundo argumento, então obtemos{(g[m])[i], (g[m])[ ... ]}
. Agora, o Mathematica vê que cada elemento corresponde à definiçãog
e substitui.Dessa maneira, conseguimos
g
agir como uma função que retorna outra função; isto é, age aproximadamente como escrevemos:(Exceto neste caso,
g[t]
por si só, avalia como aFunction
, enquanto antesg[t]
por si só não foi transformado.)O truque final que eu uso é um padrão opcional. O padrão
l_ : 0
significa "corresponder a qualquer expressão e disponibilizá-lo comol
, ou não corresponder a nada e0
disponibilizar comol
". Portanto, se você chamarf[i]
com um argumento (a imagem a ser testada), é como se você tivesse chamadof[i, 0, 1]
.Aqui está o equipamento de teste que eu usei:
fonte
JavaScript, 93,9%
Explicação
Implementação simples da idéia do @BlackCap de verificar de onde vem a luz.
A maioria das cabras está no centro de suas imagens, e suas barrigas são sempre mais escuras do que as costas por causa da luz do sol. O programa inicia no meio da imagem e faz uma anotação da cor. Em seguida, obtém a luminosidade média dos pixels acima e abaixo do centro até onde a cor é diferente da cor no centro (quando o corpo da cabra termina e o fundo é iniciado). Qualquer que seja o lado mais claro, determina se é um upgoat ou um downgoat.
Falha no downgoat 9 e upgoats 7 e 9 no segundo caso de teste.
fonte
Python, 100%, 225 bytes
Use a pesquisa reversa de imagens na cabra. Se a página retornar uma quantidade satisfatória de resultados, provavelmente é uma cabra para cima. Essa solução provavelmente não funcionará em cabras desenhadas à mão ou se o Bing for corrompido.
fonte
Java,
93,9%100%Isso funciona determinando o contraste da linha na parte superior e inferior da imagem. Suponho que o contraste na metade inferior da imagem seja maior por 2 razões:
Eu determino o contraste para cada linha calculando a diferença dos valores de pixels vizinhos, quadrando a diferença e somando todos os quadrados.
Atualizar
Algumas imagens do segundo lote causaram problemas com o algoritmo original.
upgoat3.jpg
Esta imagem estava usando a transparência que foi ignorada anteriormente. Existem várias possibilidades para resolver esse problema, mas simplesmente escolhi renderizar todas as imagens em um fundo preto de 400x400. Isso tem as seguintes vantagens:
downgoat8.jpg / upgoat8.jpg
Essas imagens têm detalhes exagerados no corpo da cabra. A solução aqui foi desfocar a imagem apenas na direção vertical. No entanto, isso gerou problemas com imagens do primeiro lote, que possuem estruturas verticais em segundo plano. A solução aqui era simplesmente contar as diferenças que excedem um certo limite e ignorar o valor real da diferença.
Em poucas palavras, o algoritmo atualizado procura áreas com muitas diferenças nas imagens que, após o pré-processamento, ficam assim:
fonte
Python 3, 91,6%
certificado com os novos casos de teste
defina o nome do arquivo para a imagem da cabra que você deseja testar. Ele usa um kernel para tornar uma imagem superior / inferior assimétrica. Tentei o operador sobel, mas isso foi melhor.
fonte
pip install Pillow
OpenCV com Hough Transform, 100%
Minha idéia original era detectar as linhas verticais das pernas da cabra e determinar sua posição vertical em relação ao corpo e ao horizonte.
Acontece que, em todas as imagens, o solo é extremamente barulhento, produzindo muitas saídas de detecção de borda Canny e as linhas detectadas correspondentes da transformação Hough. Minha estratégia foi determinar se as linhas horizontais se situam na metade superior ou inferior da imagem, o que foi suficiente para resolver o problema.
Aqui está toda a função sem gerar imagens:
Arestas do Downgoat1:
Downgoat1 linhas:
Upgoat2 arestas e linhas:
O método até funcionou bem em imagens particularmente barulhentas. Aqui estão as bordas e linhas do downgoat3:
Termo aditivo
Acontece que o desfoque mediano e o limiar Gaussiano adaptável antes da Transformação de Hough funcionar muito melhor do que a detecção de borda Canny, principalmente porque o desfoque mediano é bom em áreas barulhentas. No entanto, os problemas da minha abordagem original são claros imediatamente: são detectadas linhas de fundo proeminentes, bem como o rosto da cabra em algumas fotos.
Aqui está o downgoat8:
Os contornos (código não mostrado) detectam a borda superior da cabra (coluna) muito bem, mas não conseguem obter toda a forma.
Pesquisas adicionais: O OpenCV possui detecção de objetos baseada em recursos Haar, que geralmente é usada para coisas como carros e rostos, mas provavelmente também poderia funcionar para cabras, devido à sua forma distinta.
O reconhecimento de recursos 2D parece promissor (a correspondência de modelos não funcionará devido ao dimensionamento e rotação), mas estou com preguiça de descobrir o OpenCV para C ++.
fonte
Python 3, numpy, scikit, 100%
Esse código executa um classificador de imagens treinado por cabras em um único nome de arquivo, imprimindo 'Upgoat' ou 'Downgoat'. O código em si é uma linha de python3, precedida por uma única string gigantesca e uma linha de importação. A corda gigante é na verdade o classificador treinado por cabras, que não é escolhido em tempo de execução e recebe a imagem de entrada para classificação.
O classificador foi criado usando o sistema TPOT, de Randal Olson e equipe da Universidade da Pensilvânia. O TPOT ajuda a evoluir os pipelines de classificação de imagens de aprendizado de máquina usando programação genética. Basicamente, ele usa seleção artificial para escolher vários parâmetros e tipos de classificação para funcionar melhor com os dados de entrada que você fornece, para que você não precise saber muito sobre aprendizado de máquina para obter uma boa configuração de pipeline. https://github.com/EpistasisLab/tpot . O TPOT roda sobre o scikit-learn, do INRIA et al, http://scikit-learn.org/stable/
Dei ao TPOT cerca de cem imagens de cabras que encontrei na internet. Eu escolhi aqueles que pareciam relativamente semelhantes às cabras no teste, ou seja, "em um campo", de lado, sem muita coisa acontecendo na imagem. A saída desse processo TPOT era basicamente um objeto ExtraTreesClassifier do scikit-learn. Este classificador de imagens, depois de ser treinado (ou "em forma") em minhas cabras, foi picado na enorme corda. A sequência, portanto, contém não apenas o código classificador, mas a "impressão" do treinamento de todas as imagens de cabras nas quais foi treinada.
Eu traí um pouco durante o treinamento, incluindo a imagem de teste 'cabra em pé em um tronco' nas imagens de treinamento, mas ainda funciona muito bem em imagens genéricas de cabra em campo. Parece haver uma troca - quanto mais tempo eu deixar o TPOT rodar, melhor o classificador criado. No entanto, os melhores classificadores também parecem ser 'maiores' e, eventualmente, ultrapassam o limite de 30.000 bytes fornecido pelo @Downgoat no jogo de golfe. Atualmente, este programa está em cerca de 27kbytes. Observe que o 'segundo grupo' de imagens de teste está quebrado, assim como o 'link de backup', portanto, não tenho certeza de como isso aconteceria. Se eles fossem reparados, eu provavelmente começaria novamente, executaria novamente o TPOT e o alimentaria um monte de novas imagens e verificaria se eu poderia criar um novo classificador com menos de 30k bytes.
obrigado
atualização: por solicitação, aqui estão os dados de treinamento, redimensionados para 24x12 e combinados em uma única imagem para facilitar o upload / apresentação. são mais de cem imagens. http://deeplearning.net/datasets/ , http://www.vision.caltech.edu/Image_Datasets/Caltech256/ , pesquisa de imagens de duckduckgo, pesquisa de imagens do Google, etc.
fonte
Aprenda o Scikit com florestas aleatórias, 100%
A abordagem testada e verdadeira é convnets, mas as florestas aleatórias podem ter um desempenho (poucos parâmetros a serem ajustados). Aqui, mostro algumas técnicas gerais nas tarefas de classificação de imagens.
Comecei com 100 imagens de cabras para treinamento que encontrei no Google Images (nenhum dos dados de treinamento da AFAIK corresponde aos dados de teste). Cada imagem é redimensionada para 20x16 em escala de cinza e, em seguida, a matriz é achatada para produzir uma linha em uma matriz 2D. Uma versão invertida da imagem também é adicionada como uma linha para os dados de treinamento. Eu não precisava usar nenhuma técnica de aumento de dados .
Em seguida, alimento a matriz 2D no classificador aleatório da floresta e chamo o predizer para produzir 50 árvores de decisão. Aqui está o código (confuso):
Aqui está a primeira árvore de decisão (embora, como o modelo esteja em um conjunto, ele não seja particularmente útil )
fonte