diff --git a/CONTEXT.md b/CONTEXT.md index e9c2257..93adc17 100644 --- a/CONTEXT.md +++ b/CONTEXT.md @@ -80,9 +80,10 @@ Modèles principaux : | Modèle | Rôle | |---|---| | `Configuration` | Config globale active (caméra, GRBL, tracking, calibration) | -| `MultiWell` | Plaque multi-puits (position HG/HD/BG/BD, grille 6×4, pas XY) | +| `MultiWell` | Plaque multi-puits (position HG/HD/BG/BD, grille 6×4, pas XY, crop_radius) | | `Well` | Puit individuel (nom Ai..Di) | -| `WellPosition` | Position XY mm d'un puit dans un MultiWell + px_per_mm | +| `WellPosition` | Position XY mm d'un puit dans un MultiWell + px_per_mm (calibration optique caméra) | +| `VideoPlate` | Vidéo plaque entière associée à un MultiWell — champs : `px_per_mm` (échelle vidéo ~15 px/mm), `x_origin_mm` / `y_origin_mm` (origine CNC stable, indépendante de la calibration) | | `Experiment` | Session de capture sur un MultiWell (durée, début/fin) | | `Session` | Groupe d'expériences avec planification (ClockedSchedule one-shot) | | `SessionExperiment` | Liaison Session ↔ Experiment | @@ -109,13 +110,14 @@ Modèle `ExperimentConfig` : paramètres de tracking par puit (px_per_mm, fps, s |---|---| | `grbl.py` | Pilotage CNC via port série (G-code, homing, déplacement XY) | | `grbl_simulator.py` | Simulateur GRBL pour dev sans matériel | -| `capture_interface.py` | Interface abstraite de capture | +| `capture_interface.py` | Interface abstraite de capture — crop circulaire, edge enhance, debug overlay, tracking | | `picamera2_capture.py` | Capture ArduCam via Picamera2 | | `webcam_capture.py` | Capture webcam via OpenCV | | `videofile_capture.py` | Lecture fichier vidéo (test/sim) | +| `videoplate_capture.py` | Capture par crop dynamique dans une vidéo plaque entière — position GRBL → région extraite, hot swap vidéo, plein cadre à l'origine | | `planarian_tracker.py` | Tracking multi-individus : MOG2 + algorithme hongrois (`scipy`) | | `planarian_metrics.py` | Métriques par frame et summary (mobilité, thigmo, photo, chemo, social) | -| `tube_aligner.py` | Alignement et calibration optique du tube | +| `tube_aligner.py` | Détection HoughCircles + CLAHE, calibration optique, plage rayon configurable (`set_radius_range`) | | `circular_crop.py` | Découpe circulaire des images de puit | | `reductstore.py` | Interface ReductStore (stockage/lecture frames time série) | | `system_stats.py` | Stats système (CPU, RAM, disque — affichage dashboard) | @@ -190,6 +192,65 @@ python3 planarian_sim.py --count 5 --photo-mode fixed --photo-x 0.2 --photo-y 0. --- +## Mode capture vidéo plaque (`capture_type == 'video'`) + +Alternative à la caméra ArduCam : une **vidéo de la plaque entière** enregistrée une fois, +rejouée en boucle pendant les scans. Adapté aux labos sans Raspberry Pi ou pour tests hors matériel. + +### Flux +``` +VideoPlateCapture.capture_frame() + → lit la frame courante de la vidéo + → extrait un carré 2r×2r centré sur (GRBL_x, GRBL_y) converti en pixels + → si GRBL à (0,0) : retourne la frame entière (vue plaque) + → sinon : retourne le crop du puit courant +→ process_frame() + → edge_enhance (optionnel, CLAHE + Canny overlay vert) + → TubeAligner.detect_tube() (optionnel, debug HoughCircles) + → crop circulaire (optionnel) +``` + +### Calibration vidéo +- `VideoPlate.px_per_mm` : échelle de la vidéo (~15 px/mm) — **différent** de `WellPosition.px_per_mm` (~50 px/mm, optique caméra) +- `VideoPlate.x_origin_mm` / `y_origin_mm` : position CNC correspondant au pixel (0,0) de la vidéo — **stable**, jamais modifiée par la calibration des puits +- `MultiWell.crop_radius` : rayon du crop en pixels — contrôle la taille de la vue par puit + +### Contrôles calibration UI (boutons) +| Bouton | Action | +|---|---| +| Debug | Active `TubeAligner.debug` — détection HoughCircles en continu | +| Overlay | Affiche/masque les annotations de détection sans couper la détection | +| Contours | Active edge enhance (CLAHE + Canny overlay vert) sur la frame propre | +| Recadrer | Active le crop circulaire + navigue vers la position Base (mode vidéo) | + +### `TubeAligner.set_radius_range(min_ratio, max_ratio)` +Ajuste la plage de recherche HoughCircles en fraction de `min(w,h)` : +- Mode caméra : `0.26–0.37` (tube occupe ~30% du champ) +- Mode vidéo : `0.38–0.47` (puit remplit le crop, ratio ~0.43–0.50) + +--- + +## Déploiement réseau isolé (labo sans internet) + +``` +GitHub ←→ Portable (internet) ←→ Routeur OpenWrt ←→ Machine labo (SSH) +``` + +Mise à jour sans internet : +```bash +# Sur la machine labo (une fois) +git config receive.denyCurrentBranch updateInstead + +# Sur le portable — ajouter le labo comme remote +git remote add labo ssh://user@/chemin/PlanarianScanner + +# Workflow répétable +git pull origin video-plate-calibration # portable ← GitHub +git push labo video-plate-calibration # labo ← portable +``` + +--- + ## Licence GPL-3.0 diff --git a/README.md b/README.md index b3d6334..ff6b6d0 100644 --- a/README.md +++ b/README.md @@ -52,7 +52,14 @@ d'analyse distantes. - Pilotage du bras CNC en GRBL — déplacement automatique puits par puits - Calibration des multi-puits avec synchro base de données -- Acquisition image haute définition via ArduCam (OpenCV + Picamera2) +- Trois modes de capture : + - **ArduCam** (Picamera2) — caméra haute définition montée sur le bras + - **Webcam** — via OpenCV (développement / test) + - **Vidéo plaque** (`VideoPlateCapture`) — crop dynamique dans une vidéo plaque entière rejouée en boucle ; adapté aux scans sans caméra embarquée +- Calibration assistée : + - Détection automatique du centre du puit (Hough + CLAHE, plage rayon adaptable selon le mode) + - Overlay Canny vert pour visualiser les bords en conditions d'éclairage difficile + - Contrôles temps réel : Debug, Overlay annotations, Contours, Recadrage - Stockage des frames en base time série ReductStore - Sessions de scan paramétrables (grille complète ou sélection de puits) - Export asynchrone (Celery) : @@ -364,14 +371,22 @@ PlanarianScanner/ --- -## Procédure de calibration en 4 étapes -1. Activer "Debug détection" → voir le cercle et les zones sur le stream +## Procédure de calibration -2. Activer recadrage pour isoler le tube +### Mode caméra (ArduCam / Webcam) +1. **Debug** → active la détection HoughCircles en continu (cercle + zones affiché) +2. **Overlay** → affiche/masque les annotations sans couper la détection +3. **Recadrer** → isole le puit et navigue vers la position Base +4. **Calibrage auto** → centrage automatique puit par puit avec sauvegarde -Calibration auto +### Mode vidéo plaque +1. Créer un enregistrement `VideoPlate` dans l'admin (upload vidéo, `px_per_mm`, `x_origin_mm`, `y_origin_mm`) +2. **Contours** → overlay Canny vert pour repérer les bords des puits selon l'éclairage +3. **Debug** → détection Hough adaptée (plage rayon élargie pour puit plein cadre) +4. **Recadrer** → active le crop + déplace vers la Base +5. Naviguer puit par puit, sauvegarder les positions -![Aperçu de la vidéo](assets/calibration-auto.png) Calibration auto +![Aperçu calibration auto](assets/calibration-auto.png) [🎬 Vidéo Calibration auto](https://youtu.be/6RueJ3onUoY) diff --git a/README_EN.md b/README_EN.md index 60dd504..d3fa0ab 100644 --- a/README_EN.md +++ b/README_EN.md @@ -50,7 +50,14 @@ high-performance storage of captures, and export to remote analysis machines. - CNC arm control through GRBL — automatic well-by-well movement - Multi-well calibration with database synchronization -- High-definition image acquisition via ArduCam (OpenCV + Picamera2) +- Three capture modes: + - **ArduCam** (Picamera2) — high-definition camera mounted on the arm + - **Webcam** — via OpenCV (development / testing) + - **Plate video** (`VideoPlateCapture`) — dynamic crop from a full-plate video replayed in loop; suitable for scans without an embedded camera +- Assisted calibration: + - Automatic well-center detection (Hough + CLAHE, adjustable radius range per mode) + - Green Canny overlay to visualize well borders under difficult lighting + - Real-time controls: Debug, Annotation Overlay, Edge Enhance, Crop - Frame storage in ReductStore time-series database - Configurable scan sessions (full grid or selected wells) - Asynchronous export (Celery): @@ -343,9 +350,24 @@ PlanarianScanner/ │ └── webfonts └── templates └── admin -4-Step Calibration Procedure -Enable "Detection Debug" → display the circle and zones on the stream -Enable cropping to isolate the tube +## Calibration Procedure + +### Camera mode (ArduCam / Webcam) +1. **Debug** → enables continuous HoughCircles detection (circle + zones displayed) +2. **Overlay** → shows/hides annotations without stopping detection +3. **Crop** → isolates the well and navigates to the Base position +4. **Auto calibration** → automatic well-by-well centering with position save + +### Plate video mode +1. Create a `VideoPlate` record in admin (upload video, set `px_per_mm`, `x_origin_mm`, `y_origin_mm`) +2. **Edge Enhance** → green Canny overlay to locate well borders under variable lighting +3. **Debug** → Hough detection with wider radius range (well fills the crop) +4. **Crop** → activates circular crop + moves to Base position +5. Navigate well by well and save positions + +![Auto calibration preview](assets/calibration-auto.png) + +[🎬 Auto Calibration Video](https://youtu.be/6RueJ3onUoY) ## Status diff --git a/test_tube_scanner/scanner/process.py b/test_tube_scanner/scanner/process.py index d4ba764..dae560f 100644 --- a/test_tube_scanner/scanner/process.py +++ b/test_tube_scanner/scanner/process.py @@ -413,7 +413,10 @@ class ScannerProcess(Task): self.cam._active_median = False self.cam.set_edge_enhance(False) if self.conf.capture_type == 'video': + self.cam._active_crop = False + + self.cam.set_circular_crop(None) ctx = dict(state="crop", value=self.cam._active_crop) else: