Detecção / rastreamento de retângulos usando OpenCV

O que eu preciso

Atualmente, estou trabalhando em um tipo de jogo de realidade aumentada. O controle que o jogo usa (eu estou falando sobre o dispositivo de entrada físico aqui) é um pedaço de papel retangular e mono colorido. Eu tenho que detectar a posição, rotação e tamanho desse retângulo no fluxo de captura da câmera. A detecção deve ser invariante em escala e invariante em rotação ao longo dos eixos X e Y.

A invariância da balança é necessária caso o usuário mova o papel para longe ou em direção à câmera. Não preciso saber a distância do retângulo para que a invariância da escala se traduza em invariância do tamanho.

A invariância de rotação é necessária caso o usuário incline o retângulo ao longo do eixo X e / ou Y local. Essa rotação altera a forma do papel de retângulo para trapézio. Nesse caso, a caixa delimitadora orientada a objeto pode ser usada para medir o tamanho do papel.

O que eu fiz

No início, há uma etapa de calibração. Uma janela mostra o feed da câmera e o usuário precisa clicar no retângulo. Ao clicar, a cor do pixel para o qual o mouse está apontando é considerada como cor de referência. Os quadros são convertidos em espaço de cores HSV para melhorar a distinção de cores. Eu tenho 6 controles deslizantes que ajustam os limites superior e inferior para cada canal. Esses limites são usados para binarizar a imagem (usando o comando opencvinRange função).
Depois disso, estou corroendo e dilatando a imagem binária para remover o ruído e unir os nerby (usando o opencverode edilate funções).
O próximo passo é encontrar contornos (usando o comando opencvfindContours função) na imagem binária. Esses contornos são usados para detectar os menores retângulos orientados (usando o opencvminAreaRect função). Como resultado final, estou usando o retângulo com a maior área.

Uma breve conclusão do procedimento:

Pegue um quadroConverta esse quadro em HSVBinarize-o (usando a cor que o usuário selecionou e os limites dos controles deslizantes)Aplicar operações de transformação (corroer e dilatar)Encontre contornosObtenha a menor caixa de espuma orientada de cada contornoPegue a maior dessas caixas delimitadoras como resultado

Como você deve notar, não aproveito o conhecimento sobre a forma real do artigo, simplesmente porque não sei como usar essas informações corretamente.

Também pensei em usar os algoritmos de rastreamento do opencv. Mas havia três razões que me impediram de usá-las:

Invariância de escala: tanto quanto eu li sobre alguns algoritmos, alguns não suportam escalas diferentes do objeto.Previsão de movimento: alguns algoritmos usam a previsão de movimento para obter melhor desempenho, mas o objeto que estou rastreando se move completamente aleatório e, portanto, imprevisível.Simplicidade: estou apenas procurando um retângulo monocromático em uma imagem, nada sofisticado como rastreamento de carro ou pessoa.

Aqui está uma captura - relativamente - boa (imagem binária após corroer e dilatar)

e aqui é ruim

A questão

Como posso melhorar a detecção em geral e principalmente para ser mais resistente a mudanças de iluminação?

Atualizar

Aqui são algumas imagens brutas para teste.

Você não pode simplesmente usar material mais espesso?
Sim, eu posso e já o faço (infelizmente não posso acessar essas peças no momento). No entanto, o problema ainda permanece. Mesmo se eu usar material como papelão. Não é dobrado tão fácil quanto o papel, mas ainda é possível dobrá-lo.

Como você obtém o tamanho, a rotação e a posição do retângulo?
ominAreaRect função de opencv retorna umRotatedRect objeto. Este objeto contém todos os dados que eu preciso.

Nota
Como o retângulo é monocromático, não há possibilidade de distinguir entre superior e inferior ou esquerda e direita. Isso significa que a rotação está sempre na faixa[0, 180] o que é perfeitamente bom para meus propósitos. A proporção dos dois lados do reto é semprew:h > 2:1. Se o retângulo fosse um quadrado, o alcance da rotação mudaria para[0, 90], mas isso pode ser considerado irrelevante aqui.

Conforme sugerido nos comentários, tentarei a equalização do histograma para reduzir os problemas de brilho e dar uma olhada no ORB, SURF e SIFT.

Vou atualizar o andamento.

questionAnswers(2)

yourAnswerToTheQuestion