Deep-learning particle segmentation and quantitative morphology analysis
Turn microscopy images into reviewable particle outlines, dimensional measurements and tables: annotate → convert → train → predict → calibrate → measure.
This beginner guide uses Windows and copyable PowerShell commands. You do not need to learn programming first. Bring your own images: research images and manual annotations are not distributed.
- Capabilities and benefits
- Preparation and project download
- Open a terminal and install
- First run with the supplied particle model
- Edit settings safely
- Prepare your training data
- Labelme annotation and optional model downloads
- Convert, train and evaluate
- Prediction and preannotation
- Dimensional calibration
- Find and interpret outputs
- Working with limited hardware
- Troubleshooting
- Subsequent use, tests, backups and licensing
The workflow segments individual particles in microscopy images and measures their two-dimensional size and shape. The standard training workflow uses one class, named particle.
| Feature | Practical benefit |
|---|---|
| Lightweight YOLO11n-seg | A nano-scale architecture for exploring training and inference with limited computing resources |
| Transfer learning | Start from pretrained weights rather than learning everything from scratch; use representative samples and careful labels to make better use of a limited annotation budget |
| CPU support | Annotation, inference, measurement and small training checks can run without an NVIDIA GPU |
| Adjustable resource demand | Input size, training batch size, loader workers and image caching can be configured |
| Connected workflow | One command entry point and a shared configuration file connect annotation through measurement |
| Reviewable measurements | Overlays, individual-particle records and exclusion reasons support quality checks |
| Reusable outputs | CSV, Excel and charts can be analyzed further in Excel, Origin or Python |
The aim is practical particle analysis under limited hardware and annotation resources. Actual accuracy depends on image quality, target scale, representative data and annotation consistency. A small model does not guarantee fast training on every computer or the same accuracy on every material.
Windows CPU checks have covered one training epoch, inference, measurement and Labelme window startup. See the validation record. The full research dataset is not shipped, so this release does not promise a fixed mAP score or reproduce a publication benchmark.
- A Windows computer with 64-bit Python 3.13. The tested interpreter is Python 3.13.5.
- Internet during dependency installation and when downloading optional annotation models.
- Images you own or have permission to use. Start with 2–5 clear PNG or JPG images.
- Several GB of free space for dependencies and experiment outputs. The installed environment is much larger than the repository.
- No separate PyCharm, VS Code, Anaconda or Labelme installation is required.
CPU is the default; CUDA setup is optional. Linux/macOS have not been tested, and the Windows commands below cannot be copied unchanged to those systems.
On the GitHub repository page, choose Code → Download ZIP, then extract the archive completely. Git users may clone the repository instead. Do not run the project from inside the ZIP viewer.
A short, simple English directory name reduces typing mistakes. The extracted directory may be named particle-morphometry-main; that is fine. Open the folder that directly contains run.py, setup.ps1, README.md and configs. This is the project root. If you see only another folder, open that inner folder first.
particle-morphometry/
├── run.py Common command entry point
├── setup.ps1 Windows installation script
├── requirements.txt Python dependencies
├── configs/
│ ├── workflow.json Workflow parameters
│ └── labelme.yaml Annotation defaults
├── data/
│ ├── annotations/
│ │ ├── train/ Training images and matching JSON
│ │ ├── val/ Validation images and matching JSON
│ │ └── test/ Held-out images and matching JSON
│ ├── images/ New images to predict
│ └── datasets/ Generated YOLO datasets
├── weights/ Included YOLO checkpoints and checksums
├── pipeline/ Processing code; normally leave unchanged
├── vendor/ Included software source and wheels
├── outputs/ Training, prediction and measurement results
├── tests/ Functional test scripts
└── docs/VALIDATION.md Tested scope and limitations
Ignore .gitkeep files: they preserve empty folders. Installation creates .venv; runtime settings go under .runtime. Do not copy another computer's .venv.
If needed, get the Python 3.13 Windows 64-bit installer from the official Python website. Enable the Python Launcher during installation; enable “Add python.exe to PATH” if offered. Close old terminals after installing.
- Open the project root in File Explorer.
- Click the address bar at the top of that window.
- Type
powershelland press Enter. - In the new terminal, run:
dir run.py
py -3.13 --versionThe first command must list run.py; the second should print Python 3.13.x. If the file is missing, reopen PowerShell from the correct folder. If the launcher cannot find Python, also try python --version. The setup script detects Python 3.13 through either command. If neither works, finish installation and reopen PowerShell.
All commands below belong in PowerShell, not the Python >>> prompt. Double-clicking run.py does not open a workflow menu.
Copy this whole line into PowerShell and press Enter:
powershell -ExecutionPolicy Bypass -File .\setup.ps1The script creates .venv, installs CPU PyTorch and the other dependencies, and checks the installation. The execution-policy argument applies to that PowerShell process, not a permanent computer-wide setting.
The first installation downloads large dependencies. Wait until the command finishes and the input prompt returns. Do not paste training commands into an installation that is still running. Success includes:
Imports and bundled weight checksums OK
CUDA: False is expected with the default CPU installation. If installation fails, inspect the final error, check connectivity and retry; do not proceed to training yet.
Skip this if the script succeeded. Otherwise run each line separately, waiting for success before proceeding:
py -3.13 -m venv .venv
.\.venv\Scripts\python -m pip install torch==2.9.1 torchvision==0.24.1 --index-url https://download.pytorch.org/whl/cpu
.\.venv\Scripts\python -m pip install -r requirements.txt -c constraints-tested.txt
.\.venv\Scripts\python run.py doctorAlways use .\.venv\Scripts\python for this project. This selects the correct dependencies without requiring an environment activation command.
This route requires no annotation or training. The supplied checkpoint is specialized for ceramic proppant particles; it may not suit another material, background or magnification. Use Sections 6–9 to train your own model when necessary.
Copy 2–5 images directly into data/images, for example:
data/images/sample_001.png
data/images/sample_002.png
Use English letters, numbers and underscores in names. Avoid duplicate stems: do not use both sample_001.jpg and sample_001.png. Keep backups of originals. For your first run, avoid nested image folders.
.\.venv\Scripts\python run.py predict --model weights/particle_best.ptRead the output directory printed at completion. Under that run in outputs/predictions, open annotated and examine the overlays. Look for missed particles, merged neighbors and poor boundaries before trusting measurements.
No outlines may indicate a domain mismatch or an overly strict threshold rather than a software failure. The default prediction confidence is 0.9. For an initial visual review, follow Section 5 to try predict.CONFIDENCE_THRESHOLD = 0.25 if nothing is detected; inspect added false positives and select final settings on validation data. Input image size also affects target scale. See Section 13.
.\.venv\Scripts\python run.py measureOpen particle_measurements.xlsx in the new run directory under outputs/measurements. Pixel measurements are available by default; millimetre columns remain blank until calibration is supplied. See Section 10 for physical dimensions.
You have now completed an image-to-table workflow. Review the output before using it as research data.
Most changes belong in configs/workflow.json, not the Python source. Open it with:
notepad .\configs\workflow.jsonSettings are grouped under convert, train, predict, measure and preannotate. A key belongs to its group: changing train.IMGSZ does not change predict.IMGSZ.
- Back up the configuration first. Find the existing field and change only its value.
- Strings use straight double quotes, such as
"cpu"; numbers such as512are unquoted. - Use lowercase
true,falseandnull. JSON does not allow comments or trailing commas. - Prefer paths relative to the project root and use
/, for example"data/images". - Save before launching a command. Editing the file does not change a task already running.
- Tables below describe individual fields; do not replace the entire configuration with a few listed fields.
| Field | Default | Meaning |
|---|---|---|
train.TRAINING_MODE |
"smoke" |
Workflow check; use "formal" for research training |
train.SMOKE_EPOCHS |
5 |
Smoke-run epochs |
train.FORMAL_EPOCHS |
200 |
Planned maximum formal epochs; not an accuracy guarantee |
train.IMGSZ |
512 |
Input size; must be a multiple of 32 |
train.BATCH_SIZE |
2 |
Images per training batch; smaller values reduce memory demand |
train.DEVICE |
"cpu" |
CPU; 0 selects an available CUDA GPU |
train.WORKERS |
0 |
Loader processes; keep 0 initially on Windows |
train.CACHE_IMAGES |
false |
Avoid caching the training images in RAM |
predict.CONFIDENCE_THRESHOLD |
0.9 |
Lowering it may increase both detections and false positives |
predict.IMGSZ |
512 |
Inference input size, configured separately |
measure.CALIBRATION_MODE |
"none" |
Pixel-only measurement until calibrated |
Check JSON syntax after editing:
.\.venv\Scripts\python -m json.tool configs/workflow.json > $nullNo error means valid JSON syntax, not necessarily valid parameter values. Each workflow stage also validates settings.
| Folder | Purpose |
|---|---|
data/annotations/train |
Images used to learn model parameters |
data/annotations/val |
Images used to compare models and tune settings |
data/annotations/test |
Held-out images for final evaluation, not tuning |
The current conversion/training workflow requires data in all three splits. Roughly 70%/15%/15% is an illustrative starting allocation, not a rule. More importantly, group related images by specimen or acquisition batch. Keep duplicate images, highly similar adjacent views and crops of one source image in the same split. Split before tiling to prevent leakage.
Select representative particle sizes, shapes, densities, illumination and backgrounds, including difficult real cases. With limited labeling time, diverse representative examples are more useful than repeatedly labeling near-duplicates.
After annotation, each image must have a matching JSON:
data/annotations/
├── train/
│ ├── train_001.png
│ └── train_001.json
├── val/
│ ├── val_001.png
│ └── val_001.json
└── test/
├── test_001.png
└── test_001.json
This illustrates file pairing, not an adequate research dataset size. A tiny dataset can check execution but cannot establish model quality.
.\.venv\Scripts\python run.py annotate --images data/annotations/trainThis opens the project's installed Labelme. Select an image from the image list. If the window is empty, check that images exist in the directory. Close the Labelme window before entering the next command in the same terminal.
- Select Polygon drawing mode, not Rectangle.
- Click successive points along one particle boundary.
- Press Enter or double-click to finish the polygon.
- Enter the exact lowercase label
particle. Do not mix it withParticleorP. - Draw a separate polygon for each particle and complete the image consistently.
- Use Edit Shapes to correct outlines, then press Ctrl+S.
- Confirm a matching file appeared beside the image, such as
train_001.jsonbesidetrain_001.png.
Do not merge independent particles into one polygon or label only a few obvious objects while leaving other visible targets unannotated. Define touching particles consistently.
The project disables embedded image data in JSON. Keep each image and JSON together; do not enable “Save With Image Data.” Choose filenames before labeling; later renaming also requires correcting the JSON imagePath.
Users must download auxiliary annotation models themselves. No Labelme AI weights are included. Manual polygon annotation needs no auxiliary model.
- Open an image in Labelme and choose EfficientSam (speed) or EfficientSam (accuracy) for AI-assisted annotation. Start with the speed option on limited hardware and inspect its output.
- On first use, accept Labelme's download prompt and wait for the selected model to finish downloading.
- Internet access to the hosting service is necessary. If it fails, check connectivity and retry or continue with manual polygons.
- Follow the AI tool's interface for foreground/background prompts, inspect and correct the resulting outline, and save it as a
particlepolygon.
Labelme/OSAM caches downloaded files under the current user's ~/.cache/osam/models/blobs; ~ means the user home directory. They are outside the repository. A cached model can be reused on that computer; another computer must download its own copy. See the upstream EfficientSAM ONNX release. Beginners should use the in-app prompt rather than manually rename cache files.
Close the current window, then run these commands one at a time, finishing and closing the first window before the second:
.\.venv\Scripts\python run.py annotate --images data/annotations/val
.\.venv\Scripts\python run.py annotate --images data/annotations/testReview all splits manually. Unchecked model predictions must not become evaluation ground truth.
.\.venv\Scripts\python run.py convertThis reads the image/JSON pairs, writes split YOLO data and dataset.yaml beneath data/datasets, and records the latest dataset location. Originals are retained.
Check the reported image/instance counts and the generated qa overlays. After changing or adding labels, run conversion again; training does not automatically reconvert JSON.
The default convert.CONVERSION_MODE is "full". Advanced users can select "tile" with TILE_SIZE and TILE_OVERLAP. Start with full images. Prediction currently does not automatically tile and stitch large images; do not assume tiled training and full-image prediction have identical target scales.
.\.venv\Scripts\python run.py trainBy default this starts from the official YOLO11n-seg pretrained checkpoint and trains for five CPU epochs. Progress output is normal. Successful completion checks the workflow; five epochs do not establish research accuracy.
In the printed run directory under outputs/training, look for:
weights/best.pt: the checkpoint selected by validation performance.weights/last.pt: the final epoch checkpoint.results.csvandresults.png: epoch metrics and curves.
The latest best-model path is recorded automatically. New runs receive new output directories; still back up important runs and configurations.
Change train.TRAINING_MODE to "formal", configure FORMAL_EPOCHS, IMGSZ, BATCH_SIZE and DEVICE, save, then run the same training command. The default maximum is 200 epochs; early stopping may finish sooner. More epochs cannot repair inconsistent labels or unsuitable data.
Choose settings using validation performance and visual review. Ctrl+C interrupts a task, but the current epoch may not yet be saved. There is no dedicated resume command in this CLI; rerunning the default training command starts a new run.
train.EVALUATE_TEST_AFTER_TRAINING defaults to false. Once the experiment is fixed, set it to true for the final training/evaluation run. The program evaluates its resulting best.pt on the test split after training. This switch does not retroactively evaluate old runs; do not repeatedly tune against test performance.
Mask mAP50 measures instance segmentation average precision at IoU 0.5. It is not pixel accuracy or dimensional measurement accuracy. Physical measurements need independent calibration and review.
Copy new images into data/images, then run:
.\.venv\Scripts\python run.py predict
.\.venv\Scripts\python run.py measureThe first uses the latest completed training checkpoint; the second uses the latest successful prediction output. Confirm that these correspond to your intended experiment.
To select an older checkpoint, locate its best.pt and put that path after --model. Dragging a file into PowerShell can help obtain its path; quote paths containing spaces. The default does not automatically choose the best model across all historical experiments.
To measure an older prediction, set measure.MEASUREMENT_INPUT_DIR to its directory, which must contain instances.csv and instance_maps. Restore the empty string "" to follow the latest output again.
YOLO preannotation is separate from Labelme's EfficientSAM assistance. With the latest trained model:
.\.venv\Scripts\python run.py preannotateOr with the supplied particle checkpoint:
.\.venv\Scripts\python run.py preannotate --model weights/particle_best.ptBy default only the training split is processed. Existing JSON is preserved; new JSON is saved beside the corresponding image. Reports go under outputs/preannotations. Review and correct every result in Labelme, then reconvert before retraining. This can reduce repetitive work when expanding a dataset.
Leave measure.CALIBRATION_MODE as "none". Physical-unit columns remain blank. Pixel counts are not micrometres.
Example: in the actual image resolution being analyzed, a 100 μm reference spans 200 pixels. The scale is 100 / 200 = 0.5 μm per pixel.
Change these existing fields in the measure group:
| Field | Example value |
|---|---|
CALIBRATION_MODE |
"pixel_size" |
PIXEL_SIZE_UM |
0.5 |
These numbers are examples, not defaults to copy blindly. Save and rerun the full run.py measure command; retraining or repeating prediction is unnecessary when only calibration changes.
Alternatively, for a 100 μm reference (= 0.1 mm) spanning 200 pixels:
| Field | Example value |
|---|---|
CALIBRATION_MODE |
"reference_length" |
REFERENCE_LENGTH_PX |
200 |
REFERENCE_LENGTH_MM |
0.1 |
The program does not read scale-bar text automatically. Supply the measured values. The "field_width" mode instead uses FIELD_WIDTH_MM, which must be the true width of the full image in millimetres.
Create data/calibration.csv, for example:
image_name,pixel_size_um
sample_001.png,0.5
sample_002.png,0.8Set measure.PER_IMAGE_CALIBRATION_CSV to "data/calibration.csv" and leave the global mode as "none". Include every image in the run, with exact filenames and extensions and your actual scales. Clear the CSV setting to "" when returning to a single global scale.
Recheck calibration after resizing, cropping or changing magnification. Compare a sample of measurements against known dimensions or manual measurements.
Use the exact directory printed by the command, especially when multiple runs exist.
| Output | Purpose |
|---|---|
outputs/predictions/<run>/annotated |
Segmentation overlays for visual review |
instance_maps |
16-bit instance IDs used for measurement; may look dark in an image viewer; never convert to JPEG |
instances.csv |
Predicted particle IDs, confidence and position metadata |
outputs/measurements/<run>/particle_measurements.xlsx |
Combined Excel workbook |
particles_all.csv |
All particles and exclusion reasons |
particles_included.csv |
Particles accepted for statistics |
image_summary.csv, overall_summary.csv |
Per-image and overall summaries |
size_distribution.csv |
Size-distribution table |
qa_overlays, charts, histogram_csv |
Review images, charts and histogram data |
Wait for completion before opening Excel; close result files before writing to them again. Border particles are excluded by default and area/connectivity checks also apply, so predicted and statistically included counts can differ. Inspect exclusion_reasons rather than removing filters simply to increase counts.
Equivalent circular diameter is sqrt(4*A/pi). Feret diameters describe caliper dimensions. Circularity is 4*pi*contour_area/perimeter**2 and is sensitive to boundary quality and pixelization. Ellipse axes, axis ratios and solidity provide additional shape descriptors.
These are 2D projected descriptors, not direct 3D sphericity or particle volume. Size distributions are count-based, not sieve mass distributions. Report calibration, selection rules, segmentation error and statistical definitions with research results.
Start small, inspect outlines, then scale up. High-end GPUs are not a prerequisite for initial use, but dense particles, large images and larger datasets increase resource requirements.
| Situation | Starting adjustment | Tradeoff |
|---|---|---|
| No NVIDIA GPU | Keep CPU; try a few images and smoke training first | Formal CPU training may be much slower |
| Limited RAM/VRAM | Reduce training batch 2 to 1; keep workers 0 and image caching false | May reduce speed; monitor actual memory use |
| Large input size | Try 320 instead of 512, keeping multiples of 32 | Small-particle quality may worsen; compare on validation data |
| Limited labeling time | Select representative images and carefully review assisted labels | Assistance does not replace label quality |
| Very dense particles | Check resolution and MAX_DETECTIONS |
Too low a cap truncates results; larger caps require more resources |
These are starting points, not measured minimum hardware requirements. No universal memory minimum or per-image runtime has been established.
For optional NVIDIA acceleration, --device 0 alone cannot turn the CPU PyTorch package into a CUDA build. Follow the official PyTorch version instructions for torch 2.9.1 / torchvision 0.24.1, choose a driver-compatible CUDA build, and install it into this project's .venv. Verify:
.\.venv\Scripts\python -c "import torch; print(torch.cuda.is_available())"Only after this prints True, try:
.\.venv\Scripts\python run.py train --device 0
.\.venv\Scripts\python run.py predict --device 0Each override applies only to its command, not permanently to the configuration. CUDA has not been validated in this release. Training can also run on a stronger computer, with best.pt transferred back for inference.
| Symptom | First checks |
|---|---|
py or Python 3.13 missing |
Install 64-bit Python 3.13 and its launcher; reopen PowerShell |
run.py or setup.ps1 missing |
Reopen the terminal from the actual project root |
.venv\Scripts\python missing |
Complete installation; do not create an empty .venv manually |
ModuleNotFoundError |
Use the full .venv Python command and reinstall requirements |
| pip timeout/SSL error | Check network access and system time, then retry; do not disable certificate checks |
| Annotation model download fails | Optional models are not bundled; retry when the host is reachable or annotate manually |
| Invalid JSON | Check quotes, commas and lowercase true/false/null; run the syntax check in Section 5 |
| Missing labels during conversion | All three splits need paired image/JSON files, polygon shapes and the exact particle label |
| No latest model | Train first or explicitly use weights/particle_best.pt as in Section 4 |
| No detected particles | Check domain suitability; try confidence 0.5 or 0.25 on validation examples and inspect false positives, not just counts |
| Merged particles or bad boundaries | Improve labels and difficult samples; compare input sizes; confidence alone may not fix boundaries |
| Out of memory | Reduce batch/input size, close heavy applications, or try a small CPU run |
| Blank millimetre columns | Supply your own calibration as in Section 10 |
| Measurement cannot find results | Complete prediction first or point to a valid earlier prediction directory |
| Instance-map/CSV mismatch | Do not edit IDs or convert maps to JPEG; regenerate predictions |
| Output cannot be written | Close Excel, check directory permissions and prefer local storage |
| CUDA is False | Expected in CPU setup; GPU requires compatible drivers and a CUDA PyTorch build |
When asking for help, preserve the command, final full error, Python version and configuration. Remove private paths and research data before posting publicly.
You do not reinstall on every use. Open PowerShell in the project root and run the needed command. To see available commands or verify the environment:
.\.venv\Scripts\python run.py --help
.\.venv\Scripts\python run.py doctorDoctor checks dependencies and included YOLO weights. It does not download optional Labelme AI models.
.\.venv\Scripts\python tests/smoke_test.pyThis generates synthetic data under outputs and executes one CPU training epoch, prediction, measurement and preannotation. It needs no research images and does not download auxiliary annotation models. Success demonstrates functionality, not accuracy on real materials. A separate offscreen window-startup check is available:
.\.venv\Scripts\python tests/gui_smoke_test.pyBack up original images, JSON, important configurations, selected checkpoints and results separately. .gitignore excludes research data, environments and outputs: pushing the repository does not back up your experiments.
Moving the project can invalidate absolute paths in generated dataset YAML, latest-output pointers or virtual-environment launchers. Choose a location before installing. On another computer, reinstall dependencies, restore data and reconvert it; update model/input settings as needed.
Labelme and OSAM software wheels are included; their auxiliary models are user downloads. YOLO checkpoints remain included for initialization and particle prediction. Project source code, runtime messages, chart labels and workbook descriptions are English. A separate Chinese README is provided. Labelme may display its own interface in the system language.
See LICENSE, third-party notices and licenses/. Preserve the relevant notices when redistributing. constraints-tested.txt records tested Windows dependencies; it is not a cross-platform guarantee.
Reviewed background-only images may use a Labelme JSON with "shapes": []; a missing JSON is not treated as a background label. Conversion stops if images lack annotations. Full-image conversion preserves valid small polygons; the minimum clipped-area filter is applied only in tile mode. Image stems must be unique across extensions and folders to prevent output collisions. Prediction accepts single-class trained particle checkpoints; the included COCO initialization checkpoint is for training, not direct particle measurement.
The Windows setup and manual installation use constraints-tested.txt for tested dependency versions. Run additional release regressions with .\.venv\Scripts\python tests/test_release_regressions.py. See release review.
The setup script also detects python on PATH. If both automatic options fail but Python 3.13 x64 is installed, use this explicit form (replace the example path with your actual interpreter path):
powershell -ExecutionPolicy Bypass -File .\setup.ps1 -PythonExecutable "C:/Tools/Python313/python.exe"For manual environment creation, python -m venv .venv can replace py -3.13 -m venv .venv only after python --version confirms Python 3.13. The example path is illustrative, not a required installation directory.
Fresh-installation evidence and exact limitations are documented in USER_ACCEPTANCE.md.