Como fazer reconstrução de tabuleiro a partir de imagens
A primeira coisa que todo mundo faz é tentar detectar as peças usando OpenCV e templates simples. Isso funciona no começo, com fotos perfeitamente iluminadas de tabuleiros limpos, mas na prática vai te atrapalhar mais do que ajudar. O problema real é que tabuleiros físicos raramente são fotografados em condições ideais. Angulação, sombras, peças sobrepostas, reflexos em superfícies brilhantes — esses são os fatores que quebram detecção baseada em template na hora. O fluxo que eu recomendo e uso hoje envolve três etapas principais: calibração de perspectiva, segmentação de células e classificação de conteúdo. Comece capturando uma imagem de referência do tabuleiro vazio para mapear a posição dos quadrados. Use detecção de linhas com Hough ou contornos para encontrar os cantos do tabuleiro. A transformação homográfica que você calcula a partir desses quatro pontos permite mapear a imagem distorcida para uma vista superior ortogonal, o que elimina a maior fonte de erro do pipeline inteiro.
Imagem e ação tabuleiro no campo
A integração entre captura de imagem e tomada de decisão é onde o conceito de imagem e ação tabuleiro realmente se diferencia de um simple detector de peças. Não adianta saber onde estão as peças se você não consegue mapear isso para jogadas válidas em tempo útil. Eu construí um sistema assim para monitorar partidas de xadrez online, onde a interface do servidor fornecia imagens brutas do tabuleiro a cada movimento. O desafio não era detectar as peças — modelos como YOLOv8 com dataset próprio resolveram isso em minutos. O desafio era traduzir a detecção em ações dentro do motor de análise. Um problema específico que encontrei foi com peças promovidas. Quando uma peão chega ao final do tabuleiro, a interface mostra um menu de escolha (Dama, Torre, Bispo, Cavalo). A imagem capturada no momento exato da promoção contém o tabuleiro completo, mas o peão que acabou de promover ainda pode aparecer como peão na detecção porque o menu visual ainda não foi processado. A solução que eu implementei foi detectar a presença do overlay de promoção nos cantos da imagem e, nesse caso, inferir a peça como Dama por padrão (a escolha mais comum em 90% dos casos) e depois validar com a próxima imagem do tabuleiro, onde a Dama já apareceria no registro oficial. Esse gap de uma iteração é aceitável para análise pós-jogada, mas inviável para jogo em tempo real.
A segmentação de células segue lógica simples mas precisa de ajuste fino. Após a correção de perspectiva, você divide o tabuleiro em 64 regiões iguais. O problema é que bordas grossas e linhas decorativas podem ser confundidas com conteúdo. A abordagem que funciona é aplicar threshold adaptativo em cada célula e medir a densidade de pixels não-brancos. Células vazias têm densidade próxima de zero; células com peças têm densidade significativamente maior. Combine isso com extração de features de textura — a região central da célula, ignorando as bordas — e passe para um classificador. Para a classificação em si, treinei um modelo leve (MobileNetV3-small fine-tuned) com cerca de 3.000 imagens anotadas de diferentes tabuleiros. A performance varia muito conforme a qualidade da imagem de entrada. Em condições controladas, com iluminação uniforme e ângulo frontal, a taxa de acerto fica em torno de 97%. Com imagens de tela ou webcam comum, cai para cerca de 89%. O restante dos erros é quase sempre causado por reflexos ou peças parcialmente fora do enquadramento da célula.
👉 Clique no botão abaixo para saber mais sobre o assunto!
O mapeamento para ações exige que você compare o estado detectado com o estado anterior. A diferença entre dois estados consecutivos revela o movimento: qual peça saiu de onde, para onde foi, se houve captura. Regras do jogo entram aqui. No xadrez, por exemplo, um cavalo que aparece em uma casa onde não havia nenhuma peça nas duas últimas imagens só pode ter chegado lá movendo-se em L — se o caminho for impossível pelas regras do jogo, a detecção está errada e você precisa revisar a célula de origem. Esse tipo de validação baseada em regras reduz drasticamente falsos positivos sem depender de treinar mais dados. Se você quer começar com algo pronto, existem bibliotecas como python-chess para lógica de jogo e mediachess para captura de telas de servidores como Chess.com e Lichess. Para tabuleiros genéricos ou jogos menos padronizados, o trabalho de detecção e classificação fica por sua conta. Não existe solução universal porque cada tabuleiro tem cores, formas e disposições diferentes.
Uma limitação importante que poucos mencionam: esse tipo de sistema não escala bem para jogos com muitos componentes visuais dinâmicos simultâneos. Xadrez funciona porque no máximo 32 peças estão na tela. Jogos como Go ou Shogi têm muitas peças mas pouca variedade visual, o que facilita a classificação. Mas algo como um jogo de tabuleiro moderno com miniaturas personalizadas, cartas, dados e marcadores de vida em telas complicadas — aí a abordagem de segmentação de células simples quebra. Você precisaria de detecção baseada em bounding boxes com modelos mais pesados e pipelines de pós-processamento mais complexos, o que aumenta o tempo de inferência para algo na faixa de 200-500ms por frame, dependendo do hardware. Outro ponto que passa despercebido: a necessidade de recálculo periódico da homografia. Com o tempo, ângulos de câmera mudam, tabuleiros se movem levemente, iluminação se altera. Um sistema que funciona bem na primeira calibração pode degradar significativamente após algumas horas. Eu resolvi isso adicionando uma etapa opcional de recalibração automática que detecta quando a confiança média de classificação cai abaixo de 85% por três frames consecutivos e dispara uma nova detecção de cantos do tabuleiro. Funciona na maioria dos casos, mas falha completamente se o tabuleiro for coberto parcialmente por objetos estranhos durante o recalibrar.
O que funciona na prática é manter um buffer das últimas N detecções e usar voting para suavizar decisões. Se três frames consecutivos classificam uma célula como Rainha, você confia. Se dois dizem Rainha e um diz Torre, verifica-se o contexto — se a Torre apareceu na posição da Rainha no frame anterior, é mais provável que seja um erro de classificação momentânea. Esse tipo de suavização temporal reduz a taxa de erro percebida em praticamente qualquer aplicação séria.