A ideia é perguntar uma vez por carta, não uma vez por quadro
Reconhecimento de cartas já funciona. Aponte um bom modelo para uma carta colecionável e o nome, a coleção e o número voltam em cerca de meio segundo. Onde a coisa desanda é ao aplicar isso a vídeo: não por um problema técnico, mas por puro volume.
Vídeo é, acima de tudo, repetição. Uma carta segurada por quatro segundos a quinze quadros por segundo são sessenta fotos da mesma carta, e perguntar sessenta vezes a um endpoint de identificação devolve sessenta vezes a mesma resposta. Todo pipeline ingênuo de streaming faz exatamente isso, e é por isso que análise de transmissão tem fama de ser coisa que só uma plataforma cheia de investimento consegue rodar.
O cardstream existe para apagar essa repetição. É uma pequena máquina de estados entre o seu vídeo e a chamada de reconhecimento, construída quase inteiramente com sinais que ela mesma calcula: a cena já se acomodou? Esta é a mesma carta de um instante atrás? Existe sequer uma carta no enquadramento? A chamada dispara quando uma carta realmente nova se acomodou, e em nenhum outro caso. Todo o resto roda em hardware que você já tem.
Uma chamada por carta, não por quadro
Uma hora de show a quinze quadros por segundo (o teto para o qual o projeto é verificado) e por volta de cem cartas distintas diante da lente. Duas formas de analisar exatamente o mesmo vídeo:
chamadas de identificação: uma por quadro, a maioria repetindo uma pergunta que acabou de ser respondida.
chamadas de identificação: uma por carta distinta, seja qual for a sua taxa de quadros e por mais tempo que você segure cada carta.
Cerca de 540 vezes menos chamadas, e a diferença não é truque de número: é o projeto inteiro. Segure uma carta parada e o contador não se mexe. Acelere a câmera e o contador não se mexe. O número de chamadas acompanha as cartas que você mostra, não as horas que você transmite.
Quem mantém isso rodando
Feito por quem coloca reconhecimento em produção
O cardstream nasce do time por trás do reconhecimento de colecionáveis da Ximilar. Os endpoints de identificação que ele chama são os mesmos que operamos em produção, então cliente e serviço são mantidos pelas mesmas pessoas.
O trabalho é feito às claras
O pacote completo está no GitHub: a máquina de estados, as duas formas de implantação e a interface no navegador. Nada da lógica de decisão fica escondido atrás de um serviço que você não pode inspecionar.
Testado sem rede
A suíte inteira roda offline, com dublês no lugar dos arquivos de modelo e das chamadas HTTP. Faça um fork do repositório em um notebook sem chave da API e você ainda consegue saber se quebrou alguma coisa.
O que o código não tem permissão para esquecer
-
Uma chamada por carta, não por quadro
Toda decisão de projeto começa aqui. Se um sinal pode ser calculado localmente, ele roda antes da única chamada que sai da máquina.
-
Uma única cópia da lógica de decisão
Quando chamar mora em exatamente um módulo. Não espalhado entre um driver, um transporte e uma interface onde três pessoas podem mudar de três jeitos: um arquivo, que se lê de uma sentada.
-
Drivers continuam finos
Agendamento, log e E/S são do driver; o que conta como carta nova é do motor. Trocar a forma como os quadros chegam nunca muda em silêncio quando uma chamada sai.
-
Nada bloqueia o loop de quadros
Decodificação, detecção, HTTP e disco rodam fora do loop. Uma identificação lenta descarta um quadro; nunca transforma a sua live em um atraso que só cresce.
-
Sem prisão a fornecedor, nem a nós
A chamada de identificação é uma etapa substituível atrás de uma interface pequena. Cada filtro, limitador e cache continua funcionando se você apontar para um lugar completamente diferente.
-
Hospedado por você, por padrão
Seu hardware, sua chave, seu vídeo. No modo cliente, um único recorte por carta distinta é a única coisa que sai da máquina, a não ser que você escolha salvar o show na sua própria conta da Ximilar.
O que as cartas nos ensinaram
Parte disso é contraintuitivo o bastante para deixarmos escrito onde a próxima pessoa vai encontrar: no repositório, ao lado do código que ele restringe.
Uma dica útil pode custar precisão
Dizer ao endpoint de que jogo é a carta desliga o classificador de sistema de escrita dele, que então cai para o alfabeto latino, e uma carta japonesa acaba casando em silêncio com a impressão em inglês. Medido, não chutado; por isso definir um jogo sem sistema de escrita é tratado como erro.
Um recorte um pouco folgado casa melhor
Um corte justo em volta da carta parece certo e funciona pior. O recorte que sai leva uma margem de propósito, porque um pouco de contexto vale mais que uma borda limpa.
Recuperar é melhor que fingir
Quando uma chamada passa do tempo limite, o pipeline se destrava e segue em frente em vez de esperar um resultado que talvez nunca chegue. A limitação está documentada no repositório, não escondida debaixo do tapete.
Leia, rode, mande patches
O repositório é público: um pacote Python instalável, com extras independentes, e uma interface no navegador. Os pesos do localizador e do embedding são nossos, treinados e publicados sob Apache-2.0 junto com as versões. Issues e pull requests são bem-vindos, principalmente relatos de shows reais, que revelam coisas que nenhuma bancada de testes pega.
O reconhecimento em si é o endpoint da Ximilar e sempre será; é a parte que tem o banco de dados de cartas por trás. Tudo ao redor é seu para mudar.
Código aberto. Hospedado por você. Sua live, seu stack.
Sem plataforma no meio do caminho, sem licença por assento: conecte a API da Ximilar ou seu próprio sistema de identificação e o cardstream chama uma vez por carta distinta, não uma vez por quadro. Não importa se você faz breaks na Whatnot, comanda um show no estilo Fanatics Live ou transmite seu próprio live commerce: coloque o cardstream para rodar hoje à noite no hardware que você já tem.