Skip to content

a Python code for mechanical Digital Image Correlation (DIC) using numpy & scikit-image

License

Notifications You must be signed in to change notification settings

xdze2/stretchablecorr

Repository files navigation

stretchable corr

a Python code for Digital Image Correlation (DIC)

  • local method: the displacemenent field between images is obtained using local cross-correlation computation.

The method used here corresponds to the figure (d) below:

deformation order

Workflow

  • Load images from a given directory, sort by alphabetical order: get an image sequence.
  • Construct a regular grid with a given spacing and margin value.
  • Compute cross-correlation for every points[*]:
    • Using Lagrangian reference i.e. points are attached to the sample surface (track points).
    • Using Eulerian reference frame i.e. points remain fixed to the camera frame.
  • Post-process & graph

[*] and image-to-image vs image-to-reference (see below)

Links:

Tips

  • Extract images from video using ffmpeg:

      ffmpeg -i test\ 2\ input_file.avi -qscale:v 4  ./output/output_%04d.tiff
    
  • When naming the images, use number padding (0001.jpg, 0002.jpg, ...etc) to keep the correct order (use alphabetical sort)

  • Record as many as possible images

Displacement field description

Eulerian and Lagragian are two different way to describe the displacement field (or flow field) depending on which frame of reference is used:

  • Eulerian: the laboratory or the camera field of view is used as reference, i.e. field evaluation points remain fixed on the images.
  • Lagrangian: points on the sample surface are tracked. The frame of reference is fixed to the sample surface.

Eulerian description corresponds to the simplest data processing approach, whereas Lagrangian description require more complex data processing. Both are similar for small displacement.

image-to-image vs image-to-reference

Another important consideration is related to the choice of the reference state. The displacement field is defined relatively to a non-deformed state. This, usualy, corresponds to the first image of the sequence.

Ideally, displacement for image i are directly computed using correlation between image i and the reference image. This is the image-to-reference approach.

However, large displacement or deformation could occur between these two images, leading to a wrong correlation estimation or simply displacement larger than the window size. An other method is to perform correlations between susccesive images and integrate (sum) instantateous displacements to obtain the absolute displacement. Performing correlation image-to-image is more robust albeit leading to the summation of correlation errors.

error propagationr

Data structures

  • cube : 3D array of floats with shape (nbr_images, height, width)
    Sequence of gray-level images.
    note: ⚠ ij convention instead of xy --> height first

  • points : 2D array of floats with shape (nbr_points, 2)
    Coordinates of points (could be unstructured, i.e. not a grid).
    (x, y) order

  • displ_field : 3D array of floats with shape (nbr_images - 1, nbr_points, 2)
    generic displacements field
    could include NaNs

  • offsets : 2D array of floats with shape (nbr_images - 1, 2)
    image-to-image overall displacement
    could include NaNs

Pseudo multi-scale approach for robust processing

Similarly to iterative optimisation methods where choice of initial guess is important. The two images to be correlated have to be similar enough. When large displacement (>>50 pixels, larger than the ROI window size) occurs mutli-step methods are used.

Here a "2-scale" approach is used:

  • first, run correlation image-to-image using downsampled images and large ROI → obtain coarse_offsets values
  • second, run correlation image-to-image for all points of the grid, using previous offsets and smaller window size (~20px)

Cross-correlation methods

  • The function phase-cross-correlation from scikit-image could be used. Cross-correlation as pixel sampling is obtained using FFT. Sub-pixel precision is obtained employing an upsampled matrix-multiplication DFT [1].

[1] Manuel Guizar-Sicairos, Samuel T. Thurman, and James R. Fienup, “Efficient subpixel image registration algorithms,” Optics Letters 33, 156-158 (2008). DOI:10.1364/OL.33.000156

  • Similar approach, but non-linear optimization (BFGS) is used to locate the cross-correlation peak. See phase_registration_optim function.

Installation

  • download the repository (git clone http://, ...)
  • python --version --> Python 3.6.9
  • $ pip install numpy scipy matplotlib scikit-image
  • $ pip install numba (optional) 

for jupyter (optional) 

jupyter notebooks and jupyter-lab are web-based interactive development environment:

$ pip install jupyter jupyterlab
$ sudo apt-get install nodejs npm
$ pip install jupytext  --upgrade

in jupyter-lab, search for command: enable extension manager then install jupytext extension.

The jupytext extension is used to automatically convert notebook file (.ipynb) to a runable python script (.py).

Development & code structure

Documentation

Github static site in the /docs folder is used.

Generate the HTMLs from the source folder ./docs_src using the script:

$ source make_doc.sh

Docstrings

note: numpy's style of docstrings is used

docstring to html transmutation is done using pdoc

$ pdoc --html --output-dir docs stretchablecorr filetools --force

Markdown with math

  • convert markdown file to html using pandoc
    simplest solution to display math equation online, with Katex

  • use pandoc's config file pandoc.yaml (needs pandoc 2.10+)

      $ pandoc --defaults=pandoc.yaml
    
  • and use simple css style

Acknowledgment

Work funded by ANR Street ARt Nano Project (ANR 18-CE09-0038-01)

About

a Python code for mechanical Digital Image Correlation (DIC) using numpy & scikit-image

Topics

Resources

License

Stars

Watchers

Forks

Languages