Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Production-ready microscopy image analysis and quantitative imaging data skill for colony morphometry, cell counting, fluorescence quantification, and statistical analysis of imaging-derived measurements. Processes ImageJ/CellProfiler output (area, circularity, intensity, cell counts), performs Dunnett's test, Cohen's d effect size, power analysis, Shapiro-Wilk normality tests, two-way ANOVA, polynomial regression, natural spline regression with confidence intervals, and comparative morphometry.
.claude/skills/tooluniverse-image-analysis/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-07 | ✗→✓ | ▲ Improved | — | — |
| case-02 | ✓→✓ | = Same ✓ | — | — |
| case-04 | ✗→✗ | = Same ✗ | — | — |
| case-05 | ✗→✗ | = Same ✗ | — | — |
| case-08 | ✗→✗ | = Same ✗ | — | — |
Production-ready skill for analyzing microscopy-derived measurement data using pandas, numpy, scipy, statsmodels, and scikit-image. Designed for BixBench imaging questions covering colony morphometry, cell counting, fluorescence quantification, regression modeling, and statistical comparisons.
IMPORTANT: This skill handles complex multi-workflow analysis. Most implementation details have been moved to references/ for progressive disclosure. This document focuses on high-level decision-making and workflow orchestration.
Apply when users:
BixBench Coverage: 21 questions across 4 projects (bix-18, bix-19, bix-41, bix-54)
NOT for (use other skills instead):
tooluniverse-phylogeneticstooluniverse-rnaseq-deseq2tooluniverse-single-celltooluniverse-statistical-modelingpython# Core (MUST be installed) import pandas as pd import numpy as np from scipy import stats from scipy.interpolate import BSpline, make_interp_spline import statsmodels.api as sm from statsmodels.formula.api import ols from statsmodels.stats.power import TTestIndPower from patsy import dmatrix, bs, cr # Optional (for raw image processing) import skimage import cv2 import tifffile
Installation:
bashpip install pandas numpy scipy statsmodels patsy scikit-image opencv-python-headless tifffile
START: User question about microscopy data
│
├─ Q1: What type of data is available?
│ │
│ ├─ PRE-QUANTIFIED DATA (CSV/TSV with measurements)
│ │ └─ Workflow: Load → Parse question → Statistical analysis
│ │ Pattern: Most common BixBench pattern (bix-18, bix-19, bix-41, bix-54)
│ │ See: Section "Quantitative Data Analysis" below
│ │
│ └─ RAW IMAGES (TIFF, PNG, multi-channel)
│ └─ Workflow: Load → Segment → Measure → Analyze
│ See: references/image_processing.md
│
├─ Q2: What type of analysis is needed?
│ │
│ ├─ STATISTICAL COMPARISON
│ │ ├─ Two groups → t-test or Mann-Whitney
│ │ ├─ Multiple groups → ANOVA or Dunnett's test
│ │ ├─ Two factors → Two-way ANOVA
│ │ └─ Effect size → Cohen's d, power analysis
│ │ See: references/statistical_analysis.md
│ │
│ ├─ REGRESSION MODELING
│ │ ├─ Dose-response → Polynomial (quadratic, cubic)
│ │ ├─ Ratio optimization → Natural spline
│ │ └─ Model comparison → R-squared, F-statistic, AIC/BIC
│ │ See: references/statistical_analysis.md
│ │
│ ├─ CELL COUNTING
│ │ ├─ Fluorescence (DAPI, NeuN) → Threshold + watershed
│ │ ├─ Brightfield → Adaptive threshold
│ │ └─ High-density → CellPose or StarDist (external)
│ │ See: references/cell_counting.md
│ │
│ ├─ COLONY SEGMENTATION
│ │ ├─ Swarming assays → Otsu threshold + morphology
│ │ ├─ Biofilms → Li threshold + fill holes
│ │ └─ Growth assays → Time-lapse tracking
│ │ See: references/segmentation.md
│ │
│ └─ FLUORESCENCE QUANTIFICATION
│ ├─ Intensity measurement → regionprops
│ ├─ Colocalization → Pearson/Manders
│ └─ Multi-channel → Channel-wise quantification
│ See: references/fluorescence_analysis.md
│
└─ Q3: When to use scikit-image vs OpenCV?
├─ scikit-image: Scientific analysis, measurements, regionprops
├─ OpenCV: Fast processing, real-time, large batches
└─ Both: Often interchangeable for basic operations
See: references/image_processing.md "Library Selection Guide"CRITICAL FIRST STEP: Before writing ANY code, identify what data files are available and what the question is asking for.
pythonimport os, glob, pandas as pd # Discover data files data_dir = "." csv_files = glob.glob(os.path.join(data_dir, '**', '*.csv'), recursive=True) tsv_files = glob.glob(os.path.join(data_dir, '**', '*.tsv'), recursive=True) img_files = glob.glob(os.path.join(data_dir, '**', '*.tif*'), recursive=True) # Load and inspect first measurement file if csv_files: df = pd.read_csv(csv_files[0]) print(f"Shape: {df.shape}") print(f"Columns: {list(df.columns)}") print(df.head()) print(df.describe())
Common Column Names:
pythondef grouped_summary(df, group_cols, measure_col): """Calculate summary statistics by group.""" summary = df.groupby(group_cols)[measure_col].agg( Mean='mean', SD='std', Median='median', Min='min', Max='max', N='count' ).reset_index() summary['SEM'] = summary['SD'] / np.sqrt(summary['N']) return summary # Example: Colony morphometry by genotype area_summary = grouped_summary(df, 'Genotype', 'Area') circ_summary = grouped_summary(df, 'Genotype', 'Circularity')
For detailed statistical functions, see: references/statistical_analysis.md
Decision guide:
See: references/statistical_analysis.md for complete implementations
When to use each model:
Model comparison metrics:
See: references/statistical_analysis.md for complete implementations
Workflow: Load → Preprocess → Segment → Measure → Export
python# Quick start for cell counting from scripts.segment_cells import count_cells_in_image result = count_cells_in_image( image_path="cells.tif", channel=0, # DAPI channel min_area=50 ) print(f"Found {result['count']} cells")
Decision guide:
| Cell Type | Density | Best Method | Notes | |-----------|---------|-------------|-------| | Nuclei (DAPI) | Low-Medium | Otsu + watershed | Standard approach | | Nuclei (DAPI) | High | CellPose/StarDist | Handles touching | | Colonies | Well-separated | Otsu threshold | Fast, reliable | | Colonies | Touching | Watershed | Edge detection | | Cells (phase) | Any | Adaptive threshold | Handles uneven illumination | | Fluorescence | Low signal | Li threshold | More sensitive |
See: references/segmentation.md and references/cell_counting.md for detailed protocols
Use scikit-image when:
Use OpenCV when:
Both work for:
See: references/image_processing.md "Library Selection Guide"
Question type: "Mean circularity of genotype with largest area?"
Data: CSV with Genotype, Area, Circularity columns
Workflow:
See: references/segmentation.md "Colony Morphometry Analysis"
Question type: "Cohen's d for NeuN counts between conditions?"
Data: CSV with Condition, NeuN_count, Sex, Hemisphere columns
Workflow:
See: references/statistical_analysis.md "Effect Size Calculations"
Question type: "Dunnett's test: How many ratios equivalent to control?"
Data: CSV with multiple co-culture ratios, Area, Circularity
Workflow:
See: references/statistical_analysis.md "Dunnett's Test"
Question type: "Peak frequency from natural spline model?"
Data: CSV with co-culture frequencies and Area measurements
Workflow:
See: references/statistical_analysis.md "Regression Modeling"
| Task | Primary Tool | Reference | |------|-------------|-----------| | Load measurement CSV | pandas.read_csv() | This file | | Group statistics | df.groupby().agg() | This file | | T-test | scipy.stats.ttest_ind() | statistical_analysis.md | | ANOVA | statsmodels.ols + anova_lm() | statistical_analysis.md | | Dunnett's test | scipy.stats.dunnett() | statistical_analysis.md | | Cohen's d | Custom function (pooled SD) | statistical_analysis.md | | Power analysis | statsmodels TTestIndPower | statistical_analysis.md | | Polynomial regression | statsmodels.OLS + poly features | statistical_analysis.md | | Natural spline | patsy.cr() + statsmodels.OLS | statistical_analysis.md | | Cell segmentation | skimage.filters + watershed | cell_counting.md | | Colony segmentation | skimage.filters.threshold_otsu | segmentation.md | | Fluorescence quantification | skimage.measure.regionprops | fluorescence_analysis.md | | Colocalization | Pearson/Manders | fluorescence_analysis.md | | Image loading | tifffile, skimage.io | image_processing.md | | Batch processing | scripts/batch_process.py | scripts/ |
Ready-to-use scripts in scripts/ directory:
Usage:
bash# Count cells in image python scripts/segment_cells.py cells.tif --channel 0 --min-area 50 # Batch process folder python scripts/batch_process.py input_folder/ output.csv --analysis cell_count
For complete implementations and protocols:
Some BixBench questions use R for analysis. Python equivalents:
multcomp::glht) → scipy.stats.dunnett() (scipy ≥ 1.10)ns(x, df=4)) → patsy.cr(x, knots=...) with explicit quantile knotst.test()) → scipy.stats.ttest_ind()aov()) → statsmodels.formula.api.ols() + sm.stats.anova_lm()See: references/statistical_analysis.md for exact parameter matching
BixBench expects specific formats:
int(round(val, -3))Before returning your answer, verify:
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-04 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 21 counted toward the lift figure. The other 1 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +5 percentage points is the difference between those two pass rates over the 21 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.