Microscopy Particle Size Analysis
Overview
Automated particle size analysis from microscopy images. The pipeline takes a high-resolution microscopy image (brightfield, darkfield, or DIC mode) and produces a complete granulometric report: binary mask, individual particle measurements, size distribution tables, cumulative curves (D10/D50/D90), and Rosin-Rammler fitting coefficients.
Three-stage pipeline:
- Image Preprocessing — Otsu binarization + morphological cleanup + watershed separation
- Particle Measurement — Equivalent diameter (Feret + Heywood weighted), shape parameters
- Distribution Analysis — DIN 66141 / ISO 9276 classification, D-values, Rosin-Rammler fit
When to Use This Skill
Trigger words: particle size analysis, granulometry, particle counting, microscopy image analysis, 粒度分析, 颗粒计数, 显微图像分析, 粒径分布, D50, D90, Rosin-Rammler, 粉体粒径, 颗粒形态
Applicable scenarios:
- Analyzing powder/granule particle size from microscopy images
- Counting and measuring particles in brightfield/darkfield/DIC images
- Computing particle size distributions (D10, D50, D90, Span)
- Fitting Rosin-Rammler distribution to particle data
- Measuring particle shape parameters (circularity, aspect ratio, etc.)
Prerequisites
Python Environment
The analysis scripts require the following packages:
numpy>=1.21.0
opencv-python>=4.5.0
scipy>=1.7.0
matplotlib>=3.4.0 # optional, for chart generation
Install into the managed Python venv:
# Create venv if not exists
C:/Users/Administrator/.workbuddy/binaries/python/versions/3.13.12/python.exe -m venv C:/Users/Administrator/.workbuddy/binaries/python/envs/default
# Install dependencies
C:/Users/Administrator/.workbuddy/binaries/python/envs/default/Scripts/pip install numpy opencv-python scipy matplotlib
Scale Calibration Parameters
Before analysis, gather the following microscope configuration:
- Eyepiece magnification (M1): typically 10x or 15x
- Objective magnification (M2): e.g., 4x, 10x, 20x, 40x, 100x
- Camera pixel size: physical sensor pixel size in micrometers (check camera spec sheet)
The scale factor is: S = pixel_size / (M1 * M2) [um/pixel]
Quick Start
Basic Analysis
# Default: brightfield, 10x eyepiece, 40x objective, 5.5um pixels
C:/Users/Administrator/.workbuddy/binaries/python/envs/default/python.exe \
~/.workbuddy/skills/microscopy-particle-analysis/scripts/particle_analyzer.py \
particle_image.tif \
--output-dir ./output
With Custom Parameters
C:/Users/Administrator/.workbuddy/binaries/python/envs/default/python.exe \
~/.workbuddy/skills/microscopy-particle-analysis/scripts/particle_analyzer.py \
darkfield_sample.png \
--mode darkfield \
--eyepiece 10 --objective 20 --pixel-size 5.86 \
--bins 0.5,1,2,5,10,20,50 \
--charts --save-mask --save-annotated \
--output-dir ./results
CLI Parameters
Required
| Parameter | Description |
|-----------|-------------|
| image | Path to microscopy image file (TIFF, PNG, JPG, BMP) |
Imaging Mode
| Parameter | Default | Description |
|-----------|---------|-------------|
| --mode | brightfield | Imaging mode: brightfield, darkfield, dic |
Scale Calibration
| Parameter | Default | Description |
|-----------|---------|-------------|
| --eyepiece | 10.0 | Eyepiece magnification M1 |
| --objective | 40.0 | Objective magnification M2 |
| --pixel-size | 5.5 | Camera pixel physical size (um) |
Equivalent Diameter Weighting
| Parameter | Default | Description |
|-----------|---------|-------------|
| --weight-feret | 0.5 | Weight for Feret diameter |
| --weight-heywood | 0.5 | Weight for Heywood diameter |
Preprocessing
| Parameter | Default | Description |
|-----------|---------|-------------|
| --kernel-size | 3 | Morphological kernel size (odd) |
| --opening | 2 | Opening iterations (noise removal) |
| --closing | 2 | Closing iterations (hole filling) |
| --no-watershed | off | Disable watershed separation |
| --watershed-threshold | 0.5 | Watershed seed threshold (0-1) |
| --min-area | 10 | Min particle area (pixels) |
| --max-area | 500000 | Max particle area (pixels) |
| --blur-size | 3 | Gaussian blur kernel (0=off) |
Distribution Analysis
| Parameter | Default | Description |
|-----------|---------|-------------|
| --standard | ISO9276 | Standard: DIN66141 or ISO9276 |
| --bin-method | log | Bin spacing: log or arithmetic |
| --bins | (default) | Custom bin boundaries, comma-separated (e.g., 0.5,1,2,5,10,20,50) |
Output
| Parameter | Default | Description |
|-----------|---------|-------------|
| --output-dir | ./output | Output directory |
| --charts | off | Generate distribution charts |
| --save-mask | off | Save binary mask image |
| --save-annotated | off | Save annotated image with contours |
Output Files
The tool generates the following output files in the specified --output-dir:
1. {basename}_particles.csv
Individual particle data, one row per particle:
| Column | Unit | Description |
|--------|------|-------------|
| label | — | Connected component ID |
| equivalent_diameter_um | um | Weighted equivalent diameter |
| feret_diameter_um | um | Maximum Feret diameter |
| min_feret_diameter_um | um | Minimum Feret diameter |
| heywood_diameter_um | um | Area-equivalent circle diameter |
| area_um2 | um^2 | Particle area |
| perimeter_um | um | Contour perimeter |
| aspect_ratio | — | Min Feret / Max Feret (0-1) |
| circularity | — | 4piA / P^2 (0-1) |
| convexity | — | Hull perimeter / contour perimeter (0-1) |
| solidity | — | Area / hull area (0-1) |
| elongation | — | 1 - aspect_ratio (0-1) |
| centroid_x, centroid_y | pixels | Particle centroid position |
2. {basename}_report.json
Complete analysis report in JSON format, including:
- Image metadata and scale configuration
- Preprocessing parameters and particle counts
- Full distribution analysis results (bins, D-values, Span, Rosin-Rammler)
- Summary statistics (mean, geometric mean, harmonic mean, std dev)
3. {basename}_distribution_charts.png (with --charts)
Distribution charts:
- Top: Number (qn) vs Volume (qv) distribution bar chart
- Bottom: Cumulative volume distribution curve with D10/D50/D90 markers
4. {basename}_mask.png (with --save-mask)
Binary mask image (0=background, 255=particle).
5. {basename}_annotated.png (with --save-annotated)
Original image with green particle contours and scale bar overlay.
Workflow
When processing a microscopy image for particle analysis:
-
Gather microscope configuration — determine eyepiece/objective magnification and camera pixel size.
-
Install dependencies — ensure numpy, opencv-python, scipy are installed in the Python environment.
-
Run the analyzer — execute
particle_analyzer.pywith appropriate parameters:- Set
--modebased on imaging technique - Set
--eyepiece,--objective,--pixel-sizefor accurate physical measurements - Adjust
--binsif custom size ranges are needed - Enable
--chartsfor visual output
- Set
-
Review results — check the console summary, CSV data, and JSON report. Verify:
- Particle count is reasonable (not 0, not excessively high)
- D50 value is in expected range for the sample
- Rosin-Rammler R² > 0.8 indicates good fit
-
Adjust parameters if needed — if results are unsatisfactory:
- No particles detected → try
--mode darkfield, lower--min-area, or--no-watershed - Over-segmentation → increase
--watershed-threshold(e.g., 0.7) - Under-segmentation → decrease
--watershed-threshold(e.g., 0.3) - Too many noise particles → increase
--min-areaor--opening
- No particles detected → try
Algorithm Details
For detailed technical documentation on the algorithms used, refer to:
references/standards_reference.md— DIN 66141 / ISO 9276 standards, equivalent diameter methods, Rosin-Rammler fitting parametersreferences/methodology.md— Otsu algorithm, morphological operations, watershed segmentation, Feret diameter calculation, Rosin-Rammler linearization
Script Architecture
scripts/
├── particle_analyzer.py # Main CLI entry point - orchestrates the full pipeline
├── image_preprocessing.py # Image loading, Otsu binarization, morphology, watershed
├── particle_measurement.py # Connected components, Feret/Heywood diameter, shape parameters
├── distribution_analysis.py # Size classification, D-values, Rosin-Rammler fitting
└── requirements.txt # Python dependencies
Limitations
- Volume estimation: Particle volume is approximated as equivalent sphere (π/6 * D³). For highly non-spherical particles, this introduces bias.
- Watershed separation: Cannot perfectly separate heavily overlapping particles. Very tight clusters may still be counted as single particles.
- Otsu thresholding: Performs poorly on images with extreme non-uniform illumination. Consider pre-processing with CLAHE in such cases.
- Rosin-Rammler fit: Best suited for ground/milled powders. Bimodal or log-normal distributions may show poor R².
- Minimum particle size: Particles smaller than ~3 pixels in diameter cannot be reliably measured. Use higher magnification for sub-micron particles.
微信扫一扫