William Zhang2026-09-28

Jeu de puzzle 3×3 à pincement à une main avec MediaPipe Hand Landmarker

Détection en temps réel de 21 points-clés de la main et de l'état de pincement d'une seule main à l'aide du modèle MediaPipe Tasks Hand Landmarker. « Pincement pouce + index » est directement mappé sur la sémantique « glisser / relâcher » — le joueur dessine la ROI et complète les opérations du puzzle par gestes de pincement devant la caméra ; toute la chaîne d'interaction fonctionne sans clavier, souris ni écran tactile.

CVHand TrackingGithub

Jeu de puzzle à pincement à une main basé sur reComputer-RK / Docker / RKNN / YOLO

https://github.com/doublelf/puzzle_game


Présentation du projet

Ce projet est un puzzle pur de 217 lignes : gesture.py détecte le pincement → drawing.RectDrawer recueille deux rectangles → puzzle_game.PuzzleGame les mélange en un 3×3 → la même machine à états utilise le pincement pour faire glisser le puzzle.


Démarrage rapide

1. Cloner le dépôt et entrer dans le répertoire

bash
git clone https://github.com/doublelf/puzzle_game 
cd puzzle_game

2. Installer les dépendances

bash
pip install -r requirements.txt

requirements.txt fixe quatre dépendances :

text
opencv-python>=4.8.0
mediapipe>=0.10.14
numpy>=1.26.0
Pillow>=10.4.0

3. Lancer le jeu

bash
python main.py                  # caméra 0 par défaut, miroir horizontal activé
python main.py --cam 1          # utilise la 2ᵉ caméra
python main.py --no-flip        # désactive le miroir horizontal
python main.py --no-landmarks   # désactive la surcouche de points-clés (activée par défaut)
python main.py --hide-trails    # désactive les traînées de gestes (activées par défaut)

Au lancement, vous verrez d'abord l'écran de menu « Pinch-Puzzle » ; appuyez sur n'importe quelle touche pour entrer dans le jeu.

4. Commandes

PhaseSaisie du joueurRéponse du programme
DRAWPincement pouce + index en glissant → relâcher pour dessiner le premier rectangleRectangle rempli en vert semi-transparent, en haut à gauche Draw rectangles: 1/2
DRAWRépéter une fois pour dessiner le deuxième rectangle2/2 → READY - generating puzzle..., passage automatique à PLAY
PLAYPincement pour sélectionner la tuile de puzzle la plus proche (bordure dorée pulsante)Toast Tile #N selected + indication drag toward blank tile
PLAYFaire glisser le bout du doigt près d'une case vide adjacenteLes deux tuiles clignotent en vert + Toast SWAP!, moves s'incrémente
PLAYLes 9 tuiles à leur place80 particules arc-en-ciel éclatent au centre + grand Toast SOLVED!
À tout momentR réinitialise le puzzle en coursRetour à la phase DRAW, rectangles effacés
À tout momentM retour au menuLa caméra continue de capturer, seule la boucle de jeu est fermée
À tout momentESC quitteLibère la caméra, ferme MediaPipe, détruit la fenêtre

Exécution sans caméra

Le recomputer-rk3576-devkit est livré sans caméra USB connectée par défaut. Ce projet embarque trois utilitaires permettant un fonctionnement de bout en bout même sans caméra :

tools/verify_all.py — suite de vérification en 8 étapes

bash
cd /home/seeed/hand/puzzle_game
python3 -m tools.verify_all

Imprime chaque étape :

  • Importation des modules (gesture / drawing / puzzle_game / overlay / utils)
  • Fonctions géométriques et texte de utils
  • RectDrawer.update(None) ne lève pas d'exception
  • shuffle_solvable produit un plateau légal
  • Vrai MediaPipe Hand Landmarker chargé sur aarch64 (XNNPACK delegate, ~110 ms d'échauffement)
  • HandOverlay.add_event + rendu
  • La pipeline synthétisée tourne 60 images sans erreur

tools/run_synthetic.py — rendu hors-ligne en PNG

bash
python3 -m tools.run_synthetic --frames 180 --out /tmp/puzzle_demo
ls /tmp/puzzle_demo | wc -l      # → 180

Pilote la pipeline complète PuzzleGame + HandOverlay et écrit chaque image dans out/puzzle_XXXX.png. Dans un environnement sans caméra, parcourez les images avec feh / eog / un visualiseur d'images, ou assemblez les PNG en mp4 avec ffmpeg :

bash
ffmpeg -framerate 30 -i /tmp/puzzle_demo/puzzle_%04d.png -c:v libx264 -pix_fmt yuv420p puzzle.mp4

tools/synthetic_source.py + tools/fake_tracker.py

Une source vidéo synthétisée et un HandTracker synthétisé, équivalents en interface à cv2.VideoCapture / gesture.HandTracker. Pour basculer plus tard sur une vraie caméra, il vous suffit de remplacer ces deux lignes :

python
cap = cv2.VideoCapture(args.cam)               # remplace SyntheticHandSource
tracker = HandTracker(num_hands=2)              # remplace SyntheticHandTracker

tools/run_synthetic.py devient alors un script pilote à caméra réelle.