虚拟引伸计与全场应变分析工具
A lightweight dual-mode strain workstation for image sequences.
This repository uses StrainTrace as its project name. Existing Windows
executables, CLI commands, and Zenodo citation/DOI metadata retain the name
ezDIC.
Main/source version: 0.1.4 · release-ready source · 2026-08-30
This source snapshot has no v0.1.4 tag or GitHub release. Any local ZIP is an unverified working artifact; use the Releases page for a published, frozen- smoke-verified Windows asset.
The current main source tree contains a narrowly scoped research-grade
upgrade. It does not bump VERSION.txt, CITATION.cff, the Zenodo record,
or the existing DOI. The 27 September MIT preparation updates repository citation and license metadata; the archived DOI remains historical. The
implemented development capability is a reproducible fixed-reference,
local-subset, in-plane 2D DIC workflow plus the existing 1D virtual
extensometer; it is not a claim of universal DIC superiority or experimental
accuracy.
The development target adds a GUI-independent core, reference-based
percentile normalization, bounded coarse-to-fine multiscale initialization,
IC-GN/IC-LM solver diagnostics, explicit point valid versus strain-fit
strain_valid, and hash-linked run provenance. The locked synthetic benchmark
is a regression gate, not an estimate of experimental uncertainty.
StrainTrace has two explicit workflows:
- Virtual extensometer: track two user-defined ROI markers and export engineering strain, true strain, QC, and Origin-compatible TXT (optional OPJU).
- Full-field 2D DIC: correlate a rectangular ROI on a fixed reference frame with IC-GN or IC-LM, sample a POI grid, and export displacement and strain maps.
The full-field DIC workflow is an in-plane, local-subset 2D method. It does not replace stereo/3D DIC, DVC, or a global finite-element DIC system.
Developed by Dr. Delun Gong · DOI 10.5281/zenodo.20222465
| You need | StrainTrace provides |
|---|---|
| Fast 1D strain | Two-ROI virtual extensometer |
| In-plane full-field maps | Rectangular ROI, POI grid, IC-GN / IC-LM, u/v and strain components |
| A fixed comparison frame | Every full-field deformation frame is correlated to the selected reference frame |
| Honest failures | Failed points/frames remain NaN; a full-field run with zero valid strain points fails |
| Lab plotting | Origin-compatible TXT; optional OPJU; publication colormaps |
| Multiple gauges | Mean ± SD / SEM; Poisson-ratio roles |
| No Python for users | Portable Windows folder with ezDIC.exe |
Virtual extensometer: Load images → draw ROI 1 + ROI 2 → track → core/ + qc/
Full-field 2D DIC: Load images → draw field ROI → IC-GN/IC-LM → dic/
Full-field analysis uses the first frame in the selected analysis range as one fixed reference. Each later frame is correlated to that same reference; the workflow does not silently switch to a frame-to-frame reference. The rectangular ROI is sampled at points of interest (POIs), so the result is a POI grid rather than a value at every image pixel. It is not a 3D measurement.
All images in the selected full-field range must have the same dimensions; a mismatch is a validation failure.
Full-field output is transactional. A new run first writes its candidate files
to a staging area. Only after the whole run completes normally are those files
committed to the dic/ root as the current result. At commit time, old
successful frame_####* files are retention-moved to the output-root
_previous_runs/<run_id>/ (a sibling of dic/), never silently overwritten.
The core output is fixed and is written under dic/ for every analyzed deformation frame with a finite strain field. A failed frame is not exported as a successful result:
dic/
├─ frame_0002.txt # x, y, u, v, zncc, valid, Exx, Eyy, Exy, exx, eyy, exy, then strain_valid and solver-quality columns
├─ frame_0002.csv
├─ frame_0002_u.png
├─ frame_0002_v.png
├─ frame_0002_Exx.png
├─ frame_0002_Eyy.png
├─ frame_0002_Exy.png
└─ frame_0002_parameters.txt
x, y, u, and v are in px. All strain components are dimensionless. Exx, Eyy, and Exy are Green–Lagrange components; exx, eyy, and exy are infinitesimal components. Exy/exy are tensor shear components (the off-diagonal strain terms), not engineering shear values with an extra factor of two.
The valid column records whether a POI correlation passed the quality threshold. strain_valid is a separate strain-fit column and is exported after the 12 core measurement fields, together with solver-quality diagnostics. Failed points are exported as NaN for measurement fields (u/v, strain, and quality fields as applicable); x/y remain the POI grid coordinates. Failed measurements are not interpolated or filled. A frame with no finite strain field is a normally skipped failed frame: it contributes no current-frame files, but other valid frames may still be committed if the run has no fatal error. If no analyzed deformation frame has valid strain points, the full-field run fails and is not reported as completed.
If a fatal I/O, solver, or export exception interrupts the run, the staging
files already produced by that run are retention-moved to the output-root
_failed_runs/<run_id>/; they are never left in the dic/ root as if they were
current successful output. The run reports failure rather than committing a
partial result. This is distinct from a normally skipped no-finite-strain
frame. Old successful outputs remain traceable in output-root
_previous_runs/<run_id>/. A first GUI run that still has pre-ledger
dic/frame_* files migrates those exact names once into
dic/_previous_runs/<timestamp>/ before the core ledger takes over.
Each valid frame also gets frame_####_parameters.txt, a human-readable provenance record. It records the fixed reference_frame_1based and reference_filename, the analyzed frame_global_1based and frame_filename, field_roi, image shape, and effective subset_size_px, step_px, strain_window, solver, zncc_min, and smoothing settings (plus the sequence fingerprint when available).
The full-field UI exposes a visible optional Exx overlay switch. The overlay is written as frame_NNNN_overlay.png over the analyzed image and is additional visual QC, not a replacement for the core tables/maps. The 1D export controls do not participate in, and cannot gate, the fixed 2D core output. Preflight requires at least a 3 × 3 POI grid; a field ROI that is too narrow for three rows or three columns is blocked before processing.
core/ strain_*.txt · optional OPJU · strain plots
qc/ qc_summary.txt
optional/ full CSV, correlation plots, overlays, parameters, publication_figures/
Primary 1D TXT:
Frame EngineeringStrain TrueStrain
engineering strain = (L - L0) / L0
true strain = ln(L / L0)
PoissonRatio = - ε_transverse / ε_axial (engineering)
Failed tracking frames stay NaN. Poisson uses role-averaged groups; tiny axial magnitude also gives NaN.
- Open the Releases page. The latest published portable ZIP is currently v0.1.3 (1D virtual extensometer). This
mainsource tree is unreleased v0.2.0-dev with v0.1.4 citation metadata; it is not a GitHub Release asset. An unverified local ZIP is not a release asset. - Extract the full downloaded folder; the portable package's top-level directory is
ezDIC_Windows_x64. Keep_internal/next toezDIC.exeand retain the license, citation, version, and notice files. - Run
ezDIC.exeon Windows 10/11 x64.
For source use, either double-click start_ezDIC.bat or:
py -3.11 -m venv .venv
.\.venv\Scripts\python.exe -m pip install -r requirements.txt
.\.venv\Scripts\python.exe dic_virtual_extensometer_gui_v7_multi_roi_range.pyFor tests and the release-build toolchain, install the pinned build/test set:
.\.venv\Scripts\python.exe -m pip install -r requirements-build.txt
.\.venv\Scripts\python.exe -m pytest -qThe implemented source CLI is GUI-independent and reads strict UTF-8 JSON
configuration against schemas/run_config_v1.json. Relative paths resolve next
to the configuration file; non-finite numbers, unknown keys, invalid mode
fields, and unsupported input shapes are rejected. image_paths and
image_folder are mutually exclusive. A folder is collected with StrainTrace's
natural image ordering and supported image suffixes. Keep analysis outputs and
benchmark reports outside the repository (for example under a caller-owned
temporary directory).
The following are minimal complete configurations. Replace the example image
and output paths with real paths; the field names are the schema field names.
The 1D reference must equal start_frame_1based; the 2D field-ROI reference
(field_roi_reference_frame_1based; if omitted, it defaults to
reference_frame_1based) must equal reference_frame_1based. A 2D run
processes the selected reference first for initialization, then correlates
every other selected frame to that same fixed reference.
{
"schema_version": 1,
"analysis_mode": "extensometer",
"image_paths": [
"C:/data/seq/frame_001.png",
"C:/data/seq/frame_002.png"
],
"start_frame_1based": 1,
"end_frame_1based": 2,
"reference_frame_1based": 1,
"output_dir": "C:/data/ezdic_1d_output",
"roi_groups": [
{
"name": "axial",
"roi1": [10, 20, 21, 21],
"roi2": [100, 20, 21, 21],
"strain_mode": "x",
"role": "axial"
}
],
"tracking": {
"template_policy": "fixed_reference",
"use_prev_frame_template": false
},
"quality": {
"min_valid_frames": 1,
"min_strain_valid_fraction": 0.8,
"enable_fb_check": true
},
"normalization": {
"policy": "reference_percentile",
"clip": true
},
"export": { "write_manifest": true },
"transaction": { "enabled": true },
"metadata": {}
}{
"schema_version": 1,
"analysis_mode": "fullfield",
"image_paths": [
"C:/data/seq/frame_001.png",
"C:/data/seq/frame_002.png"
],
"start_frame_1based": 1,
"end_frame_1based": 2,
"reference_frame_1based": 1,
"output_dir": "C:/data/ezdic_2d_output",
"field_roi": [20, 20, 120, 100],
"solver": {
"name": "IC-GN",
"subset_size_px": 21,
"step_px": 5,
"strain_window_px": 5
},
"pyramid": { "levels": 1, "scale": 0.5 },
"quality": {
"min_correlation_valid_fraction": 0.95,
"min_strain_valid_fraction": 0.8
},
"normalization": {
"policy": "reference_percentile",
"clip": true
},
"export": { "write_manifest": true },
"transaction": { "enabled": true },
"metadata": {}
}# Validate and execute the current source contract
py -3.11 -m ezdic_cli validate-config --config .\run_config.json
py -3.11 -m ezdic_cli run --config .\run_config.json
py -3.11 -m ezdic_cli run --config .\run_config.json --progress-json
py -3.11 -m ezdic_cli verify-manifest --manifest <output_dir>\run_manifest.json
py -3.11 -m ezdic_cli benchmark --output $env:TEMP\ezdic-benchmarkExit codes are stable: 0 means configuration, execution, scientific gate,
and manifest verification all passed; 2 means configuration/usage or
preflight failure; 3 means an I/O, solver, export, or other runtime failure;
and 4 means a scientific gate or manifest-verification failure.
run --progress-json emits line-delimited JSON run_started, progress, and
run_finished events while retaining the same exit-code contract. The source
entrypoint is python ezdic_cli.py; the frozen onedir bundle exposes the same
contract as ezDIC-cli.exe alongside the windowed ezDIC.exe.
Headless runs use the same fixed reference and numerical core as the GUI. Their
transaction lifecycle is the output root's current core/, qc/, optional/,
or dic/ files, recoverable sibling _previous_runs/<run_id>/ archives, and
retained fatal-run sibling _failed_runs/<run_id>/ staging. Existing current
outputs are archived only during commit; a failed run does not replace them.
The registration row in a 1D result is a reference baseline and is excluded
from the scientific deformation-frame gate. A failed POI may retain its x/y
grid coordinates, while measurement fields (u/v, strain, and applicable
quality fields) remain NaN.
A run manifest binds canonical configuration, ordered input identities and
hashes, image shape/dtype, normalization bounds, code/environment fingerprints,
output inventory and hashes, status, and the scientific gate.
verify-manifest recomputes this contract and detects changed, missing,
unexpected, or tampered manifest-listed files without modifying user data.
The optional Origin OPJU export additionally requires Windows, OriginPro 2021+, a valid local OriginPro license, and requirements-origin.txt:
.\.venv\Scripts\python.exe -m pip install -r requirements-origin.txtBuild a Windows portable package with powershell -File .\build_release.ps1. The build script validates release metadata, runs its checks fail-closed, and copies the support files into the package.
The development portable build is an onedir package containing ezDIC.exe,
ezDIC-cli.exe, the GUI-independent core/CLI/benchmark modules, and
schemas/run_config_v1.json. The wrapper's --smoke-test path imports the
core/CLI/benchmark contract before any Tk root and performs read-only checks.
It writes a marker only when EZDIC_FROZEN_SMOKE_MARKER points to a
caller-provided temporary path.
The default 1D tracking policy is a fixed reference template
(template_policy=fixed_reference, use_prev_frame_template=false).
follow_deformed_experimental is available only when explicitly enabled and
is not part of the fixed-reference claim. For full-field quality, the
best_to_second_peak_ratio_min value means best_peak / second_peak; larger
is better and the default lower bound is 1.02. It is not the inverse
second_peak / best_peak ratio. The positive coverage defaults are a minimum
0.95 correlation-valid fraction and 0.80 strain-valid fraction; they can be
made stricter in a caller configuration but are never silently relaxed.
The locked v5 synthetic engineering gate currently records the following clean
baseline values (report_version=ezdic-benchmark-report-v5,
cases_version=ezdic-benchmark-cases-v3, locked case hash
3dbe0dae3fdf8f30ec32c9fd8f036f0a53b4a705380626e7860773f62f31cb20):
| Case | Measured value | Gate |
|---|---|---|
Small translation [2.3, -1.2] |
RMSE 0.0199391 px, P95 0.0292620 px, max 0.0325828 px | strict clean baseline |
Large translation [28, -18], 3 pyramid levels, search radius 8 |
RMSE 0.0115297 px, P95 0.0239809 px, max 0.0269902 px | strict clean baseline |
| Affine field | displacement RMSE 0.00363440 px, P95 0.00651265 px, max 0.0103737 px | strict clean baseline |
| Affine strain | max component error 0.000273879, consistency error 0.000270908 | strict clean baseline |
| Near-1D periodic texture | typed AMBIGUOUS_TEXTURE before solver/export; solver_calls=0, 0 artifacts |
typed rejection; artifacts = 0 |
The quality-score v1 ranking covers 567 numeric solver rows: 563 good
and 4 bad labels, including 2 rejected bad rows. It records
ROC-AUC 0.994227353463588 with error tolerance 0.25 px (gate ≥ 0.90).
The illustrative threshold is explicitly NOT_CALIBRATED,
quality_threshold_evaluated=false, and quality_threshold_pass=null; it is
not a calibrated binary acceptance rule. Under finite-error labels the false
accept count is 2/2 = 100%; under ranking outcomes it is 2/4 = 50%.
The JSON report is hash-linked to its non-empty per-point CSV. These rates and
the ranking AUC must not be read as experimental accuracy, uncertainty, or
natural-texture performance.
In plain terms, this quality threshold is not calibrated.
The canonical evidence CSV SHA-256 is
39d4e52f35cd3161a1e877b6edcd5187568bf275c6c8d552422605b73b4c0bfb.
These are deterministic synthetic engineering-gate observations for the locked geometry, seeds, clean baselines, and image-corruption panel. They are not experimental uncertainty, calibration validation, or evidence that StrainTrace is more accurate or robust than every other DIC project.
Full-field DIC is an in-plane local-subset method using IC-GN / IC-LM with a first-order affine subset warp. It reports a POI grid, not per-pixel values; it is not stereo / 3D DIC, DVC, GPU/MPI, SIFT/AKAZE feature guidance, crack-topology masking, or global finite-element DIC. Arbitrary experimental texture is not an accepted capability claim. Pixel coordinates and displacements remain in px unless the user supplies an external calibration; strain values are dimensionless. Experimental calibration and uncertainty quantification are not implemented in this target. Failed subsets stay NaN, and finite output or a passing synthetic gate is not by itself experimental validation.
Relative to projects with stereo/3D, DVC, global-FE, GPU/MPI, or broader feature-guided solvers, StrainTrace deliberately does not claim those capabilities. Its intended narrow advantage is an auditable local workflow for the fixed-reference 2D tensile-image scenario: one numerical core, deterministic normalization, explicit quality/strain validity, transactional output, and reproducible synthetic gates.
Gong, D. (2026). ezDIC (v0.1.4). Zenodo. https://doi.org/10.5281/zenodo.20222465
See CITATION.cff, NOTICE_Attribution_and_Usage.txt, LICENSE.txt, and RELEASE_NOTES_v0.1.4.md for attribution, redistribution terms, and the release boundary.
See the submission guide for the manuscript, verified author metadata, research-use evidence and final checks. This repository is being prepared for submission; no JOSS acceptance is claimed.
Python 3.11–3.13; desktop use requires Tk. Windows is the maintained desktop platform. From a source checkout:
python -m pip install ".[test]"
straintrace --help
straintrace-guiFor a reproducible numerical check, run from a different directory:
straintrace benchmark --output straintrace-synthetic-checkThis generates its own synthetic images and reports defined numerical gates. It is not experimental accuracy or quality-threshold calibration. See API, contributing, and support.
The author authorized MIT licensing of the current source on 27 September 2026. See LICENSE.txt. Historical ezDIC archives retain their original records; the historical metadata does not govern this candidate. The existing DOI is not an archive of the new MIT preparation. Legacy module names, source version 0.1.4 and executable identity remain for compatibility; use the Git commit to identify this candidate and choose a distinct final release version after review.

