readme
This commit is contained in:
+362
@@ -0,0 +1,362 @@
|
||||
#  PlanarianScanner
|
||||
|
||||
> Automated imaging system for behavioral tracking of planarians
|
||||
|
||||
> (C) dd@linuxtarn.org for the Biology Laboratory, Champollion University, Albi
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
**PlanarianScanner** is a web application developed for monitoring the activity
|
||||
and movements of **planarians** (*Platyhelminthes*) in laboratory research.
|
||||
|
||||
The system controls a motorized multi-well scanner composed of a CNC arm (GRBL)
|
||||
and a high-definition ArduCam camera mounted on a Raspberry Pi 4. It enables
|
||||
automated image acquisition on a **6×4 wells × 4 plates** grid,
|
||||
high-performance storage of captures, and export to remote analysis machines.
|
||||
|
||||
---
|
||||
|
||||
## Hardware
|
||||
|
||||
| Component | Details |
|
||||
|---|---|
|
||||
| Board | Raspberry Pi 4 |
|
||||
| Camera | High-definition ArduCam |
|
||||
| Motion system | CNC arm (L2544) controlled by GRBL |
|
||||
| Well grid | 6×4 × 4 multi-well plates |
|
||||
| Network | Local LAN — Samba/rsync export |
|
||||
|
||||
---
|
||||
|
||||
## Technical Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|---|---|
|
||||
| Backend | Django + Django Channels |
|
||||
| Real-time | Redis (broker + channel layer) |
|
||||
| Acquisition | OpenCV + Picamera2 |
|
||||
| Storage | ReductStore (high-performance time series) |
|
||||
| Asynchronous tasks | Celery + django-celery-beat |
|
||||
| Export | Samba (CIFS), rsync/SSH |
|
||||
| Platform | Raspberry Pi 4 — Debian Linux |
|
||||
|
||||
---
|
||||
|
||||
## Features
|
||||
|
||||
### Application 1: Test Tube Scanner
|
||||
|
||||
- CNC arm control through GRBL — automatic well-by-well movement
|
||||
- Multi-well calibration with database synchronization
|
||||
- High-definition image acquisition via ArduCam (OpenCV + Picamera2)
|
||||
- Frame storage in ReductStore time-series database
|
||||
- Configurable scan sessions (full grid or selected wells)
|
||||
- Asynchronous export (Celery):
|
||||
- ZIP archive of JPEG images per session
|
||||
- MP4 video generated from captured frames
|
||||
- Automatic transfer of exports to remote machines (Linux / Windows)
|
||||
- Nightly export scheduling via django-celery-beat
|
||||
- Real-time web interface (Django Channels / WebSocket)
|
||||
- Django administration interface (sqlite3 or mariadb or postgresql)
|
||||
- Long-task progress tracking through polling
|
||||
|
||||
### Application 2: Planarian Detection and Multi-Individual Tracking in a Tube
|
||||
|
||||
[🎬 Planarian Simulation Video](https://youtu.be/pkzClmBp_KM)
|
||||
|
||||
- Supports multiple planarians with configurable parameters via Django or CSV.
|
||||
|
||||
- Strategy:
|
||||
|
||||
- MOG2 background subtraction (lightweight on Raspberry Pi 4)
|
||||
- Detection of all valid contours (surface >= min_area_px)
|
||||
- Frame-to-frame association using minimum Euclidean distance
|
||||
via the Hungarian algorithm (scipy.optimize.linear_sum_assignment)
|
||||
- Independent inter-frame state per individual (PlanarianState)
|
||||
- Returns a list of results, one for each tracked individual
|
||||
|
||||
- Per-planarian CSV export compatible with EthoVision XT.
|
||||
- Metrics per frame:
|
||||
|
||||
- Mobility : velocity, distance, moving, mobility_state
|
||||
- Thigmo : dist_to_wall_mm, near_wall
|
||||
- Photo : dist_to_light_mm, heading_to_light_deg, fleeing_light
|
||||
- Chemo : dist_to_food_mm, heading_to_food_deg, approaching_food, in_food_zone
|
||||
- Social : nearest_neighbour_mm, in_avoid_zone, in_aggreg_zone, chem_repulsion_level
|
||||
|
||||
- Summary metrics:
|
||||
|
||||
- Mobility : movedCenter_pointTotal_mm, velocity_mean_mm_s, state durations
|
||||
- Thigmo : thigmotaxis_pct_time_near_wall
|
||||
- Photo : photo_pct_time_fleeing, photo_mean_dist_mm, photo_latency_s
|
||||
- Chemo : chemo_pct_time_approaching, chemo_pct_time_in_zone,
|
||||
chemo_latency_s, chemo_mean_dist_mm
|
||||
- Social : social_pct_time_avoiding, social_pct_time_aggregating,
|
||||
social_mean_nn_mm, social_contact_events
|
||||
|
||||
- Default EthoVision thresholds (configurable via Django or CSV)
|
||||
|
||||
- **Immobile** : movement < 0.2 mm/s
|
||||
- **Mobile** : 0.2 to 1.5 mm/s
|
||||
- **Highly mobile** : > 1.5 mm/s
|
||||
|
||||
| EthoVision | CSV frames | CSV summary |
|
||||
|---|---|---|
|
||||
| movedCenter-pointTotalmm | total_distance_mm | movedCenter_pointTotal_mm |
|
||||
| VelocityCenter-pointMeanmm/s | velocity_mm_s | velocity_mean_mm_s |
|
||||
| MovementMoving | moving, duration_moving_s | movement_moving_duration_s |
|
||||
| MovementNot Moving | duration_stopped_s | movement_not_moving_duration_s |
|
||||
| ImmobileFrequency / Duration | mobility_state | mobility_immobile_frequency/duration_s |
|
||||
| MobileFrequency / Duration | mobility_state | mobility_mobile_frequency/duration_s |
|
||||
| Highly mobileFrequency / Duration | mobility_state | mobility_highly_mobile_frequency/duration_s |
|
||||
|
||||
- Behaviors
|
||||
|
||||
- **Thigmotaxis** : wall attraction (--thigmotaxis)
|
||||
- **Phototaxis** : fleeing from light (--photo-mode, --photo-strength)
|
||||
- **Chemotaxis** : attraction toward a food source (--chemo-strength)
|
||||
- **Inter-individuals** : contact avoidance, aggregation, chemical repulsion
|
||||
|
||||
### Application 4: Planarian Simulation
|
||||
|
||||
- planarian_sim.py
|
||||
|
||||
Circular space of 16 mm diameter, 500x500 px
|
||||
Supports multiple planarians with configurable parameters via CLI arguments.
|
||||
Per-planarian CSV export compatible with EthoVision XT.
|
||||
|
||||
Simulated behaviors:
|
||||
- Thigmotaxis : wall attraction (--thigmotaxis)
|
||||
- Phototaxis : fleeing from light (--photo-mode, --photo-strength)
|
||||
- Chemotaxis : attraction toward a food source (--chemo-strength)
|
||||
- Inter-individual : contact avoidance, aggregation, chemical repulsion
|
||||
|
||||
Usage:
|
||||
python3 planarian_sim.py [options]
|
||||
|
||||
Examples:
|
||||
python3 planarian_sim.py --count 5 --thigmotaxis 0.4
|
||||
python3 planarian_sim.py --count 5 --photo-mode fixed --photo-x 0.2 --photo-y 0.2 --photo-strength 0.6
|
||||
python3 planarian_sim.py --count 5 --chemo-x 0.7 --chemo-y 0.5 --chemo-strength 0.5
|
||||
python3 planarian_sim.py --count 5 --avoid-strength 0.6 --aggreg-strength 0.2
|
||||
|
||||
- make_videos.sh
|
||||
|
||||
- Configurable video generator
|
||||
|
||||
Usage:
|
||||
- ./make_video.sh (generates the default file)
|
||||
- ./make_video.sh all (generates 24 videos for 24 test tubes)
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```text
|
||||
Raspberry Pi 4
|
||||
├── Django (web interface + API)
|
||||
│ ├── Django Channels ←→ Redis (real-time WebSocket)
|
||||
│ └── Celery workers
|
||||
│ ├── scanning(session_id) — well traversal
|
||||
│ ├── export_images_zip() — JPEG ZIP generation
|
||||
│ ├── export_video_mp4() — MP4 generation (OpenCV)
|
||||
│ └── transfer → /mnt/exports — Samba share
|
||||
│
|
||||
├── ArduCam ← Picamera2 / OpenCV — HD capture
|
||||
├── CNC GRBL ← Serial — XY movement
|
||||
└── ReductStore — frame time-series storage
|
||||
|
||||
Installation
|
||||
|
||||
Full documentation coming soon.
|
||||
|
||||
Using piImager, install Raspberry Pi OS 64-bit Trixie on the Raspberry Pi 4.<br>
|
||||
Customize your Raspberry Pi with at least SSH enabled (SSH key or password).<br>
|
||||
Later, for convenience, you may install a VNC server.
|
||||
|
||||
ssh rpi4@ip.of.raspi
|
||||
|
||||
git clone https://github.com/your-repo/planarianscanner.git
|
||||
git@github.com:deunix-educ/PlanarianScanner.git
|
||||
|
||||
# modify environment variables if needed
|
||||
cp .env.example .env
|
||||
# Edit .env : SECRET_KEY, REDIS_URL, REDUCTSTORE_URL, ...
|
||||
|
||||
cd PlanarianScanner/etc
|
||||
chmod +x *.sh
|
||||
|
||||
# install system libraries
|
||||
./1-install-sys.sh
|
||||
|
||||
# compile reductstore (~15 min on Raspberry Pi 4)
|
||||
./2-cargo-reductstore-install.sh
|
||||
|
||||
# install samba client
|
||||
./3-install-samba-client.sh
|
||||
|
||||
# install mariadb
|
||||
./4-install_mariadb.sh
|
||||
|
||||
# install adminer
|
||||
./5-install_adminer.sh
|
||||
|
||||
# Configure Django applications
|
||||
./6-install_django_app.sh
|
||||
|
||||
# test
|
||||
sudo supervisorctl stop test_tube:*
|
||||
./manage.py runserver 0.0.0.0:8000
|
||||
|
||||
# local test
|
||||
# http://127.0.0.1:8000
|
||||
|
||||
# remote test
|
||||
# http://ip.of.raspi:8000
|
||||
|
||||
# end of test
|
||||
sudo supervisorctl restart test_tube:*
|
||||
|
||||
Starting services:
|
||||
|
||||
All services are accessible through supervisor
|
||||
http://root:toor@ip-of-raspi:9001
|
||||
or
|
||||
sudo supervisorctl start|stop|restart reductstore
|
||||
sudo supervisorctl start|stop|restart test_tube:*
|
||||
|
||||
Add scanner.local to the hosts file on web clients:
|
||||
if 10.8.0.100 is the Raspberry Pi 4 local IP address of the server
|
||||
|
||||
10.8.0.100 scanner.local
|
||||
|
||||
- linux : /etc/hosts
|
||||
- windows: C:\Windows\System32\drivers\etc\hosts
|
||||
- mac : /private/etc/hosts
|
||||
Repository Organization
|
||||
PlanarianScanner/
|
||||
├── assets
|
||||
│ ├── calibration-auto.png
|
||||
│ └── logo.png
|
||||
├── browser.py
|
||||
├── etc
|
||||
│ ├── 1-install-sys.sh
|
||||
│ ├── 2-cargo-reductstore-install.sh
|
||||
│ ├── 3-install-samba-client.sh
|
||||
│ ├── 4-install_mariadb.sh
|
||||
│ ├── 5-install_adminer.sh
|
||||
│ ├── 6-install_django_app.sh
|
||||
│ ├── db
|
||||
│ │ ├── configuration.json
|
||||
│ │ ├── multiwell.json
|
||||
│ │ └── well.json
|
||||
│ ├── install-linux-samba-server.sh
|
||||
│ ├── nginx_service.conf
|
||||
│ ├── reductstore_service.conf
|
||||
│ ├── requirements.txt
|
||||
│ ├── scanner_service.conf
|
||||
│ └── supervisor-inet_http.conf
|
||||
├── LICENSE
|
||||
├── README.md
|
||||
└── test_tube_scanner
|
||||
├── home
|
||||
│ ├── apps.py
|
||||
│ ├── asgi.py
|
||||
│ ├── celerymodule.py
|
||||
│ ├── context_processors.py
|
||||
│ ├── __init__.py
|
||||
│ ├── locale
|
||||
│ ├── management
|
||||
│ ├── middleware.py
|
||||
│ ├── __pycache__
|
||||
│ ├── settings.py
|
||||
│ ├── static
|
||||
│ ├── templates
|
||||
│ ├── templatetags
|
||||
│ ├── urls.py
|
||||
│ ├── views.py
|
||||
│ └── wsgi.py
|
||||
├── logs
|
||||
│ ├── celery.log
|
||||
│ └── test_tube.log
|
||||
├── manage.py
|
||||
├── media
|
||||
│ ├── images
|
||||
│ └── simulation
|
||||
├── modules
|
||||
│ ├── capture_interface.py
|
||||
│ ├── circular_crop.py
|
||||
│ ├── grbl.py
|
||||
│ ├── __init__.py
|
||||
│ ├── picamera2_capture_basic.py
|
||||
│ ├── picamera2_capture.py
|
||||
│ ├── planarian_metrics.py
|
||||
│ ├── planarian_tracker.py
|
||||
│ ├── __pycache__
|
||||
│ ├── reductstore.py
|
||||
│ ├── system_stats.py
|
||||
│ ├── tube_aligner.py
|
||||
│ ├── utils.py
|
||||
│ ├── videofile_capture.py
|
||||
│ └── webcam_capture.py
|
||||
├── planarian
|
||||
│ ├── admin.py
|
||||
│ ├── apps.py
|
||||
│ ├── forms.py
|
||||
│ ├── __init__.py
|
||||
│ ├── migrations
|
||||
│ ├── models.py
|
||||
│ ├── __pycache__
|
||||
│ ├── templates
|
||||
│ ├── tests.py
|
||||
│ ├── urls.py
|
||||
│ └── views.py
|
||||
├── run-workers.sh
|
||||
├── scanner
|
||||
│ ├── admin.py
|
||||
│ ├── apps.py
|
||||
│ ├── constants.py
|
||||
│ ├── consumers.py
|
||||
│ ├── export_tasks.py
|
||||
│ ├── __init__.py
|
||||
│ ├── migrations
|
||||
│ ├── models.py
|
||||
│ ├── multiwell.py
|
||||
│ ├── process.py
|
||||
│ ├── __pycache__
|
||||
│ ├── routing.py
|
||||
│ ├── static
|
||||
│ ├── tasks.py
|
||||
│ ├── templates
|
||||
│ ├── templatetags
|
||||
│ ├── tests.py
|
||||
│ ├── urls.py
|
||||
│ └── views.py
|
||||
├── staticfiles
|
||||
│ ├── admin
|
||||
│ ├── css
|
||||
│ ├── img
|
||||
│ ├── js
|
||||
│ ├── scanner
|
||||
│ └── webfonts
|
||||
└── templates
|
||||
└── admin
|
||||
4-Step Calibration Procedure
|
||||
Enable "Detection Debug" → display the circle and zones on the stream
|
||||
Enable cropping to isolate the tube
|
||||
|
||||
## Status
|
||||
|
||||

|
||||

|
||||

|
||||

|
||||

|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
GPL-3.0 — Open-source project, developed for sharing and scientific reproducibility.
|
||||
Reference in New Issue
Block a user