LLE Vial Analysis is a hardware-integrated computer-vision application I originally built in 2019 to automate liquid-liquid extraction (LLE) vial inspection in a laboratory workflow.
The system captures vial images from a camera mounted above a 48-well plate, runs a custom-trained object-detection model, and turns the detections into measurements and decisions. It identifies liquid layers and meniscus shapes, estimates layer volumes, flags rag layers and unsuitable samples, annotates the source images, writes an Excel report, stores results in SQLite, and can notify scientists by email.
The camera and lighting assembly was designed as a 3D-printed attachment for the well-plate area of a Sirius automation platform.
This repository is a portfolio archive of a system designed for a specific camera, lighting setup, plate geometry, and laboratory environment. The web interface can be run locally, but a complete analysis run requires compatible hardware and the trained model file. It is not presented as a general-purpose or production-ready laboratory product.
The trained weights and source video are intentionally excluded from Git because they are large binary artifacts. Place the model at weights/epoch_149.pt, or change WEIGHTS_PATH in .env.
- The Flask and Socket.IO interface collects the experiment identifier and vial count.
- OpenCV watches the camera feed and captures each vial when the image stabilizes.
- The custom PyTorch detector locates vial features, layers, menisci, residue, and rag layers.
- Post-processing converts pixel locations into volume estimates and sample classifications.
- The app creates annotated images, an Excel workbook, SQLite records, and optional email attachments.
The models/ and utils/ directories contain the YOLOR/YOLO-family inference foundation used by the custom detection pipeline. Project-specific capture, measurement, reporting, and application code lives in app.py, detect.py, and core/.
Python 3.12 is the currently verified interpreter. Run commands from the repository root because the original application uses relative paths.
python3.12 -m venv .venv
source .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -r requirements.txt
cp .env.example .envThe dependency file records the known-working package versions. For an NVIDIA installation, install the matching PyTorch and torchvision build for your CUDA version using the official PyTorch instructions before installing the remaining requirements. The recovered local environment uses PyTorch 2.5.1 and torchvision 0.20.1 with CUDA 12.1.
Generate a local Flask secret before starting the app:
python -c "import secrets; print(secrets.token_hex(32))"Paste that value into SECRET_KEY in .env. Review the camera, email, output-path, processing-device, and weight-path settings there as well.
Create the local database once:
python -m core.create_databasepython app.pyOpen http://127.0.0.1:5254. Submitting an analysis starts camera capture, so use the interface with the expected hardware attached.
Place input images in excel/full_images/, configure WEIGHTS_PATH, and run:
python detect.pyThe script's default experiment metadata is demonstration data; normal operation calls it from the capture workflow with values supplied through the interface.
The portable application and core behavior can be checked without camera hardware:
python -m unittest discover -vapp.py— Flask/Socket.IO interface and process coordinationcore/— capture workflow, measurement calculations, reports, email, and SQLite accessdetect.py— object-detection inference and result orchestrationmodels/,utils/— YOLO-family model and inference utilitiesmatch/— calibrated vial-reference images used by the capture triggertemplates/,static/— browser interface and portfolio screenshotsexcel/2ml_LLE_templateImages.xlsx— report templateutilities/— standalone camera experiments retained for referencetests/— route, validation, image-processing, reference-image, and database regression tests
Licensed under the GNU General Public License v3.0; see LICENSE.md. The detector implementation includes code derived from the GPL-licensed YOLOR/YOLO ecosystem, with upstream references retained in the source. Vendored browser libraries and their licenses are listed in THIRD_PARTY_NOTICES.md.
Created by Jeremy Demers in 2019.

