GestureDeck é um motor configurável de gestos para Linux. Ele usa OpenCV e MediaPipe para reconhecer uma mão pela webcam e controla volume, mute e reprodução de mídia sem bloquear a captura. Os comandos permitidos são definidos internamente; o arquivo TOML não executa comandos shell arbitrários.
| Gesto | Padrão | Ação |
|---|---|---|
Pinça (pinch) |
Polegar e indicador próximos | Volume contínuo |
Quatro dedos (four_fingers) |
Indicador, médio, anelar e mínimo estendidos; polegar dobrado | Play/pause |
Paz (peace) |
Indicador e médio estendidos; anelar e mínimo dobrados | Próxima faixa |
Três dedos (three_fingers) |
Indicador, médio e anelar estendidos; mínimo dobrado | Faixa anterior |
Polegar e mínimo (thumb_pinky) |
Somente polegar e mínimo estendidos | Alternar mute |
Palma aberta (open_palm) |
Cinco dedos estendidos | Ativar/desativar o controle |
Somente a mão escolhida em tracking.control_hand é processada. Com "any", a primeira mão retornada pelo MediaPipe é usada.
- Python 3.12
uvmediapipe==0.10.21e OpenCV, instalados pelouv
- webcam compatível com V4L2;
- PipeWire/WirePlumber e
wpctl, necessários para volume e mute; playerctl, necessário para play/pause e troca de faixas;pw-play, opcional, para os beeps;- sessão gráfica somente quando
interface.visible = true.
No Arch Linux, instale o suporte de mídia com:
pacman -S playerctlSe playerctl não existir, somente as ações de mídia ficam indisponíveis. Sem pw-play, apenas os beeps são desativados. Sem wpctl, volume e mute ficam indisponíveis. Cada ausência gera um único aviso no terminal.
uv sync --python 3.12
uv run gesturedeckUse Q ou Esc na janela para sair. Ctrl+C funciona nos modos visível e oculto. A câmera e o worker de ações são encerrados mesmo quando ocorre erro.
uv run gesturedeck # execução normal
uv run gesturedeck --config outro/config.toml # configuração alternativa
uv run gesturedeck --headless # força o modo sem janela
uv run gesturedeck --check # valida TOML e dependências
uv run gesturedeck --list-cameras # procura índices V4L2
uv run gesturedeck --versionEdite config.toml. Se o arquivo, uma seção ou uma opção conhecida não existir, o valor padrão correspondente é usado. Uma string vazia desativa um gesto, por exemplo peace = "".
Exemplo completo com os valores padrão:
[interface]
visible = true
[camera]
device = 0
width = 640
height = 480
fps = 30
[tracking]
process_every_n_frames = 2
detection_confidence = 0.65
tracking_confidence = 0.65
control_hand = "any"
[volume]
minimum_distance = 25
maximum_distance = 180
smoothing = 0.18
update_interval = 0.15
minimum_change = 0.03
[activation]
enabled = true
hold_seconds = 0.8
cooldown = 1.5
start_active = false
beep = true
[gestures]
pinch = "volume"
four_fingers = "play_pause"
peace = "next_track"
three_fingers = "previous_track"
thumb_pinky = "mute"
[gesture_detection]
stability_seconds = 0.35
loss_tolerance_seconds = 0.12
release_seconds = 0.25
default_cooldown = 1.0
[gesture_cooldowns]
play_pause = 1.0
next_track = 1.0
previous_track = 1.0
mute = 1.0
[feedback]
beep = true
display_seconds = 1.5
[performance]
camera_buffer = 1
config_reload_seconds = 1.0
[privacy]
blur_face = false
blur_strength = 51
blur_padding = 0.35
detect_every_n_frames = 5As únicas ações aceitas são volume, play_pause, next_track, previous_track, mute e a string vazia. pinch aceita somente volume ou vazio; ações discretas não aceitam volume.
stability_seconds: tempo durante o qual um gesto discreto precisa permanecer reconhecido;loss_tolerance_seconds: tolerância para uma falha curta de detecção sem perder o candidato;release_seconds: tempo sem o mesmo gesto antes de ele poder disparar novamente;default_cooldown: intervalo padrão entre execuções da mesma ação;gesture_cooldowns: sobrescreve o cooldown por ação;activation.hold_seconds: duração da palma aberta para alternar o estado;activation.cooldown: intervalo entre alternâncias de ativação.
A palma tem prioridade sobre todos os outros gestos e nunca dispara outra ação no mesmo instante. Depois de alternar, é preciso fechar ou retirar a mão. Enquanto INATIVO, todos os gestos são ignorados, exceto a palma aberta. A pinça é contínua e não usa a estabilidade dos gestos discretos.
O arquivo é monitorado durante a execução. Alterações válidas são aplicadas sem interromper o loop; um TOML inválido mantém a última configuração válida. Mudanças de câmera, parâmetros internos do MediaPipe ou buffer são informadas como dependentes de reinicialização.
Defina privacy.blur_face = true para desfocar rostos na janela. blur_strength controla a intensidade e deve ser um inteiro ímpar maior ou igual a 3. blur_padding amplia a área ao redor do rosto proporcionalmente: 0.0 usa apenas a caixa detectada, 0.35 adiciona 35% em cada lado e o máximo aceito é 2.0. detect_every_n_frames reduz o custo da detecção reutilizando a última região encontrada. O config.toml incluído já deixa essa opção ativada.
No modo visível são mostrados estado, candidato, gesto confirmado, ação executada, volume e progresso de estabilidade. Candidato, confirmação, sucesso e erro usam cores diferentes. Com interface.visible = false, nenhuma função de janela do OpenCV é chamada; encerre com Ctrl+C.
uv run python -m unittest discover -s tests -vOs testes não acessam webcam, áudio ou players reais.
- iluminação ruim, oclusões e mãos parcialmente fora do quadro reduzem a precisão;
- o detector facial pode falhar em perfil, pouca luz ou oclusões; o desfoque ajuda, mas não garante anonimato absoluto;
- os padrões são geométricos e podem exigir pequenos ajustes pessoais de pose;
- a lateralidade depende da classificação do MediaPipe e da imagem espelhada;
playerctlsó controla players compatíveis com MPRIS;- resolução e FPS solicitados dependem do suporte real da webcam;
- com
tracking.control_hand = "any"e duas mãos visíveis, a mão escolhida pode mudar conforme a ordem da detecção.
Distribuído sob a licença MIT. Consulte LICENSE.