SubsetDIC
SubsetDIC is a Python package for 2D subset-based digital image correlation (DIC). The performance-critical algorithms are implemented in C++ and exposed to Python through pybind11.
This project is based on the algorithm flow of Ncorr and keeps the original
Ncorr reference source under reference_code/ for comparison.
For the pure Python implementation, see lbd-hfut/Subset-DIC.
Features
- Subset-based 2D DIC for grayscale image pairs.
- C++ core with Python API.
- Quintic B-spline preprocessing for image interpolation and reference-image gradients.
- ROI-based region extraction.
- SIFT or manual seed selection.
- Region-growing DIC propagation.
- Optional displacement-gradient / strain-field calculation.
- Example
ringandstarcases undercase/.
Project Layout
SubsetDIC/
|-- src/
| |-- subsetdic/ # Python API and configuration helpers
| `-- cpp/ # C++ DIC core and pybind11 bindings
|-- config/
| `-- default.yaml # Default DIC parameters
|-- case/
| |-- ring/ # Example ring images and ROI
| `-- star/ # Example star displacement images and ROI
|-- tests/
| |-- test_dic.py # Synthetic translation integration test
| `-- run_cases.py # Run bundled ring/star cases
`-- reference_code/ # Ncorr MATLAB/C++ reference implementation
Installation
Requirements:
- Python 3.9+
- CMake 3.21+
- A C++17 compiler
- Visual Studio C++ Build Tools on Windows
Install in editable mode:
python -m pip install -e .
This compiles the C++ extension module _core. In editable mode, Python source
files are loaded from this repository, while the compiled extension may be
installed into your Python environment's site-packages, for example:
C:\Users\<user>\miniconda3\Lib\site-packages\subsetdic\_core.cp312-win_amd64.pyd
After changing files in src/cpp/, run the install command again to rebuild
the extension.
Quick Start
import numpy as np
from PIL import Image
from subsetdic import SubsetDIC
ref = np.array(Image.open("case/star/001.bmp")).astype(np.float64)
cur = np.array(Image.open("case/star/002.bmp")).astype(np.float64)
roi = (np.array(Image.open("case/star/003.bmp")) > 128).astype(np.uint8)
dic = SubsetDIC({
"dic": {
"radius": 5,
"spacing": 1,
"cutoff_diffnorm": 1e-6,
"cutoff_iteration": 50,
"subsettrunc": False,
},
"seeds": {
"method": "manual",
"n_seeds": 1,
"manual_positions": [(512, 128)],
},
"strain": {
"enabled": True,
"radius": 15,
},
"border": {
"bcoef": 5,
"interp": 5,
"extrap": 5,
},
})
result = dic.run(ref, cur, roi)
print(result.success)
print(result.u.shape, result.v.shape)
print(result.valid.sum())
API
The main entry point is:
from subsetdic import SubsetDIC
dic = SubsetDIC(config)
result = dic.run(ref_img, def_img, roi_mask=None)
Inputs:
ref_img: reference image, 2D array.def_img: deformed/current image, 2D array with the same shape.roi_mask: optional 2D mask. Non-zero pixels are included in DIC.
DicResult fields:
success: whether DIC produced a result.u,v: displacement fields.corrcoef: correlation residual field.valid: valid point mask.dudx,dudy,dvdx,dvdy: displacement gradients, available when strain calculation is enabled.points_computed: number of propagated valid points.regions: ROI regions generated from the mask.
B-Spline Preprocessing
SubsetDIC follows the Ncorr-style B-spline image preprocessing path. Before
the C++ IC-GN solver starts, both reference and current images are converted to
quintic B-spline coefficient images. These coefficient images are then packed
into a QK_B_QKT lookup table.
The current-image gray value interpolation in the C++ core is evaluated from that lookup table, not from bilinear interpolation on the raw image. The reference-image gradients used by IC-GN are extracted from the same lookup table convention, so interpolation and gradient calculation share the same B-spline basis.
The pure Python version of this project is available at lbd-hfut/Subset-DIC and can be used as a reference for the B-spline preprocessing logic.
Configuration
Default parameters live in config/default.yaml.
dic:
radius: 20
spacing: 1
cutoff_diffnorm: 1.0e-6
cutoff_iteration: 50
subsettrunc: true
direct_seed_grid: false
seeds:
method: sift
n_seeds: 1
strain:
enabled: true
radius: 5
postprocess:
enabled: true
max_iterations: 8
min_neighbors: 3
corrcoef_threshold: 2.0
border:
bcoef: 20
interp: 20
extrap: 20
Important parameters:
dic.radius: subset radius in pixels.dic.spacing: grid spacing between calculated DIC points.dic.cutoff_diffnorm: IC-GN convergence threshold.dic.cutoff_iteration: maximum IC-GN iterations.dic.subsettrunc: whether to truncate subsets near ROI boundaries.dic.direct_seed_grid: solve each grid point with seed-style local search instead of region-growing propagation. This is slower but more robust for periodic or highly nonuniform displacement fields such as the star case.seeds.method:siftfor automatic seeds ormanualfor fixed positions.seeds.manual_positions: list of(x, y)seed coordinates when using manual seeds.strain.enabled: whether to compute displacement gradients.strain.radius: radius used for gradient fitting.postprocess.enabled: interpolate bad displacement points from neighboring valid points before strain calculation.postprocess.max_iterations: maximum neighbor-growing fill iterations.postprocess.min_neighbors: minimum valid 8-neighbors required to fill a bad point.postprocess.corrcoef_threshold: points with larger correlation residual are treated as bad during interpolation.
You can also override selected DIC parameters when calling run:
result = dic.run(ref, cur, roi, radius=15, spacing=3, compute_strain=False)
Running Tests
Run the synthetic translation test:
python tests\test_dic.py
Expected output includes:
PASSED
All tests passed!
If pytest is installed, the same test can be run with:
python -m pytest -q
Running Example Cases
Run bundled cases:
python tests\run_cases.py
This runs:
case/ringcase/star
Generated outputs are saved under each case's result/ directory:
u.npyv.npycorrcoef.npyvalid.npydudx.npy,dudy.npy,dvdx.npy,dvdy.npywhen strain is enabledoverview.png
The result/ directories are ignored by Git because they are generated files.
Development Notes
- Python files under
src/subsetdic/are used directly in editable installs. - C++ changes under
src/cpp/require rebuilding withpython -m pip install -e .. - The extension module is named
subsetdic._core. - Arrays passed to the C++ core are stored in column-major/Fortran layout to match the Ncorr-style indexing.
reference_code/contains the original Ncorr source used to check algorithm behavior and edge cases.
License
See LICENSE.
Metadata
Release files for subsetdic 0.1.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| subsetdic-0.1.1.tar.gz | 1.9 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| subsetdic-0.1.1-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
| subsetdic-0.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 | Details |
| subsetdic-0.1.1-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| subsetdic-0.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 | Details |
| subsetdic-0.1.1-cp310-cp310-win_amd64.whl | CPython 3.10 | CPython 3.10 | Windows x86-64 | Details |
| subsetdic-0.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl | CPython 3.10 | CPython 3.10 | Linux glibc 2.28+ x86-64, Linux glibc 2.24+ x86-64 | Details |
| subsetdic-0.1.1-cp39-cp39-win_amd64.whl | CPython 3.9 | CPython 3.9 | Windows x86-64 | Details |
| subsetdic-0.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl | CPython 3.9 | CPython 3.9 | Linux glibc 2.24+ x86-64, Linux glibc 2.28+ x86-64 | Details |
Total release size: 3.8 MB
Release files / subsetdic-0.1.1.tar.gz
| Download URL | subsetdic-0.1.1.tar.gz |
|---|---|
| Size | 1.9 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
db9428306bb1720d01226d203e316358fff04127a6406a62e7154d7efc39c7b0
|
|
BLAKE2b-256 checksum How to use checksums |
6eb3697fdffe6ce7a751a6017627aa10fe00caf44aeeb0b326a5b4eda9b7233c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp312-cp312-win_amd64.whl
| Download URL | subsetdic-0.1.1-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 330.2 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
7fa2954425f02ceb856d9f79507801991bac03b77b4f2510579197eccd6b39fb
|
|
BLAKE2b-256 checksum How to use checksums |
2063e8a3d283a8b4e86f37478c39fb59527b4d01235f79475fab7b7be37b684c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | subsetdic-0.1.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 146.4 kB |
| Tags | CPython 3.12 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
cd75a3f9e32221b9f4f81c24b5e6d4611f0265e1a51c0292ac9c4727a1566c4b
|
|
BLAKE2b-256 checksum How to use checksums |
cf5ee7492ff292b9585a4422bfadd375b15ae33f13e112c4064092d9d530630c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp311-cp311-win_amd64.whl
| Download URL | subsetdic-0.1.1-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 327.2 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
e9e1ac3a677e65e25fc81aa1247a2c6f34a3276ef725cd79a034ae394b6b93c1
|
|
BLAKE2b-256 checksum How to use checksums |
c75bd308732717081e39140e6d8c20937f637cf15745d43e0e57edf92b2cf303
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | subsetdic-0.1.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 147.2 kB |
| Tags | CPython 3.11 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
ac6e45040e24e5756a0ae0e37064c824d6244104c66c1464dd9cb1329df3fdd8
|
|
BLAKE2b-256 checksum How to use checksums |
9e23b8d548984ad4b8f47c757577b465b4af47ec610ed299fc551a7298968c42
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp310-cp310-win_amd64.whl
| Download URL | subsetdic-0.1.1-cp310-cp310-win_amd64.whl |
|---|---|
| Size | 326.5 kB |
| Tags | CPython 3.10 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
a590bf1cf45e21661acd4214f204baadea9eebaef237edf083db3b591cf44929
|
|
BLAKE2b-256 checksum How to use checksums |
873fc9cd0ca86681da13bdbe7b95b61e461179e1b6d5494b5385de0dcb593356
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | subsetdic-0.1.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 145.7 kB |
| Tags | CPython 3.10 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
0d2b1268f511331c4c5c6e491333d0ca75f4dea870c272b9aa336c746edb756f
|
|
BLAKE2b-256 checksum How to use checksums |
55f39124beb4de1f2281d000dbf3c3aa55661244d488c56def3236fa9cc433bc
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp39-cp39-win_amd64.whl
| Download URL | subsetdic-0.1.1-cp39-cp39-win_amd64.whl |
|---|---|
| Size | 327.3 kB |
| Tags | CPython 3.9 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
5a9c3fd8218ff19465b45e24a8b2f1ac0cefc11f3e2ebdfddfca37b3bbd2ace9
|
|
BLAKE2b-256 checksum How to use checksums |
acc6b6cb8ed2c4571b691f1c92801fa348b650f37dcdf0f5a82b6a7fde476247
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency logRelease files / subsetdic-0.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl
| Download URL | subsetdic-0.1.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 146.0 kB |
| Tags | CPython 3.9 Linux glibc 2.24+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
27c673230e9a438dc7dfb3562e6e7f437fa9bf499a311d5f0d78368930623232
|
|
BLAKE2b-256 checksum How to use checksums |
d55fcd2d2710e6484230379f09e2f5f3116f36ced4b172fbf75e03fb2694dd23
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 23, 2026.
Transparency log