Image-based Displacement Identification (IDI) implementation in python.
See the documentation for pyIDI.
In version 1.0, we overhauled the package API. With growing usage in IDEs other than jupyter notebooks, we have made the package more user-friendly. The new API allows the autocompletion and documentation of the package to be more accessible in IDEs like VSCode, Cursor, PyCharm, etc.
To install the new version, use the following command:
pip install pyidior to upgrade (if already installed):
pip install -U pyidiFor the user, the main difference is that instead of calling the pyIDI class where the
method is set, first, the VideoReader class is called. Then, this instance is passed
to the specific method class. Here is an example:
from pyidi import VideoReader, SimplifiedOpticalFlow
# Read the video
video = VideoReader('video.cih')
# Pass the video to the selected method class
sof = SimplifiedOpticalFlow(video)
sof.set_points(points=[[0, 1], [1, 1], [2, 1]])
sof.configure(...)
displacements = sof.get_displacements()The methods themselves have not changed, only the way they are called. Unfortunately, this breaks the backward compatibility with the previous version. We apologize for any inconvenience this may cause. To keep using the old version, please install the package with the following command:
pip install pyidi==0.30.2or when using .cine videos:
pip install pyidi[cine]or use the legacy pyIDI class:
from pyidi import pyIDINote that the legacy pyIDI class does not necessarily offer the full functionality of the new version.
The legacy pyIDI class is only kept for compatibility with the old version and will not be updated.
Run GUI by instantiating GUI class (input is VideoReader object):
from pyidi import VideoReader, GUI
# Read the video
video = VideoReader('data/data_synthetic.cih')
# Run GUI
gui = GUI(video)Method class (e.g. SimplifiedOpticalFlow) is instantiated during the use of GUI. It is accessible in gui.method. To get displacements:
method = gui.method
displacements = method.displacementsThe pyIDI method works with various formats: .cih, .cihx, .png, .avi etc. Additionally, it can also work with numpy.ndarray as input.
If an array is passed, it must have a shape of: (n time points, image height, image width).
Set the points where displacements will be determined:
p = np.array([[0, 1], [1, 1], [2, 1]]) # example of points
video.set_points(points=p)
Or use point selection UI to set individual points or grid inside selected area. For more information about UI see documentation. Launch viewer with:
A high-speed video of a vibrating music-box comb is published on Zenodo
(10.5281/zenodo.22105821, CC BY 4.0) and can be
loaded directly from pyidi. Only the requested frames are downloaded and they are cached
in ~/.pyidi/datasets (or in PYIDI_DATA_DIR), so the first call is the only slow one:
import pyidi
# 600 frames of 640x552 px, 16-bit: 404 MiB on the first call
video = pyidi.datasets.load_music_box()
lk = pyidi.LucasKanade(video)
lk.set_points([[109, 500], [175, 500], [329, 500]]) # three teeth of the comb
lk.configure(roi_size=(21, 51)) # a region one tooth tall
displacements = lk.get_displacements()The comb was recorded with a Photron FASTCAM SA-Z at 7500 fps. Its teeth are cantilevers of graduated length, so each rings at its own natural frequencies, with sub-pixel amplitudes on a naturally speckled surface — a convenient benchmark for displacement identification. The identified frequencies land within a few cents of equal-tempered pitches across nearly two octaves:
Datasets are a registry, so this one is loaded like any other: pyidi.datasets.list_datasets()
says what is available, pyidi.datasets.load_dataset('music_box') loads it, and
pyidi.datasets.register_dataset() accepts a recording of your own published the same way
(a Zenodo record with a Photron cihx header next to an uncompressed mraw file).
The full example is in examples/Showcase_music_box.ipynb:
from the raw video to the notes of the comb and to the operating deflection shape of a single
tooth. If you use the dataset, please cite it:
- Stanovnik, G., & Slavič, J. (2026). High-speed video of a vibrating music-box comb (Photron FASTCAM SA-Z, 7500 fps, 640x552 px) [Data set]. Zenodo. https://doi.org/10.5281/zenodo.22105821
- Add _name_of_method.py with class that inherits after
IDIMethods - This class must have methods:
calculate_displacementswith attributedisplacementsget_points(static method - sets attribute video.points)
- In
pyIDIadd a new method of identification inavaliable_methodsdictionary.
If you are using the pyIDI package for your research, consider citing our articles:
- Masmeijer, T., Habtour, E., Zaletelj, K., & Slavič, J. (2024). Directional DIC method with automatic feature selection. Mechanical Systems and Signal Processing, 224 . https://doi.org/10.1016/j.ymssp.2024.112080
- Čufar, K., Slavič, J., & Boltežar, M. (2024). Mode-shape magnification in high-speed camera measurements. Mechanical Systems and Signal Processing, 213, 111336. https://doi.org/10.1016/J.YMSSP.2024.111336
- Zaletelj, K., Gorjup, D., Slavič, J., & Boltežar, M. (2023). Multi-level curvature-based parametrization and model updating using a 3D full-field response. Mechanical Systems and Signal Processing, 187, 109927. https://doi.org/10.1016/j.ymssp.2022.109927
- Zaletelj, K., Slavič, J., & Boltežar, M. (2022). Full-field DIC-based model updating for localized parameter identification. Mechanical Systems and Signal Processing, 164. https://doi.org/10.1016/j.ymssp.2021.108287
- Gorjup, D., Slavič, J., & Boltežar, M. (2019). Frequency domain triangulation for full-field 3D operating-deflection-shape identification. Mechanical Systems and Signal Processing, 133. https://doi.org/10.1016/j.ymssp.2019.106287

