Config-driven calibration-free multi-view DIC workflow.
Project description
PyMultiDIC
PyMultiDIC is a Python-first multi-view digital image correlation workflow. It
wraps the full solving process as public Python API calls under
pymultidic.<function_name> while keeping native C++ acceleration for the
expensive Ncorr-style 2D DIC, CPU-only COLMAP SfM, and 3D reconstruction
stages.
The project can be used in two ways:
- Install the released package with
pip install pymultidicand call the API. - Build the repository locally, including the native C++ components under
native/, then run the same API from source.
The full user manual is available here: docs/pymultidic_usage_en.md.
Example Results
The bundled case/CylinderDIC example was solved through the Python API. A
small set of representative result files is stored under
docs/results/cylinderdic.
3D morphology cloud map
Total 3D displacement cloud map
Displacement component cloud maps
| Ux | Uy | Uz |
|---|---|---|
Additional copied outputs:
- docs/results/cylinderdic/sparse_scene.png
- docs/results/cylinderdic/camera_observations_3d.png
- docs/results/cylinderdic/recon3d_002.ply
- docs/results/cylinderdic/recon3d_report.json
- docs/results/cylinderdic/pipeline_report.json
The example is regenerated from run.py using the native COLMAP ring matcher
and the native_recon3d backend. The current regenerated report registers all
12 cameras in one SfM model, exports 3606 sparse points, and reconstructs 3548
valid 3D displacement tracks for frame 002.bmp.
Install From PyPI
pip install pymultidic
Then call the package from Python:
import pymultidic
config = pymultidic.load_config("configs/MDIC.yaml")
report = pymultidic.run_pipeline(
config,
steps=["validate", "sfm", "scale", "mask", "dic2d", "recon3d", "visualize3d"],
)
You can also call the API without a YAML file. In direct-input mode,
case_root is required and the remaining paths and numerical parameters use
PyMultiDIC defaults unless overridden:
import pymultidic
report = pymultidic.run_pipeline(
case_root="case/CylinderDIC",
project_name="CylinderDIC",
steps=["validate", "sfm", "scale", "mask", "dic2d", "recon3d", "visualize3d"],
subset_radius=25,
subset_spacing=6,
min_corrcoef=0.6,
)
If an MDICConfig object is supplied, it is used as the base configuration.
Explicit keyword arguments still override matching fields for that call:
config = pymultidic.load_config("configs/MDIC.yaml")
pymultidic.run_sfm(config, colmap_workspace="colmap_native")
Local Native C++ Build
Use this route when developing the repository, changing files under native/,
or validating native builds before publishing wheels. The only supported local
source build path is the top-level native/CMakeLists.txt
entry point:
native_ncorr/libnative_ncorr.ancorr_clinative_recon3dpybind11 extensionnative_colmappybind11 extension
WSL / Linux example:
sudo apt-get update
sudo apt-get install -y \
build-essential cmake ninja-build python3-dev python3-pip \
libboost-all-dev libeigen3-dev libceres-dev libflann-dev \
libopenimageio-dev openimageio-tools libopencv-dev \
libsqlite3-dev libgflags-dev libgoogle-glog-dev \
libmetis-dev libsuitesparse-dev libglew-dev qtbase5-dev
python3 -m pip install -U pybind11 scikit-build-core
cmake -S native -B build/wsl-native -G Ninja \
-DPYBIND11_FINDPYTHON=ON \
-DPython_EXECUTABLE=/usr/bin/python3 \
-Dpybind11_DIR=$(python3 -m pybind11 --cmakedir)
cmake --build build/wsl-native
Expected WSL/Linux outputs:
build/wsl-native/ncorr/libnative_ncorr.a
build/wsl-native/ncorr/ncorr_cli
build/wsl-native/recon3d/native_recon3d*.so
build/wsl-native/colmap/native_colmap*.so
Windows example from a Developer PowerShell with CMake and Ninja available:
python -m pip install -U pybind11 scikit-build-core cmake ninja
cmake -S native -B build/windows-native -G Ninja -DPYBIND11_FINDPYTHON=ON
cmake --build build/windows-native
Expected Windows outputs include:
build/windows-native/ncorr/ncorr_cli.exe
build/windows-native/recon3d/native_recon3d*.pyd
build/windows-native/colmap/native_colmap*.pyd
After the native build, run the full example from the repository root:
python run.py --config configs/MDIC.yaml
run.py automatically prefers extensions from build/wsl-native/colmap and
build/wsl-native/recon3d, so stale editable installs do not shadow the current
checkout.
The default SfM backend is native_colmap. It embeds the required CPU-only
COLMAP code into a native_colmap pybind11 extension, so users do not need the
pycolmap Python API or a separately downloaded colmap executable. The
default matcher is ring, which imports a camera-order-aware pair list for the
multi-camera CylinderDIC layout instead of using exhaustive all-pairs matching.
This avoids unstable far-view matches on repeated speckle texture while still
using COLMAP SIFT extraction, geometric verification, and incremental mapping.
The embedded build uses the bundled COLMAP source tree in
native/colmap/upstream by default. To test a different upstream checkout, pass
-DMDIC_COLMAP_SOURCE_DIR=/path/to/colmap. If the extension is built without an
available source tree, the old external command runner is kept only as a
development fallback. Enable it explicitly with
colmap.allow_external_executable: true; otherwise native_colmap raises a
clear backend-unavailable error instead of silently requiring users to install
COLMAP. The previous pycolmap backend remains available as an optional
fallback with pip install .[pycolmap] and colmap.backend: pycolmap.
Model registration summaries and native backend capabilities are included in
sfm_report.json.
The maintained boundary is the narrow native_colmap API plus stable Multi-DIC
output files. Project-specific logic belongs in native/colmap; the upstream
COLMAP tree should stay structurally intact and be linked through
native/colmap/upstream or an explicit MDIC_COLMAP_SOURCE_DIR.
Public API
Core API functions:
pymultidic.load_config(config_path, workspace_root=None)pymultidic.build_config(config=None, *, case_root=None, ...)pymultidic.validate_project(config=None, **kwargs)pymultidic.run_validate(config=None, **kwargs)pymultidic.run_sfm(config=None, **kwargs)pymultidic.run_scale(config=None, **kwargs)pymultidic.run_mask(config=None, **kwargs)pymultidic.run_dic2d(config=None, **kwargs)pymultidic.run_recon3d(config=None, **kwargs)pymultidic.run_visualize3d(config=None, **kwargs)pymultidic.run_step(config_or_step=None, step=None, **kwargs)pymultidic.run_pipeline(config=None, steps=None, stop_on_error=True, **kwargs)
See docs/pymultidic_usage_en.md for the full function-by-function parameter reference, return values, and examples.
Workflow
flowchart TD
A["Case folder<br/>camera images and calibration images"] --> B["validate<br/>check inputs and output folders"]
B --> C["sfm<br/>camera geometry, sparse points, observations"]
C --> D["scale<br/>checkerboard world-scale correction"]
C --> E["mask<br/>ROI masks from user masks or automatic logic"]
D --> F["dic2d<br/>native ncorr per-camera 2D DIC"]
E --> F
F --> G["recon3d<br/>triangulated 3D displacement and pair surfaces"]
G --> H["visualize3d<br/>morphology and displacement cloud maps"]
H --> I["reports, npz, ply, png results"]
Manual step-by-step control:
import pymultidic
config = pymultidic.build_config(
case_root="case/CylinderDIC",
project_name="CylinderDIC",
subset_radius=25,
subset_spacing=6,
min_corrcoef=0.6,
)
for step in ["validate", "sfm", "scale", "mask", "dic2d", "recon3d", "visualize3d"]:
report = pymultidic.run_step(config, step)
if not report.get("ok"):
raise RuntimeError(f"{step} failed: {report}")
Output Layout
By default, results are written under <case_root>/<output_root>. For the
bundled example this is case/CylinderDIC/results.
Common output folders:
logs/: JSON reports for each step and the full pipeline.sfm/colmap/: camera models, sparse points, observations, and COLMAP files.scale/: checkerboard scale correction outputs.masks/: ROI masks, overlays, and debug images.dic2d/: per-camera/per-frame DIC2D.npzoutputs.recon3d/: global 3D reconstruction.npzand.plyfiles.recon3d/pairs/<frame>/: MultiDIC-style pair surface meshes.recon3d/post/<frame>/: pair-surface post-processing results.figures/: 3D visualization outputs.figures/surface_clouds/: morphology, total displacement, and Ux/Uy/Uz cloud maps.
Programmatic access to visualization outputs:
vis_report = pymultidic.run_visualize3d(config)
outputs = vis_report["outputs"]
print(outputs["surface_cloud_morphology"])
print(outputs["surface_cloud_displacement_total"])
print(outputs["surface_cloud_displacement_ux"])
print(outputs["surface_cloud_displacement_uy"])
print(outputs["surface_cloud_displacement_uz"])
Reference Source
reference_code_lib/ is kept as local reference source code. The formal
PyMultiDIC implementation lives in the repository root, the pymultidic/
package, the multidic/ implementation modules, and the native C++ projects
under native/.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distributions
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pymultidic-0.1.4.tar.gz.
File metadata
- Download URL: pymultidic-0.1.4.tar.gz
- Upload date:
- Size: 8.7 MB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2d4ea72d862acd6c6dfbb8bece100650d1172cded169435a03c6266ea39395b9
|
|
| MD5 |
fb50f140eaa1dc450cd2f60a656ba578
|
|
| BLAKE2b-256 |
39cf111075d837511dcfe43e23d3f52fc46cd0dc08615cb50fc5ba93319ee4cb
|
Provenance
The following attestation bundles were made for pymultidic-0.1.4.tar.gz:
Publisher:
wheels.yml on lbd-hfut/Multi-DIC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymultidic-0.1.4.tar.gz -
Subject digest:
2d4ea72d862acd6c6dfbb8bece100650d1172cded169435a03c6266ea39395b9 - Sigstore transparency entry: 2148355364
- Sigstore integration time:
-
Permalink:
lbd-hfut/Multi-DIC@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lbd-hfut
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymultidic-0.1.4-cp312-cp312-win_amd64.whl.
File metadata
- Download URL: pymultidic-0.1.4-cp312-cp312-win_amd64.whl
- Upload date:
- Size: 26.8 MB
- Tags: CPython 3.12, Windows x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4754aabfafe3e647a3c2c26ed750bc1803fd8f128674d3fdeb283267d2e77c5d
|
|
| MD5 |
2d29c9b1ba9d7906c4d96d71e62bd420
|
|
| BLAKE2b-256 |
4a22681f81c732d7b27d9b4f2901227b90b194eb063a81a42808d610bc24504f
|
Provenance
The following attestation bundles were made for pymultidic-0.1.4-cp312-cp312-win_amd64.whl:
Publisher:
wheels.yml on lbd-hfut/Multi-DIC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymultidic-0.1.4-cp312-cp312-win_amd64.whl -
Subject digest:
4754aabfafe3e647a3c2c26ed750bc1803fd8f128674d3fdeb283267d2e77c5d - Sigstore transparency entry: 2148355387
- Sigstore integration time:
-
Permalink:
lbd-hfut/Multi-DIC@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lbd-hfut
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymultidic-0.1.4-cp312-cp312-manylinux_2_34_x86_64.whl.
File metadata
- Download URL: pymultidic-0.1.4-cp312-cp312-manylinux_2_34_x86_64.whl
- Upload date:
- Size: 75.4 MB
- Tags: CPython 3.12, manylinux: glibc 2.34+ x86-64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2137b9669c3c45886fa272608156651568d840566e3d2b5bf4555c6cff417ee9
|
|
| MD5 |
c4fd7c93d2bb7735a703647b5b6cbcd1
|
|
| BLAKE2b-256 |
78bf2c8f41e5b6092bf94b06913320cfe063308ca442b815a6211bd33f7942ee
|
Provenance
The following attestation bundles were made for pymultidic-0.1.4-cp312-cp312-manylinux_2_34_x86_64.whl:
Publisher:
wheels.yml on lbd-hfut/Multi-DIC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymultidic-0.1.4-cp312-cp312-manylinux_2_34_x86_64.whl -
Subject digest:
2137b9669c3c45886fa272608156651568d840566e3d2b5bf4555c6cff417ee9 - Sigstore transparency entry: 2148355384
- Sigstore integration time:
-
Permalink:
lbd-hfut/Multi-DIC@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lbd-hfut
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Trigger Event:
push
-
Statement type:
File details
Details for the file pymultidic-0.1.4-cp312-cp312-macosx_14_0_arm64.whl.
File metadata
- Download URL: pymultidic-0.1.4-cp312-cp312-macosx_14_0_arm64.whl
- Upload date:
- Size: 41.9 MB
- Tags: CPython 3.12, macOS 14.0+ ARM64
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f76149942400913360a309ee8092489a3d63b7b8d3c46dc2b25cfa15255d84a1
|
|
| MD5 |
0d696fc14495c2f68a7fafbe576a186f
|
|
| BLAKE2b-256 |
31283c5936d7fe354647629b6e4f60606df0ba5f7d464a595c3d42db5ea014c7
|
Provenance
The following attestation bundles were made for pymultidic-0.1.4-cp312-cp312-macosx_14_0_arm64.whl:
Publisher:
wheels.yml on lbd-hfut/Multi-DIC
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pymultidic-0.1.4-cp312-cp312-macosx_14_0_arm64.whl -
Subject digest:
f76149942400913360a309ee8092489a3d63b7b8d3c46dc2b25cfa15255d84a1 - Sigstore transparency entry: 2148355379
- Sigstore integration time:
-
Permalink:
lbd-hfut/Multi-DIC@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Branch / Tag:
refs/tags/v0.1.4 - Owner: https://github.com/lbd-hfut
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
wheels.yml@b4263fcf4682d507a64beae68b2bc2216434a8fc -
Trigger Event:
push
-
Statement type: