Processamento de Imagem: Melhoria do Algoritmo para o Reconhecimento da ‘Coca-Cola Can’

Um dos projetos mais interessantes nos quais trabalhei nos últimos dois anos foi um projeto sobre processamento de imagens . O objective era desenvolver um sistema capaz de reconhecer as ‘latas’ da Coca-Cola (note que estou enfatizando a palavra ‘latas’, você verá por que em um minuto). Você pode ver uma amostra abaixo, com a lata reconhecida no retângulo verde com escala e rotação.

Correspondência de modelos

Algumas restrições no projeto:

  • O fundo pode ser muito barulhento.
  • A lata pode ter qualquer escala ou rotação ou mesmo orientação (dentro de limites razoáveis).
  • A imagem pode ter algum grau de imprecisão (os contornos podem não ser totalmente retos).
  • Pode haver garrafas da Coca-Cola na imagem, e o algoritmo só deve detectar a lata !
  • O brilho da imagem pode variar muito (então você não pode confiar demais na detecção de colors).
  • A lata pode estar parcialmente escondida nas laterais ou no meio e possivelmente parcialmente escondida atrás de uma garrafa.
  • Não poderia haver nada na imagem, caso em que você não tinha que encontrar nada e escrever uma mensagem dizendo isso.

Então você pode acabar com coisas complicadas como essa (que neste caso, meu algoritmo falharia totalmente):

Falha total

Eu fiz este projeto há um tempo atrás, e me diverti muito fazendo isso, e tive uma implementação decente. Aqui estão alguns detalhes sobre minha implementação:

Idioma : Feito em C ++ usando a biblioteca OpenCV .

Pré-processamento : Para o pré-processamento da imagem, ou seja, transformar a imagem em uma forma mais bruta para dar ao algoritmo, usei 2 methods:

  1. Alterar o domínio de colors de RGB para HSV e filtrar com base na tonalidade “vermelha”, saturação acima de um certo limite para evitar colors parecidas com laranja e filtragem de baixo valor para evitar tons escuros. O resultado final foi uma imagem binária em preto e branco, em que todos os pixels brancos representariam os pixels que correspondem a esse limite. Obviamente, ainda há muita porcaria na imagem, mas isso reduz o número de dimensões com as quais você tem que trabalhar. Imagem binarizada
  2. Filtragem de ruído usando filtragem mediana (tomando o valor mediano de pixel de todos os vizinhos e substituindo o pixel por esse valor) para reduzir o ruído.
  3. Usando o Canny Edge Detection Filter para obter os contornos de todos os itens após 2 etapas precedentes. Detecção de contorno

Algoritmo : O algoritmo em si que eu escolhi para essa tarefa foi extraído deste livro incrível sobre extração de características e chamado Generalized Hough Transform (bem diferente do Hough Transform regular). Basicamente diz algumas coisas:

  • Você pode descrever um object no espaço sem conhecer sua equação analítica (que é o caso aqui).
  • Ele é resistente a deformações de imagem, como dimensionamento e rotação, já que basicamente testa sua imagem para cada combinação de fator de escala e fator de rotação.
  • Ele usa um modelo base (um modelo) que o algoritmo “aprende”.
  • Cada pixel restante na imagem de contorno votará em outro pixel que, supostamente, será o centro (em termos de gravidade) do seu object, com base no que aprendeu com o modelo.

No final, você acaba com um mapa de calor dos votos, por exemplo, aqui todos os pixels do contorno da lata vão votar em seu centro gravitacional, então você terá muitos votos no mesmo pixel correspondente ao centro, e vai ver um pico no mapa de calor como abaixo:

GHT

Uma vez que você tenha isso, uma heurística baseada em limiares simples pode fornecer a localização do pixel central, a partir do qual você pode derivar a escala e a rotação e, em seguida, plotar seu pequeno retângulo (a escala final e o fator de rotação serão obviamente relativos ao seu modelo original). Em teoria, pelo menos …

Resultados : Agora, embora essa abordagem tenha funcionado nos casos básicos, ela estava gravemente deficiente em algumas áreas:

  • É extremamente lento ! Eu não estou enfatizando isso o suficiente. Quase um dia inteiro foi necessário para processar as 30 imagens de teste, obviamente porque eu tinha um fator de escala muito alto para rotação e translação, já que algumas das latas eram muito pequenas.
  • Estava completamente perdido quando as garrafas estavam na imagem e, por alguma razão, quase sempre achavam a garrafa em vez da lata (talvez porque as garrafas fossem maiores, portanto tinham mais pixels, portanto mais votos).
  • As imagens difusas também não eram boas, uma vez que os votos terminavam em pixels em locais randoms ao redor do centro, terminando assim com um mapa de calor muito barulhento.
  • A variação na tradução e rotação foi alcançada, mas não na orientação, o que significa que uma lata que não estava diretamente voltada para o objective da câmera não foi reconhecida.

Você pode me ajudar a melhorar meu algoritmo específico , usando exclusivamente resources do OpenCV , para resolver os quatro problemas específicos mencionados?

Espero que algumas pessoas também aprendam algo a partir disso, afinal acho que não apenas as pessoas que fazem perguntas deveriam aprender. 🙂

Uma abordagem alternativa seria extrair resources (pontos chave) usando a transformação de recurso invariante de escala (SIFT) ou Recursos robustos acelerados (SURF).

Ele é implementado no OpenCV 2.3.1.

Você pode encontrar um bom exemplo de código usando resources em Features2D + Homography para encontrar um object conhecido

Ambos os algoritmos são invariantes para escalonamento e rotação. Como eles funcionam com resources, você também pode manipular a oclusão (contanto que pontos-chave suficientes estejam visíveis).

Digite a descrição da imagem aqui

Fonte da imagem: exemplo do tutorial

O processamento leva algumas centenas de ms para o SIFT, o SURF é um pouco mais rápido, mas não é adequado para aplicativos em tempo real. O ORB usa o FAST, que é mais fraco em relação à invariância de rotação.

Os documentos originais

  • SURF: Recursos robustos acelerados
  • Recursos distintos de imagem de keypoints invariables ​​em escala
  • ORB: uma alternativa eficiente para SIFT ou SURF

Para acelerar as coisas, eu aproveitaria o fato de que você não é solicitado a encontrar uma imagem / object arbitrário, mas especificamente um com o logotipo da Coca-Cola. Isso é significativo porque esse logotipo é muito distinto e deve ter uma assinatura característica e invariável de escala no domínio da frequência, particularmente no canal vermelho de RGB. Ou seja, o padrão alternado de vermelho para branco-para-vermelho encontrado por uma linha de varredura horizontal (treinado em um logotipo alinhado horizontalmente) terá um “ritmo” distinto ao passar pelo eixo central do logotipo. Esse ritmo irá “acelerar” ou “desacelerar” em diferentes escalas e orientações, mas permanecerá proporcionalmente equivalente. Você poderia identificar / definir algumas dúzias de tais linhas de varredura, tanto horizontalmente quanto verticalmente através do logotipo e várias outras na diagonal, em um padrão de estrela. Chame isso de “linhas de verificação de assinatura”.

Linha de varredura de assinatura

Procurar por essa assinatura na imagem de destino é uma simples questão de digitalizar a imagem em faixas horizontais. Procure por uma alta freqüência no canal vermelho (indicando a mudança de uma região vermelha para uma branca), e uma vez encontrada, veja se ela é seguida por um dos ritmos de freqüência identificados na session de treinamento. Quando uma correspondência for encontrada, você saberá instantaneamente a orientação e a localização da linha de varredura no logotipo (se você acompanhar essas coisas durante o treinamento), de modo que identificar os limites do logotipo a partir daí é trivial.

Eu ficaria surpreso se isso não fosse um algoritmo linearmente eficiente, ou quase isso. Obviamente não aborda a discriminação da sua garrafa, mas pelo menos você terá seus logotipos.

(Atualização: para o reconhecimento de garrafas eu procuraria por coca-cola (o líquido marrom) adjacente ao logotipo – ou seja, dentro da garrafa. Ou, no caso de uma garrafa vazia, eu procuraria uma tampa que sempre teria mesma forma básica, tamanho e distância do logotipo e normalmente será todo branco ou vermelho.Procure por uma forma elíptica de cor sólida onde uma capa deve ser, em relação ao logotipo.Não infalível é claro, mas seu objective aqui deve ser encontre os mais fáceis rapidamente .)

(Faz alguns anos desde meus dias de processamento de imagens, então mantive essa sugestão de alto nível e conceitual. Acho que pode ser um pouco como um olho humano pode operar – ou pelo menos como meu cérebro funciona!)

Problema divertido: quando eu olhei para sua imagem de garrafa, eu pensei que era uma lata também. Mas, como humano, o que eu fiz para dizer a diferença é que eu notei que também era uma garrafa …

Então, para distinguir latas e garrafas, que tal simplesmente procurar por garrafas primeiro? Se você encontrar um, mascare o label antes de procurar por latas.

Não é muito difícil de implementar, se você já está fazendo latas. A desvantagem real é o dobro do tempo de processamento. (Mas pensando em aplicativos do mundo real, você vai acabar querendo fazer garrafas de qualquer maneira 😉

Não é difícil até para os humanos distinguir entre uma garrafa e uma lata na segunda imagem (desde que a região transparente da garrafa esteja escondida)?

Eles são quase os mesmos, exceto por uma região muito pequena (isto é, a largura no topo da lata é um pouco pequena, enquanto o invólucro da garrafa tem a mesma largura, mas uma pequena alteração, certo?)

A primeira coisa que me veio à mente foi verificar o topo vermelho da garrafa. Mas ainda é um problema, se não houver tampa para a garrafa, ou se ela estiver parcialmente oculta (como mencionado acima).

A segunda coisa que pensei foi sobre a transparência da garrafa. O OpenCV tem alguns trabalhos para encontrar objects transparentes em uma imagem. Confira os links abaixo.

  • Minutas das Notas da Reunião do OpenCV 2012-03-19

  • Minutas de notas da reunião do OpenCV 2012-02-28

Particularmente, olhe para isso para ver com que precisão eles detectam o vidro:

  • Minutas das Notas da Reunião do OpenCV 2012-04-24

Veja o resultado da sua implementação:

Digite a descrição da imagem aqui

Eles dizem que é a implementação do artigo “Uma estrutura de contorno ativo geodésico para encontrar vidro” por K. McHenry e J. Ponce, CVPR 2006 .

Pode ser útil no seu caso um pouco, mas o problema surge novamente se a garrafa estiver cheia.

Então eu acho que aqui você pode procurar pelo corpo transparente das garrafas primeiro ou por uma região vermelha conectada a dois objects transparentes lateralmente, que é obviamente a garrafa. (Ao trabalhar idealmente, uma imagem da seguinte forma.)

Digite a descrição da imagem aqui

Agora você pode remover a região amarela, isto é, o label da garrafa e executar seu algoritmo para encontrar a lata.

De qualquer forma, esta solução também tem problemas diferentes, como nas outras soluções.

  1. Só funciona se a sua garrafa estiver vazia. Nesse caso, você terá que procurar a região vermelha entre as duas colors pretas (se o líquido da Coca-Cola for preto).
  2. Outro problema se parte transparente é coberta.

Mas de qualquer forma, se não houver nenhum dos problemas acima nas imagens, isso parece ser um caminho melhor.

Eu realmente gosto das respostas de Darren Cook e do stacker para esse problema. Eu estava no meio de jogar meus pensamentos em um comentário sobre eles, mas acredito que minha abordagem é muito em forma de resposta para não sair daqui.

Resumindo, você identificou um algoritmo para determinar se um logotipo da Coca-Cola está presente em um determinado local no espaço. Agora você está tentando determinar, para orientações arbitrárias e fatores de escala arbitrários, uma heurística adequada para distinguir as latas de Coca-Cola de outros objects, incluindo: garrafas , outdoors , propagandas e apetrechos da Coca-Cola, todos associados a esse logo icônico. Você não citou muitos desses casos adicionais em sua declaração de problema, mas eu sinto que eles são vitais para o sucesso do seu algoritmo.

O segredo aqui é determinar quais resources visuais uma lata contém ou, através do espaço negativo, quais resources estão presentes para outros produtos de Coca-Cola que não estão presentes em latas. Para esse fim, a resposta principal atual esboça uma abordagem básica para selecionar “pode” se e somente se “garrafa” não for identificada, seja pela presença de uma tampa de garrafa, líquido ou outras heurísticas visuais semelhantes.

O problema é que isso se quebra. Uma garrafa pode, por exemplo, estar vazia e não ter a presença de uma tampa, o que leva a um falso positivo. Ou, poderia ser uma garrafa parcial com resources adicionais mutilados, levando novamente à falsa detecção. Escusado será dizer que isto não é elegante, nem é eficaz para os nossos propósitos.

Para este fim, os critérios de seleção mais corretos para as latas parecem ser os seguintes:

  • É a forma da silhueta do object, como você esboçou em sua pergunta , correto? Se sim, um.
  • Se assumirmos a presença de luz natural ou artificial, detectamos um contorno cromado na garrafa que indica se ela é feita de alumínio? Se sim, um.
  • Determinamos que as propriedades especulares do object estão corretas em relação às nossas fonts de luz ( link de vídeo ilustrativo na detecção da fonte de luz )? Se sim, um.
  • Podemos determinar quaisquer outras propriedades sobre o object que o identifique como um possível, incluindo, mas não limitado a, a inclinação da imagem topológica do logotipo, a orientação do object, a justaposição do object (por exemplo, em uma superfície plana como uma mesa ou no contexto de outras latas), e a presença de uma aba de puxar? Se sim, para cada um, +1.

Sua sorting pode se parecer com o seguinte:

  • Para cada correspondência candidata, se a presença de um logotipo da Coca-Cola for detectada, desenhe uma borda cinza.
  • Para cada partida acima de +2, desenhe uma borda vermelha.

Isso destaca visualmente para o usuário o que foi detectado, enfatizando pontos fracos positivos que podem, corretamente, ser detectados como latas mutiladas.

A detecção de cada propriedade carrega uma complexidade de espaço e tempo muito diferente, e para cada abordagem, uma rápida passagem por http://dsp.stackexchange.com é mais do que razoável para determinar o algoritmo mais correto e mais eficiente para seus propósitos. Minha intenção aqui é, pura e simplesmente, enfatizar que detectar se algo é possível invalidando uma pequena parte do espaço de detecção do candidato não é a solução mais robusta ou eficaz para esse problema e, idealmente, você deve tomar as ações apropriadas adequadamente.

E ei, parabéns pela publicação do Hacker News! No geral, essa é uma pergunta muito interessante, digna da publicidade que recebeu. 🙂

Olhando para a forma

Dê uma olhada na forma da porção vermelha da lata / garrafa. Observe como a lata afunila ligeiramente no topo, enquanto a etiqueta da garrafa é reta. Você pode distinguir entre esses dois comparando a largura da parte vermelha ao longo do comprimento dela.

Olhando para os destaques

Uma maneira de distinguir entre garrafas e latas é o material. Uma garrafa é feita de plástico, enquanto uma lata é feita de metal de alumínio. Em situações suficientemente bem iluminadas, olhar para a especularidade seria uma maneira de dizer um label de garrafa a partir de um label de lata.

Tanto quanto eu posso dizer, é assim que um humano diria a diferença entre os dois tipos de labels. Se as condições de iluminação forem fracas, certamente haverá alguma incerteza em distinguir as duas de qualquer maneira. Nesse caso, você teria que ser capaz de detectar a presença da própria garrafa transparente / translúcida.

Por favor, dê uma olhada no rastreador predador de Zdenek Kalal. Requer algum treinamento, mas ele pode aprender ativamente como o object rastreado observa diferentes orientações e escalas e o faz em tempo real!

O código-fonte está disponível em seu site. Está no MATLAB , mas talvez haja uma implementação Java já feita por um membro da comunidade. Eu tenho re-implementado com sucesso a parte tracker do TLD em C #. Se bem me lembro, o TLD está usando o Ferns como o detector de ponto chave. Eu uso SURF ou SIFT em vez disso (já sugerido por @stacker) para readquirir o object se ele foi perdido pelo rastreador. O feedback do rastreador faz com que seja fácil construir com o tempo uma lista dinâmica de modelos sift / surf que, com o tempo, permitem readquirir o object com alta precisão.

Se você estiver interessado em minha implementação do rastreador C #, fique à vontade para perguntar.

Se você não está limitado a apenas uma câmera que não estava em uma de suas restrições, talvez você possa passar a usar um sensor de alcance como o Xbox Kinect . Com isso, você pode executar a segmentação de acordo com a cor e a profundidade da imagem. Isso permite uma separação mais rápida de objects na imagem. Você pode então usar a correspondência ICP ou técnicas similares para igualar a forma da lata ao invés de apenas seu contorno ou cor e, dado que é cilíndrica, esta pode ser uma opção válida para qualquer orientação se você tiver uma varredura 3D prévia do alvo. Essas técnicas costumam ser bastante rápidas, especialmente quando usadas para um propósito específico que deve resolver seu problema de velocidade.

Eu também poderia sugerir, não necessariamente por precisão ou velocidade, mas por diversão você poderia usar uma neural network treinada em sua imagem segmentada por tons para identificar a forma da lata. Estes são muito rápidos e muitas vezes podem ter até 80/90% de precisão. O treinamento seria um processo longo, já que você teria que identificar manualmente a lata em cada imagem.

Eu detectaria retângulos vermelhos: RGB -> HSV, filtro vermelho -> imagem binária, próximo (dilate então corroer, conhecido como imclose em matlab)

Então olhe através dos retângulos do maior para o menor. Retângulos que possuem retângulos menores em uma posição / escala conhecida podem ser removidos (assumindo que as proporções do flask são constantes, o retângulo menor seria uma tampa de garrafa).

Isso deixará você com retângulos vermelhos, então você precisará detectar os logotipos para saber se eles são um retângulo vermelho ou uma lata de coque. Como o OCR, mas com um logo conhecido?

Esta pode ser uma ideia muito ingênua (ou pode não funcionar de todo), mas as dimensões de todas as latas de coque são fixas. Assim pode ser que se a mesma imagem contiver uma lata e uma garrafa, então você pode diferenciá-las por considerações de tamanho (as garrafas serão maiores). Agora, devido à falta de profundidade (ou seja, mapeamento 3D para mapeamento 2D), é possível que uma garrafa possa parecer encolhida e não haja diferença de tamanho. Você pode recuperar algumas informações de profundidade usando imagens estéreo e depois recuperar o tamanho original.

Eu não estou ciente do OpenCV, mas olhando para o problema logicamente eu acho que você poderia diferenciar entre garrafa e lata, alterando a imagem que você está procurando ou seja, Coca-Cola. Você deve incorporar até a parte superior da lata, como no caso da lata há forro de prata no topo da coca-cola e no caso da garrafa não haverá tal forro de prata.

Mas obviamente este algoritmo falhará nos casos em que a parte superior da lata está escondida, mas nesse caso até o ser humano não será capaz de diferenciar entre os dois (se a porção de garrafa / lata da coca-cola for visível)

Hmm, eu realmente acho que estou pensando em alguma coisa (essa é a pergunta mais interessante de todas – então seria uma pena não continuar tentando encontrar a resposta “perfeita”, mesmo que uma resposta aceitável tenha sido encontrada). .

Depois de encontrar o logotipo, seus problemas estão pela metade. Então você só tem que descobrir as diferenças entre o que está ao redor do logotipo. Além disso, queremos fazer o mínimo possível. Eu acho que isso é realmente essa parte fácil …

O que está ao redor do logotipo? Para uma lata, podemos ver o metal, que apesar dos efeitos da iluminação, não muda em sua cor básica. Contanto que saibamos o ângulo do label, podemos dizer o que está diretamente acima dele, então estamos vendo a diferença entre eles:

Aqui, o que está acima e abaixo do logotipo é completamente escuro, consistente em colors. Relativamente fácil nesse aspecto.

Aqui, o que está acima e abaixo é leve, mas ainda consistente em colors. É todo em prata, e todo em metal prateado na verdade parece bem raro, assim como as colors prateadas em geral. Além disso, ele está em um slither fino e próximo o suficiente do vermelho que já foi identificado para que você possa traçar sua forma durante todo o seu comprimento para calcular uma porcentagem do que pode ser considerado o anel de metal da lata. Realmente, você só precisa de uma pequena fração disso em qualquer lugar ao longo da lata para dizer que é parte dela, mas você ainda precisa encontrar um equilíbrio que garanta que não seja apenas uma garrafa vazia com algo metálico atrás dela.

E finalmente, o complicado. Mas não tão complicado, uma vez que estamos apenas passando pelo que podemos ver diretamente acima (e abaixo) do invólucro vermelho. É transparente, o que significa que vai mostrar o que está por trás disso. Isso é bom, porque as coisas que estão por trás não são tão consistentes em colors quanto o metal circular prateado da lata. Poderia haver muitas coisas diferentes por trás, o que nos diria que é uma garrafa vazia (ou cheia de líquido claro), ou uma cor consistente, o que poderia significar que ela está cheia de líquido ou que a garrafa está simplesmente na frente de um Cor sólida. Estamos trabalhando com o que está mais próximo da parte superior e inferior, e as chances de as colors certas estarem no lugar certo são relativamente pequenas. Sabemos que é uma garrafa, porque não tem aquele elemento visual chave da lata, que é relativamente simplista comparado ao que poderia estar por trás de uma garrafa.

(esse último foi o melhor que pude encontrar de uma garrafa vazia grande de coca-cola – de maneira interessante, a tampa e o anel são amarelos, indicando que a vermelhidão da tampa provavelmente não deve ser confiada)

Na rara circunstância de que um tom semelhante de prata está por trás da garrafa, mesmo após a abstração do plástico, ou a garrafa é de alguma forma preenchida com o mesmo tom de líquido prateado, podemos recorrer ao que podemos estimar aproximadamente como sendo o forma da prata – que como mencionei, é circular e segue a forma da lata. Mas mesmo que eu não tenha nenhum conhecimento em processamento de imagens, isso parece lento. Melhor ainda, por que não deduzir isso pela primeira vez verificando os lados do logotipo para garantir que não há nada da mesma cor prata lá? Ah, mas e se houver o mesmo tom de prata atrás de uma lata? Então, nós realmente temos que prestar mais atenção às formas, olhando para o topo e o fundo da lata novamente.

Dependendo de quão perfeito tudo isso precisa ser, pode ser muito lento, mas acho que meu conceito básico é verificar primeiro as coisas mais fáceis e próximas. Passe por diferenças de cor ao redor da forma já combinada (o que parece ser a parte mais trivial disso) antes de tentar descobrir a forma dos outros elementos. Para listá-lo, vai:

  • Encontre a atração principal (fundo do logotipo vermelho e possivelmente o próprio logotipo para orientação, embora no caso de a lata ser virada para fora, você precisa se concentrar apenas no vermelho)
  • Verifique a forma e orientação, mais uma vez através da vermelhidão muito distinta
  • Verifique as colors em torno da forma (uma vez que é rápido e indolor)
  • Finalmente, se necessário, verifique a forma dessas colors em torno da atração principal para a redondeza correta.

No caso de você não poder fazer isso, provavelmente significa que o topo e a base da lata estão cobertos, e as únicas coisas possíveis que um humano poderia ter usado para fazer uma distinção entre a lata e a garrafa são a oclusão e a reflection. da lata, o que seria uma batalha muito mais difícil de processar. No entanto, para ir ainda mais longe, você pode seguir o ângulo da lata / garrafa para verificar se há mais traços de garrafa, usando as técnicas de digitalização semitransparentes mencionadas nas outras respostas.

Pesadelos adicionais interessantes podem include uma lata sentada convenientemente atrás da garrafa a uma distância tal que o metal dela simplesmente apareça acima e abaixo da etiqueta, o que ainda falharia enquanto você estivesse escaneando ao longo de toda a extensão do vermelho. label – que na verdade é mais um problema porque você não está detectando uma lata onde você poderia ter, em vez de considerar que você está realmente detectando uma garrafa, incluindo a lata por acidente. O copo está meio vazio, nesse caso!


Como aviso legal, eu não tenho experiência nem nunca pensei sobre o processamento de imagens fora desta questão, mas é tão interessante que me fez pensar muito profundamente sobre isso, e depois de ler todas as outras respostas, eu considero isso possivelmente a maneira mais fácil e eficiente de fazê-lo. Pessoalmente, estou feliz por não ter que pensar em programar isso!

EDITAR

desenho ruim de uma lata na pintura MS Além disso, veja este desenho que fiz no MS Paint … É absolutamente horrível e bastante incompleto, mas baseado apenas na forma e colors, você pode adivinhar o que provavelmente será. Em essência, essas são as únicas coisas que a pessoa precisa se preocupar em procurar. Quando você olha para essa forma muito distinta e combinação de colors tão próximas, o que mais poderia ser? O pedaço que eu não pintei, o fundo branco, deveria ser considerado “qualquer coisa inconsistente”. Se tivesse um plano de fundo transparente, ele poderia passar por quase todas as outras imagens e você ainda conseguiria vê-las.

Eu gosto do desafio e queria dar uma resposta, o que resolve a questão, eu acho.

  1. Extrair resources (pontos chave, descritores como SIFT, SURF) do logotipo
  2. Combine os pontos com uma imagem do modelo do logotipo (usando o Matcher como Brute Force)
  3. Estimar as coordenadas do corpo rígido (problema PnP – SolvePnP)
  4. Estimar a posição da tampa de acordo com o corpo rígido
  5. Faça retroprojeção e calcule a posição do pixel da imagem (ROI) da tampa da garrafa (suponho que você tenha os parâmetros intrínsecos da câmera)
  6. Verifique com um método se a tampa está lá ou não. Se lá, então esta é a garrafa

A detecção da tampa é outro problema. Pode ser complicado ou simples. Se eu fosse você, simplesmente verificaria o histograma de colors no ROI para uma decisão simples.

Por favor, dê o feedback se eu estiver errado. Obrigado.

Há um monte de descritores de colors usados ​​para reconhecer objects, o artigo abaixo compara muitos deles. Eles são especialmente poderosos quando combinados com SIFT ou SURF. SURF ou SIFT sozinho não são muito úteis em uma imagem de lata de coca cola porque eles não reconhecem muitos pontos de interesse, você precisa da informação de cor para ajudar. Eu uso BIC (Border / Interior Pixel Classi fi catation) com SURF em um projeto e funcionou muito bem para reconhecer objects.

Descritores de colors para recuperação de imagens na Web: um estudo comparativo

Eu gosto da sua pergunta, independentemente de estar fora do tópico ou não: P

Um interessante aparte; Acabei de concluir um assunto no meu curso em que abordamos robótica e visão computacional. Nosso projeto para o semestre foi incrivelmente parecido com o que você descreveu.

Nós tivemos que desenvolver um robô que usasse um Xbox Kinect para detectar garrafas e latas de Coca-Cola em qualquer orientação em uma variedade de iluminação e condições ambientais. Nossa solução envolveu o uso de um filtro de passagem de banda no canal Hue em combinação com a transformação do círculo hough. Conseguimos restringir um pouco o ambiente (poderíamos escolher onde e como posicionar o robô e o sensor Kinect), caso contrário, usaríamos as transformadas SIFT ou SURF.

Você pode ler sobre a nossa abordagem no meu blog sobre o assunto 🙂

Você precisa de um programa que aprenda e melhore a precisão da sorting organicamente a partir da experiência.

Vou sugerir aprendizado profundo, com aprendizado profundo isso se torna um problema trivial.

Você pode treinar novamente o modelo inception v3 no Tensorflow:

Como Treinar a Camada Final do Ingresso para Novas Categorias .

Nesse caso, você estará treinando uma neural network convolucional para classificar um object como uma lata de coca-cola ou não.

Aprendizagem Profunda

Reúna pelo menos algumas centenas de imagens contendo latas de refrigerante, anote a checkbox delimitadora em torno delas como classs positivas, inclua garrafas de refrigerante e outros produtos de cola que os rotule como classs negativas, assim como objects randoms.

A menos que você colete um dataset muito grande, execute o truque de usar resources de aprendizado profundo para um dataset pequeno. O ideal é usar uma combinação de Support Vector Machines (SVM) com redes neurais profundas.

Depois de alimentar as imagens em um modelo de aprendizagem profunda previamente treinado (por exemplo, GoogleNet), em vez de usar a camada de decisão (rede) da neural network para fazer classificações, use os dados das camadas anteriores para treinar seu classificador.

OpenCV e Google Net: http://docs.opencv.org/trunk/d5/de7/tutorial_dnn_googlenet.html

OpenCV e SVM: http://docs.opencv.org/2.4/doc/tutorials/ml/introduction_to_svm/introduction_to_svm.html

Como alternativa a todas essas boas soluções, você pode treinar seu próprio classificador e tornar seu aplicativo robusto para erros. Como exemplo, você pode usar o Haar Training , fornecendo um bom número de imagens positivas e negativas do seu alvo.

Pode ser útil extrair apenas latas e pode ser combinado com a detecção de objects transparentes.

Estou alguns anos atrasado para responder a essa pergunta. Com o estado da arte levado aos limites pela CNN nos últimos 5 anos, eu não usaria o OpenCV para fazer essa tarefa agora! ( Eu sei que você queria especificamente resources OpenCv na questão ) Eu sinto que algoritmos de detecção de objects, como Faster-RCNNs, YOLO, SSD etc, aceitariam esse problema com uma margem significativa em comparação com os resources do OpenCV. Se eu resolvesse esse problema agora (depois de 6 anos !!) eu definitivamente usaria o Faster-RCNN .

Existe um pacote de visão computacional chamado HALCON da MVTec, cujas demos podem fornecer boas idéias de algoritmos. Há muitos exemplos semelhantes ao seu problema que você poderia executar no modo de demonstração e, em seguida, examinar os operadores no código e ver como implementá-los a partir de operadores existentes do OpenCV.

Eu usei este pacote para rapidamente prototipar algoritmos complexos para problemas como este e, em seguida, descobrir como implementá-los usando os resources existentes do OpenCV. Em particular para o seu caso, você poderia tentar implementar no OpenCV a funcionalidade embutida no operador find_scaled_shape_model . Alguns operadores apontam para o artigo científico sobre a implementação de algoritmos que pode ajudar a descobrir como fazer algo semelhante no OpenCV. Espero que isto ajude…

Se você está interessado em ser em tempo real, então o que você precisa é adicionar um filtro de pré-processamento para determinar o que é escaneado com o material pesado. Um bom filtro de pré-processamento rápido e em tempo real que permitirá que você escaneie coisas que são mais propensas a ser uma lata de coca-cola do que não antes de passar para coisas mais duvidosas: faça uma busca na imagem pelos maiores patches de cor que são uma certa tolerância longe do sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) da sua lata de coca-cola. Comece com uma tolerância de colors muito rígida e trabalhe até obter tolerâncias de colors mais brandas. Então, quando seu robô ficar sem tempo para processar o quadro atual, ele usará os flasks encontrados atualmente para seus propósitos. Por favor, note que você terá que ajustar as colors RGB no sqrt(pow(red,2) + pow(blue,2) + pow(green,2)) para obtê-los apenas para a direita.

Além disso, isso é muito idiota, mas você se certificou de ativar as otimizações do compilador -oFast quando compilou seu código C?

As primeiras coisas que eu procuraria são colors – como RED, ao fazer detecção de olhos vermelhos em uma imagem – há uma certa faixa de colors para detectar, algumas características sobre isso considerando a área ao redor e tal como a distância do outro olho se é de fato visível na imagem.

1: primeira característica é cor e vermelho é muito dominante. Depois de detectar o Coca Cola Red existem vários itens de interesse 1A: Qual é o tamanho desta área vermelha (é quantidade suficiente para determinar a verdadeira ou não – 10 pixels provavelmente não é suficiente), 1B: ela contém a cor do label – “Coca-Cola” ou onda. 1B1: Existe o suficiente para considerar uma alta probabilidade de que seja um label?

O item 1 é uma espécie de atalho – pré-processo se esse ranho existir na imagem – seguir em frente.

Então, se for esse o caso, eu posso utilizar esse segmento da minha imagem e começar a olhar um pouco mais para o zoom da área em questão – basicamente, olhar para as regiões / bordas circundantes …

2: Dado o ID da área da imagem acima em 1 – verifique os pontos circundantes [arestas] do item em questão. A: Existe o que parece ser uma parte superior ou inferior da lata – prata? B: Uma garrafa pode parecer transparente, mas também pode haver uma mesa de vidro – então há uma mesa / prateleira de vidro ou uma área transparente – se houver várias saídas possíveis. Uma garrafa pode ter uma tampa vermelha, pode não ser, mas ela deve ter a forma do topo da garrafa / parafusos de rosca ou uma tampa. C: Mesmo que isso falhe A e B, ele ainda pode ser uma lata – parcial. Isto é mais complexo quando é parcial, porque uma garrafa parcial / parcial pode parecer a mesma, portanto, um pouco mais de processamento de medição da borda da região Vermelha. a borda .. pequena garrafa pode ser semelhante em tamanho ..

3: Após a análise acima, é quando eu veria as letras e o logotipo da onda – porque eu posso orientar minha busca por algumas das letras nas palavras Como você pode não ter todo o texto devido a não ter todas as letras pode, a onda se alinharia em certos pontos ao texto (distância sábia) para que eu pudesse procurar essa probabilidade e saber quais letras deveriam existir naquele ponto da onda na distância x.

Talvez muitos anos atrasado, mas, no entanto, uma teoria para tentar.

A proporção de retângulo delimitador da região do logótipo vermelho para a dimensão global da garrafa / lata é diferente. No caso de Can, deve ser 1: 1, enquanto que será diferente em garrafa (com ou sem tampa). Isso deve facilitar a distinção entre os dois.

Atualização: A curvatura horizontal da região do logotipo será diferente entre a lata e a garrafa devido a sua respectiva diferença de tamanho. Isso pode ser especificamente útil se o seu robô precisar pegar a lata / garrafa e você decidir a pegada de acordo.