YOLO-people-projection
Uma câmara observa pessoas num chão. O computador calcula onde cada uma está, em metros, envia isso por OSC, e um projetor desenha no chão exatamente debaixo dos seus pés.
Este guia mostra como funciona: a montagem física, a calibração que alinha tudo, e como os ficheiros se alimentam uns aos outros. Os comandos passo a passo estão no README.
1. Como funciona, numa imagem
Cada imagem da câmara passa pela mesma cadeia. O YOLO, um modelo de reconhecimento de imagem, encontra cada pessoa e os seus tornozelos. Os tornozelos são convertidos de píxeis da câmara para metros no chão. Um seguidor (tracker) acompanha cada pessoa de imagem para imagem e dá-lhe um id. As posições saem como mensagens OSC, que qualquer programa pode receber. Um sketch de Processing desenha em metros, e o seu desenho é ajustado ao projetor para aparecer onde as pessoas estão.
track_osc.py. Em baixo: um sketch de Processing (a aba People, o seu desenho, a aba Projection). Qualquer outro programa que fale OSC pode ocupar o lugar da linha de baixo.2. A montagem física
É preciso um projetor apontado para o chão, uma câmara que veja toda a área projetada, e um retângulo marcado com fita no chão, dentro de ambos. Nada precisa de ficar de frente: a calibração corrige os ângulos da câmara e do projetor.
1Projetor
Aponte-o para o chão e ligue-o como segundo ecrã (estendido, não duplicado). Tome nota da sua resolução e da sua posição no ambiente de trabalho, p. ex. 1280x800 em 1920,0.
2Câmara
Monte-a alta, a olhar para baixo, a ver toda a área projetada. Serve qualquer câmara, resolução ou cadência: uma webcam, uma câmara USB melhor, ou a imagem a cores de uma câmara de profundidade.
3Fita
Marque os quatro cantos de um retângulo dentro de ambas, meça a largura e a altura em metros, e lembre-se de qual é a marca 1.
4Escuridão
Calibre com a sala o mais escura possível, para a câmara conseguir ler os marcadores projetados.
3. Três maneiras de medir o chão
O mesmo ponto do chão tem três endereços diferentes: um píxel na imagem da câmara, um píxel na imagem do projetor, e uma posição em metros a partir da marca 1. A câmara e o projetor veem o chão de lado, por isso os seus píxeis esticam-se de maneira diferente ao longo dele. A calibração mede como converter entre os três, sob a forma de duas homografias: transformações que levam qualquer superfície plana vista de um ângulo para a mesma superfície vista de outro.
4. Calibração
A calibração faz-se com dois scripts, depois de saber que câmara usar. Repita-a sempre que a câmara ou o projetor mudarem de sítio.
Escolher a câmara
As câmaras escolhem-se por número. O cameras.py lista as que o computador vê, e --snapshots guarda uma imagem de cada, para as distinguir:
$ python cameras.py --snapshots
camera 0: 1280x720 (V4L2), average brightness 104, saved camera_0.jpg
camera 2: 1920x1080 (V4L2), average brightness 97, saved camera_2.jpg
Depois calibre com esse número. Peça uma resolução, uma cadência ou imagens comprimidas se quiser mais do que a câmara dá por omissão:
python calibrate.py --source 2 --proj-pos 1920,0 --proj-size 1280x800 --floor-size 2.4x1.4
python calibrate.py --source 2 --width 1920 --height 1080 --fps 60 --fourcc MJPG \
--proj-pos 1920,0 --proj-size 1280x800 --floor-size 2.4x1.4
A câmara, a resolução, e a cadência e o formato se os pediu, ficam guardados com a calibração, por isso tudo o que vem depois as usa sem ser preciso dizer-lhe. Uma câmara por HDMI (uma DSLR ou uma câmara de vídeo) funciona da mesma maneira, através de um dispositivo de captura HDMI para USB.
calibrate.py: câmara, projetor e chão
1Marcadores
O projetor mostra uma grelha de marcadores ArUco quadrados, cada um com o seu padrão. A câmara encontra-os (carregue em ESPAÇO) e, como se sabe a posição de cada marcador no projetor, isto liga os píxeis da câmara aos píxeis do projetor.
2Chão
O projetor fica branco. Clique nas quatro marcas de fita na imagem da câmara, pela ordem. Com as medidas do retângulo, isso liga os píxeis da câmara a metros e, através do passo 1, os metros a píxeis do projetor.
3Verificação
O projetor desenha uma grelha em metros. Se o contorno ficar em cima da fita, carregue em s para guardar.
foot_calibrate.py: onde assentam os pés
O YOLO encontra tornozelos, não o ponto onde o pé toca no chão, e visto de lado a diferença é de vários centímetros. O projetor mostra alvos um de cada vez; põe-se em cada um com a cruz entre os pés, e o script aprende uma pequena correção entre o sítio onde foi detetado e o sítio onde estava realmente. Nos testes, o erro passou de cerca de 30 cm para cerca de 4 cm.
O que fica guardado
calibration.json
├── floor width_m, height_m o retângulo de fita
├── cameras
│ └── cam0 source, resolution que câmara, a que resolução
│ fps, fourcc se os pediu
│ H_cam_to_floor píxeis da câmara → metros
│ foot_correction do foot_calibrate.py
└── projectors
└── proj0 resolution, position que ecrã é
H_floor_to_proj metros → píxeis do projetor
É específico do seu espaço, por isso não faz parte do repositório. Os sketches de Processing encontram-no na sua própria pasta ou na mais próxima acima dela.
5. Pôr uma peça a funcionar
Correm dois programas lado a lado: o seguidor, e o que transformar as posições numa peça.
track_osc.py --simulate 3 envia três pessoas imaginárias a passear pelo chão; --simulate 2 --with-camera junta duas às reais.O follow.py é o teste tudo-em-um: segue as pessoas e desenha ele próprio um círculo debaixo de cada uma, diretamente no projetor, sem precisar de sketch nem de OSC. Use-o para confirmar a calibração e o seguimento antes de pôr uma peça a funcionar.
6. As mensagens OSC
Uma mensagem por cada pessoa seguida, sempre que o seguidor processa uma imagem: tantas vezes quanto a câmara e o computador permitirem, ou conforme --max-fps.
/person id x y
| Argumento | Tipo | Significado |
|---|---|---|
id | int | o mesmo enquanto a pessoa estiver a ser seguida |
x | float | metros a partir da marca 1 ao longo da largura, de 0 a W |
y | float | metros a partir da marca 1 ao longo da altura, de 0 a H |
Não se envia nada quando alguém sai. Esqueça quem não tiver dado notícias há quase um segundo. Se o seguidor perder alguém e o voltar a encontrar dentro de uns segundos, perto de onde o perdeu, volta a enviá-lo com o mesmo id: guarde a pessoa durante esse tempo se quiser que volte como ela mesma.
O README mostra como recebê-las no TouchDesigner, Max, Pure Data e Python.
7. Como os ficheiros encaixam
As setas vão de cada ficheiro para os ficheiros que ele usa.
pipeline.py é o coração do seguimento, usado pelo follow.py e pelo track_osc.py; o foot_calibrate.py usa a sua deteção dos pés e o models.py diretamente. (O p_track.py, um teste rápido do YOLO, usa só o cameras.py e o models.py.)| Ficheiro | O que faz |
|---|---|
calibrate.py | Marcadores, cliques nas marcas de fita e uma verificação: cria o calibration.json. |
foot_calibrate.py | Alvos para pisar: acrescenta a correção dos pés. |
follow.py | Círculos debaixo das pessoas, desenhados diretamente no projetor, para confirmar o seguimento. |
track_osc.py | O seguidor para pôr uma peça a funcionar: envia OSC, sem janela de projetor. --simulate para pessoas imaginárias. |
pipeline.py | Uma imagem da câmara → pés (o ponto médio entre os tornozelos, ou a base do retângulo da pessoa se os tornozelos não forem claros) → metros no chão, dentro da fita → seguimento. |
models.py | Carrega o YOLO no melhor hardware desta máquina: uma placa NVIDIA, se houver, senão o processador, com um limite de threads para deixar espaço ao sketch. |
tracking.py | Associa os pés de cada imagem às pessoas já conhecidas, suaviza o seu movimento e mantém os seus ids quando falham por um momento. |
cameras.py | Imagens de qualquer câmara, escolhida pelo número, ou de um ficheiro de vídeo, tudo igual para o resto. Corra-o para listar as suas câmaras. |
calib_utils.py | A matemática da calibração (homografias), o padrão de marcadores e funções para as janelas. |
osc.py | Constrói e envia as mensagens OSC, sem nenhum pacote extra. |
recording.py | As teclas c / p / f gravam a imagem da câmara, a imagem do projetor ou o ecrã, em recordings/. |
processing/…/People.pde | Recebe o OSC, faz cada pessoa deslizar entre mensagens e fá-la aparecer e desaparecer gradualmente. |
processing/…/Projection.pde | Encontra a calibração e o ecrã do projetor, e ajusta o canvas do sketch, em escala de metros, ao chão. |