Ricardo Henriques - Ricardo Henriques: ‘É preciso se adaptar ao mundo do conhecimento desde ...
Ricardo Henriques: ‘É preciso se adaptar ao mundo do conhecimento desde ...

Rastreamento visual com o trabalho de Ricardo Henriques: guia prático

O nome ricardo henriques aparece frequentemente quando se estuda tracking visual moderno, especialmente a vertente que une filtros de correlação e redes convolucionais. Ele é investigador no Departamento de Electrónica, Telecomunicações e Informática da Universidade de Coimbra e os seus contributos mais citados estão na área dos trackers CSRT, KCF e das abordagens baseadas em redes Siamese para tracking de objectos. Se estás a tentar usar isso na prática, o caminho mais directo passa por OpenCV e pelo módulo de tracking integrado que pullou muitos desses algoritmos da comunidade académica.

Como começar com os trackers inspirados no trabalho de ricardo henriques

A instalação básica é simples. Num ambiente com Python 3.9 ou superior: ``` pip install opencv-python ``` Não precisas de bibliotecas separadas para CSRT ou KCF. Eles vêm dentro do próprio OpenCV. A versão mínima recomendada é a 4.5+, porque versões anteriores têm implementações incompletas do discriminative correlation filter e podem falhar silenciosamente em edge cases de scale variation. O fluxo geral funciona assim: carregas um frame inicial, defines uma bounding box manualmente, crias o tracker com o método certo e depois fazes update frame a frame. Parece trivial, mas a escolha do algoritmo faz diferença extrema dependendo do cenário. Para objectos com deformação moderada e oclusões curtas, o CSRT costuma ser o mais estável. Para movimento rápido com pouca texturação, o KCF pode perder o objecto logo no primeiro frame de translação brusca.

O código mínimo para testar fica assim:

👉 Clique no botão abaixo para saber mais sobre o assunto!

``` import cv2 import numpy as np video = cv2.VideoCapture('cena_teste.mp4') ok, frame = video.read() bbox = cv2.selectROI('Tracker', frame, False) tracker = cv2.TrackerCSRT_create() tracker.init(frame, bbox) while True: ok, frame = video.read() if not ok: break ok, bbox = tracker.update(frame) x, y, w, h = [int(v) for v in bbox] cv2.rectangle(frame, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.imshow('Tracker', frame) if cv2.waitKey(1) & 0xFF == ord('q'): break ```

Isto funciona na maioria dos casos de teste rápidos, mas não é robusto para produção. O problema real começa quando a iluminação muda abruptamente ou quando o objecto sai do quadro e volta segundos depois.

Eu fiz um projecto interior com câmara fixa e iluminação fluorescente que oscilava com o ciclo de temperatura do ar condicionado. O CSRT perdia o rastreio a cada 40 segundos, aparentemente sem motivo. A solução que funcionou foi fazer um re-seed do tracker com deteção de novo objecto por matching num raio de 30 pixeis à volta da posição prevista quando o score de confiança caía abaixo de 0.3. Não é bonito, mas resolveu o problema sem recorrer a redes pesadas. O parâmetro crítico é o threshold de confiança — o valor por defeito no OpenCV é arbitrário e precisa de calibração por cena.

Por dentro dos algoritmos: o que realmente diferencia CSRT de KCF

Ambos são trackers baseados em discriminative correlation filters, mas a diferença principal está no kernel. O KCF usa um kernel lineal, o que é rápido mas assume que o objecto se comporta de forma aproximadamente translacional dentro da janela. O CSRT introduz um kernel Gaussiano com auto-parâmetros de escala e orientação, o que lhe permite lidar melhor com variações de tamanho e ligeiras rotações. O trade-off é que o CSRT é cerca de 2 a 3 vezes mais lento em termos de FPS no mesmo hardware. Outro ponto que muita gente perde: ambos os trackers operam num espaço de características calculado a partir de HOG (Histogram of Oriented Gradients). Isso significa que objectos com textura muito baixa — uma parede lisa, um carro branco num dia de nevoeiro — simplesmente não têm assinatura HOG suficiente para o filtro distinguir o alvo do fundo. Neste cenário, o tracker falha de forma consistente e não há ajuste de hiperparâmetros que resolva. A alternativa aqui é usar um detector de interest points separado e fundir com o tracking, ou migrar para abordagens Siamese como SiamFC ou SiamRPN, que aprendem características hierárquicas diretamente da imagem em vez de dependerem de handcrafted features. O trabalho que o Ricardo Henriques e colegas publicaram sobre escalonamento multi-banda do tracker adicionou outra camada útil: em vez de processar só a imagem original, o CSRT calcula a correlação em múltiplas escalas simultaneamente. Isso ajuda quando o objecto se afasta ou aproxima rapidamente, mas custa computação adicional e nem sempre justifica o ganho se o objecto já estiver bem delimitado desde o início.

O que ninguém avisa sobre a bounding box inicial

A qualidade da bounding box define tudo. Se incluires demasiado fundo ao redor do objecto, o filtro vai aprender também texturas do cenário e confundir-se quando partes semelhantes aparecem noutro contexto. Eu perdi duas tardes num projeto de contagem de caixas em fita transportadora porque a bbox inicial puxava 40% de fundo. Reduzir a margem para algo em torno de 5 a 10% do tamanho do objecto resolveu o problema na mesma pipeline. O tracker fica mais sensível a oclusões, mas ganha precisão em condições normais.

Parametros úteis para ajustar no CSRT:

- channel_indexes: por defeito é (0, 1, 2) para RGB. Se a tua câmara fornecer apenas intensidade ou canais transformados, ajusta isto. Usar só o canal relevante pode melhorar performance em cenários de baixo contraste. - compress_factor: controlo a resolução interna do tracker. Valores mais altos aceleram o processamento mas reduzem a precisão em detalhes finos. Para tracking a 60fps com objectos pequenos, 8 a 12 é geralmente o ponto certo. Valores acima de 20 começam a degradar seriamente. - kernel_sigma: afeta a sensibilidade a mudanças de escala. Valores altos tornam o tracker mais tolerante a variações de tamanho mas mais propenso a drift. Em testes comparativos meus, 0.5 foi o valor que melhor equilibrou drift e precisão para objectos a distância média.

Cenários onde estes trackers falham de forma previsível

A primeira categoria é oclusão total. Quando o objecto some completamente do quadro por mais de dois segundos, o tracker assume que ainda está presente e continua a predizer posições que não correspondem a nada. Não há fallback automático no OpenCV. Tens de detetar o reset manualmente, seja por queda de resposta do filtro, seja por deteção de movimento no fundo que indica ausência do alvo. A segunda é o problema de similaridade distractor. Se houver outro objecto visualmente semelhante ao alvo no campo de visão, o correlacionador pode colapsar para o distractor e nunca recuperar sem intervenção externa. Isto é particularmente em linhas de montagem onde peças idênticas passam regularmente. A solução prática é manter uma janela de memory menor ou adicionar um classificador leve de verificação periódica. A terceira, e talvez mais importante, é que trackers como CSRT e KCF não aprendem durante o operation. Eles inicializam com um frame e depois aplicam filtros fixos. Se o objecto mudar de aparência de forma abrupta — uma caixa pintada de vermelho que é virada e mostra o lado azul, por exemplo — o tracker não se adapta. A memória do filtro é estática e isso é uma limitação estrutural, não um bug. Para cenários com mudança de aparência significativa, é preferível usar trackers baseados em redes Siamese que atualizam o modelo de forma contínua. Se precisas de tracking com adaptação de aparência em tempo real, olha para a biblioteca Deep-MOT ou para o repositório oficial do SiamRPN++ disponível no GitHub. São mais pesados e requerem GPU razoável, mas compensam em complexidade de cena onde trackers clássicos falham sistematicamente.