pyIDI source code#
Video Reader#
Module for reading video files from high-speed video recordings.
@author: Ivan Tomac (itomac@fesb.hr), Klemen Zaletelj (klemen.zaletelj@fs.uni-lj.si), Janko Slavič (janko.slavic@fs.uni-lj.si)
- class pyidi.video_reader.VideoReader(input_file, root=None, fps=None)[source]#
Bases:
objectManages reading of high-speed video recordings. The video recording can be any of the supported file formats which includes image streams, video files or memory map for “mraw” file format.
This applies to frames from image and video file formats: Reader returns the frame as a monochrome image. For colour images automatic conversion to grayscale (luma channel) is performed. Other channels can be selected (“R”, “G”, “B”) or custom weights can be applied. The reader returns image in 2D “numpy.array” (“height, width”) of type “numpy.uint8” or “numpy.uint16” depending on the bit depth of the originalimage file.
- __init__(input_file, root=None, fps=None)[source]#
The video recording is initialized by providing the path to the image/video file, “cih(x)” file from Photron, or “numpy.ndarray”. For image stream it is enough to provide the path to the any image file in the sequence. Images in stream must be in the same directory and named in the way that can be sorted in the correct order, e.g. for stream of 10000 images file names should be: “im_0000.ext, …, im_9999.ext”. Image formats that support multiple images, such as “gif”, “tif” are supported too. Upgrade is needed to enable higher bit depth then 8 bit for video file formats.
- Parameters:
input_file (str) – path to the image/video or “cih(x)” file
root (str) – root directory of the image/video file. Only used when the input file is a “np.ndarray”. Defaults to None.
fps (int or None) – frames per second. If None and Photron file is passed, the fps is read from the cih/cihx file. Defaults to None.
- configure(**kwargs)[source]#
Configure reader parameters after initialization.
Supported keyword arguments:
fps(int): Frames per second.root(str): Root directory for output or image sequence files. Used with “np.ndarray”.The directory is created if it does not exist.video_format(str): PyAV pixel format string used when reading frames. (default: “gray”, “gray16be”, “gray16le”). For custom selection of image channels, or using custom weights for conversion to monochrome, video format must be set to the RGB format, depending on the bit depth of the original image file, e.g. “rgb24”, “rgb48le”, “rgb48be”.channel(str): Colour channel to extract from RGB images. Must be one of “R”, “G”, “B”.channel_weights(list or tuple): Three weights applied to the RGB channels to produce a monochrome image, e.g. luma coefficients[0.299, 0.587, 0.114].
- Parameters:
kwargs (dict) – Keyword arguments as described above.
- Raises:
ValueError – If
channelis not a string orchannel_weightsis not a list/tuple of length 3.
- get_frame(frame_number, *args, **kwargs)[source]#
Returns the “frame_number”-th frame from the video. Frames from image and video files are checked for the bit depth and converted to 8 or 16 bit depth if needed. The frames from “numpy.ndarray” and “mraw” files are returned as they are.
- Parameters:
frame_number (int) – frame number
args – additional arguments to be passed to the image readers to handle
multiple channels in image :param kwargs: additional keyword arguments forwarded to image/video reader methods :type kwargs: dict :return: image (monochrome)
- get_frames(frame_range=None, *args, **kwargs)[source]#
Returns all the available frames.
If “mraw” or “np.ndarray”, it returns the frames as they are. If images or mp4, avi, etc., the
get_framemethod is called in a loop. In this case, theargsare passed to theget_framemethod (see theget_framemethod for details).- Parameters:
frame_range (tuple, list, int, None, optional) – The range of the frames to return. If None, all frames are returned. If int, the frames from zero to
frame_rangeare returned. If tuple, the frames from first to second index are returned.args – positional arguments forwarded to
get_framekwargs (dict) – keyword arguments forwarded to
get_frame
- _get_frame_from_image(frame_number)[source]#
Reads the frame from the image stream, or image file containing multiple images. 8bit and 16 bit images are supported. The bit depth is determined from the image properties. Color images are automatically converted to monochrome using a weighted sum with weights [0.299, 0.587, 0.114] by setting format to “gray” in
iio.imread. If the channel is configured as “R”, “G” or “B”, using a configuration method, the corresponding channel is returned or if the custom channel weights are set using a configuration method, the weighted sum of the “RGB” channels is returned.- Parameters:
frame_number (int) – frame number
- Returns:
image (monochrome)
- _get_frame_from_video_file(frame_number)[source]#
Reads the frame from the video file which is supported by the “imagio.v3” “pyav” plug-in. Returns the frame as a monochrome image (sum with weights [0.299, 0.587, 0.114]). Custom channel selection and custom weights for conversion to monochrome are supported by setting
channelorchannel_weightsusing configuration method.- Parameters:
frame_number (int) – frame number
- Returns:
monochrome image in 8 bit depth (note: needs upgrade to support higher bit depth)
- _initialise_phortron_camera_files(input_file)[source]#
Initialise reader state for Photron
cih/cihxsources.Loads frame data and metadata using
pyMRAWand populates core attributes such as frame count, image size, fps and source metadata.- Parameters:
input_file (str) – Path to a Photron header file (
.cihor.cihx)
- _initialise_slow_files(input_file)[source]#
Initialise reader state for
.slowrecordings.- Parameters:
input_file (str) – Path to a
.slowfile
- _initalise_image_files(input_file)[source]#
Initialise reader state for image files and image sequences.
Stores metadata from
imageioinself.image_meta. Theself.image_meta["video_format"]value is later used when reading frames via thepyavplugin to preserve the detected pixel format.- Parameters:
input_file (str) – Path to an image file from the sequence or a multi-image file
- _initialise_video_files(input_file)[source]#
Initialise reader state for video containers handled by
pyav.- Parameters:
input_file (str) – Path to a supported video file
- _initialise_numpy_array(input_file)[source]#
Initialise reader state when source frames are provided as ndarray.
- Parameters:
input_file (numpy.ndarray) – Frame stack with shape
(N, H, W)
IDIMetod base class#
- class pyidi.methods.idi_method.IDIMethod(video: VideoReader, *args, **kwargs)[source]#
Bases:
objectCommon functions for all methods.
- __init__(video: VideoReader, *args, **kwargs)[source]#
The image displacement identification method constructor.
For more configuration options, see method.configure()
- configure()[source]#
Configure the displacement identification method here.
IMPORTANT:#
All of the settings should be passed through this method. Inside the method, each setting should be saved as an attribute of the class, keeping the same name as the argument. This is important as the settings are then saved to the results file and can be used to reproduce the results.
See the
LucasKanadeexample for example usage.
- configure_multiprocessing(process_number, progress, task_id)[source]#
Configure the multiprocessing settings here.
- Parameters:
process_number (int) – The number of the process.
progress (multiprocessing.Value) – The progress object.
task_id (multiprocessing.Value) – The task ID.
- calculate_displacements()[source]#
Calculate the displacements of set points here. The result should be saved into the self.displacements attribute.
- create_temp_files(init_multi=False)[source]#
Temporary files to track the solving process.
This is done in case some error occurs. In this eventuality the calculation can be resumed from the last computed time point.
- Parameters:
init_multi (bool, optional) – when initialization multiprocessing, defaults to False
- update_log(last_time)[source]#
Updating the log file.
A new last time is written in the log file in order to track the solution process.
- Parameters:
last_time (int) – Last computed time point (index)
- resume_temp_files()[source]#
Reload the settings written in the temporary files.
When resuming the computation of displacement, the settings are loaded from the previously created temporary files.
- temp_files_check()[source]#
Checking the settings of computation.
The computation can only be resumed if all the settings and data are the same as with the original analysis. This function checks that (writing all the setting to dict and comparing the json dump of the dicts).
If the settings are the same but the points are not, a new analysis is also started. To set the same points, check the temp_pyidi folder.
- Returns:
Whether to resume analysis or not
- Return type:
bool
- _make_comparison_dict()[source]#
Make a dictionary for comparing the original settings with the current settings.
Used for finding out if the analysis should be resumed or not.
- Returns:
Settings
- Return type:
dict
- show_points(figsize=(15, 5), cmap='gray', color='r')[source]#
Shoe points to be analyzed, together with ROI borders.
- Parameters:
figsize – matplotlib figure size, defaults to (15, 5)
cmap – matplotlib colormap, defaults to ‘gray’
color – marker and border color, defaults to ‘r’
Simplified optical flow#
- class pyidi.methods._simplified_optical_flow.SimplifiedOpticalFlow(video: VideoReader, *args, **kwargs)[source]#
Bases:
IDIMethodDisplacmenet computation based on Simplified Optical Flow method [1].
- Literature:
- [1] Javh, J., Slavič, J., & Boltežar, M. (2017). The subpixel resolution
of optical-flow-based modal analysis. Mechanical Systems and Signal Processing, 88, 89–99.
- [2] Lucas, B. D., & Kanade, T. (1981). An Iterative Image Registration
Technique with an Application to Stereo Vision. In Proceedings of the 7th International Joint Conference on Artificial Intelligence - Volume 2 (pp. 674–679). San Francisco, CA, USA: Morgan Kaufmann Publishers Inc.
- configure(subset_size=3, pixel_shift=False, convert_from_px=1.0, frame_range='all', mean_n_neighbours=0, zero_shift=False, progress_bar=True, reference_range=(0, 100))[source]#
Set the attributes, compute reference image and gradients.
- Parameters:
video (object) – ‘parent’ object
subset_size – size of the averaging subset, defaults to 3
subset_size – int, optional
pixel_shift – use pixel shift or not?, defaults to False
pixel_shift – bool, optional
convert_from_px – distance unit per pixel, defaults to 1.
convert_from_px – float or int, optional
frame_range – what range of images to calculate into displacements, defaults to ‘all’
frame_range – str or tuple, optional
mean_n_neighbours – average the displacements of neighbouring points (how many points), defaults to 0
mean_n_neighbours – int, optional
zero_shift – shift the mean of the signal to zero?, defaults to False
zero_shift – bool, optional
progress_bar – show progress bar while calculating the displacements, defaults to True
progress_bar – bool, optional
reference_range – what range of images is averaged into reference image, defaults to (0, 100)
reference_range – tuple, optional
- calculate_displacements()[source]#
Calculate the displacements of set points here. The result should be saved into the self.displacements attribute.
- pixel_shift_fun(i, points, image_shape)[source]#
Pixel shifting implementation. Points that are going outside of the image range are excluded.
- _reference()[source]#
Calculation of the reference image, image gradients and gradient amplitudes.
- Parameters:
images – Images to average. Usually the first 100 images.
subset_size – Size of the subset to average.
- Returns:
Reference image, image gradient in 0 direction, image gradient in 1 direction, gradient magnitude
- class pyidi.methods._simplified_optical_flow.PickPoints(video, subset, axis, min_grad)[source]#
Bases:
objectPick the area of interest.
Select the points with highest gradient in vertical direction.
- inside_polygon(x, y, points)[source]#
Return True if a coordinate (x, y) is inside a polygon defined by a list of verticies [(x1, y1), (x2, x2), … , (xN, yN)].
Reference: http://www.ariel.com.au/a/python-point-int-poly.html
The Lucas-Kanade algorithm for translations#
- class pyidi.methods._lucas_kanade.LucasKanade(video: VideoReader, *args, **kwargs)[source]#
Bases:
IDIMethodTranslation identification based on the Lucas-Kanade method using least-squares iterative optimization with the Zero Normalized Cross Correlation optimization criterium.
- configure(roi_size=(9, 9), pad=2, max_nfev=20, tol=1e-08, int_order=3, verbose=1, show_pbar=True, processes=1, resume_analysis=False, reference_image=0, frame_range='full')[source]#
Displacement identification based on Lucas-Kanade method, using iterative least squares optimization of translatory transformation parameters to determine image ROI translations.
- Parameters:
roi_size (tuple, list, int, optional) – (h, w) height and width of the region of interest. ROI dimensions should be odd numbers. Defaults to (9, 9)
pad (int, optional) – size of padding around the region of interest in px, defaults to 2
max_nfev (int, optional) – maximum number of iterations in least-squares optimization, defaults to 20
tol (float, optional) – tolerance for termination of the iterative optimization loop. The minimum value of the optimization parameter vector norm.
int_order (int, optional) – interpolation spline order
verbose (int, optional) – show text while running, defaults to 1
show_pbar (bool, optional) – show progress bar, defaults to True
processes (int, optional, defaults to 1.) – number of processes to run
resume_analysis – if True, the last analysis results are loaded and computation continues from last computed time point.
reference_image (int or tuple or ndarray) – The reference image for computation. Can be index of a frame, tuple (slice) or numpy.ndarray that is taken as a reference.
frame_range (tuple or "full") – Part of the video to process. If “full”, a full video is processed. If first element of tuple is not 0, a appropriate reference image should be chosen.
- calculate_displacements()[source]#
Calculate displacements for set points and roi size.
kwargs are passed to configure method. Pre-set arguments (using configure) are NOT changed!
- optimize_translations(G, F_spline, maxiter, tol, d_subpixel_init=(0, 0), point_index=None, frame=None)[source]#
Determine the optimal translation parameters to align the current image subset G with the interpolated reference image subset F.
- Parameters:
G (array of shape roi_size) – the current image subset.
F_spline (scipy.interpolate.RectBivariateSpline) – interpolated referencee image subset
maxiter (int) – maximum number of iterations
tol (float) – convergence criterium
d_subpixel_init – initial subpixel displacement guess, relative to the integrer position of the image subset G
point_index (int, optional) – index of the point being processed (for error messages)
frame (int, optional) – frame number being processed (for error messages)
- Returns:
the obtimal subpixel translation parameters of the current image, relative to the position of input subset G.
- Return type:
array of size 2
- _padded_slice(point, roi_size, image_shape, pad=None)[source]#
Returns a slice that crops an image around a given
pointcenter,roi_sizeandpadsize. If the resulting slice would be out of bounds of the image to be sliced (given byimage_shape), the slice is snifted to be on the image edge and a warning is issued.- Parameters:
point (array_like of size 2, (y, x)) – The center point coordiante of the desired ROI.
roi_size – Size of desired cropped image (y, x). type roi_size: array_like of size 2, (h, w)
image_shape – Shape of the image to be sliced, (h, w). type image_shape: array_like of size 2, (h, w)
pad (int, optional, defaults to None) – Pad border size in pixels. If None, the video.pad attribute is read.
- Return crop_slice:
tuple (yslice, xslice) to use for image slicing.
- _set_reference_image(video: VideoReader, reference_image)[source]#
Set the reference image.
- _interpolate_reference(video: VideoReader)[source]#
Interpolate the reference image.
Each ROI is interpolated in advanced to save computation costs. Meshgrid for every ROI (without padding) is also determined here and is later called in every time iteration for every point.
- Parameters:
video (object) – parent object
- pyidi.methods._lucas_kanade.multi(video: VideoReader, idi_method: LucasKanade, processes, configuration_keys: list)[source]#
Splitting the points to multiple processes and creating a pool of workers.
- Parameters:
video (VideoReader) – VideoReader object
idi_method (IDIMethod) – IDIMethod object
processes (int) – number of processes to run
configuration_keys (list) – list of configuration keys
- pyidi.methods._lucas_kanade.worker(points, idi_kwargs, method_kwargs, i, progress, task_id)[source]#
A function that is called when for each job in multiprocessing.
- pyidi.methods._lucas_kanade.compute_inverse_numba(Gx, Gy, tol=1e-10)[source]#
Compute the inverse of the gradient matrix for Lucas-Kanade optimization.
- Parameters:
Gx – x-gradient of the image subset
Gy – y-gradient of the image subset
tol – tolerance for detecting singular matrix
- Returns:
inverse matrix, or None if the matrix is near-singular
Directional Lucas-Kanade#
- class pyidi.methods._directional_lucas_kanade.DirectionalLucasKanade(video: VideoReader, *args, **kwargs)[source]#
Bases:
IDIMethodUnidirectional translation identification as introduced in: Masmeijer T., Habtour E., Zaletelj, K., & Slavič, J., (2024). Directional DIC method with automatic feature selection. MSSP. “https://doi.org/10.1016/j.ymssp.2024.112080”. The implementation is based on the Lucas-Kanade method using least-squares iterative optimization with the Zero Normalized Cross Correlation optimization criterium.
- configure(roi_size=(9, 9), dij=(1, 0), pad=(2, 2), max_nfev=20, tol=1e-08, int_order=3, verbose=1, show_pbar=True, processes=1, resume_analysis=False, reference_image=0, frame_range='full', use_numba=False)[source]#
Displacement identification based on Directional Lucas-Kanade method, using iterative least squares optimization of translatory transformation parameters to determine image ROI translations.
- Parameters:
video (object) – parent object
roi_size (tuple, list, int, optional) – (h, w) height and width of the region of interest. ROI dimensions should be odd numbers. Defaults to (9, 9)
dij (tuple, list, optional) – Assumed vibration direction. If |d| != 1, the vector is normalized. Convention is ‘negative down, positive right’.
pad (int, optional) – size of padding around the region of interest in px, defaults to 2
max_nfev (int, optional) – maximum number of iterations in least-squares optimization, defaults to 20
tol (float, optional) – tolerance for termination of the iterative optimization loop. The minimum value of the optimization parameter vector norm.
int_order (int, optional) – interpolation spline order
verbose (int, optional) – show text while running, defaults to 1
show_pbar (bool, optional) – show progress bar, defaults to True
processes (int, optional, defaults to 1.) – number of processes to run
resume_analysis (bool, optional) – if True, the last analysis results are loaded and computation continues from last computed time point.
reference_image (int or tuple or ndarray) – The reference image for computation. Can be index of a frame, tuple (slice) or numpy.ndarray that is taken as a reference.
frame_range (tuple or "full") – Part of the video to process. If “full”, a full video is processed. If first element of tuple is not 0, a appropriate reference image should be chosen.
use_numba (bool) – Use numba.njit for computation speedup. Currently not implemented.
- calculate_displacements(**kwargs)[source]#
Calculate displacements for set points and roi size.
kwargs are passed to configure method. Pre-set arguments (using configure) are NOT changed!
- optimize_translations(G, F_spline, maxiter, tol, dij, d_subpixel_init=(0, 0))[source]#
Determine the optimal translation parameters to align the current image subset G with the interpolated reference image subset F.
- Parameters:
G (array of shape roi_size) – the current image subset. (G already is of type float64)
F_spline (scipy.interpolate.RectBivariateSpline) – interpolated referencee image subset
maxiter (int) – maximum number of iterations
tol (float) – convergence criterium
d_subpixel_init – initial subpixel displacement guess, relative to the integrer position of the image subset G
- Returns:
the obtimal subpixel translation parameters of the current image, relative to the position of input subset G.
- Return type:
array of size 2
- _padded_slice(point, roi_size, image_shape, pad=None)[source]#
Returns a slice that crops an image around a given point center, roi_size and pad size. If the resulting slice would be out of bounds of the image to be sliced (given by image_shape), the slice is snifted to be on the image edge and a warning is issued. :param point: The center point coordiante of the desired ROI. :type point: array_like of size 2, (y, x) :param roi_size: Size of desired cropped image (y, x). :type roi_size: array_like of size 2, (h, w) :param image_shape: Shape of the image to be sliced, (h, w). :type image_shape: array_like of size 2, (h, w) :param pad: Pad border size in pixels. If None, the video.pad attribute is read. :type pad: int, optional, defaults to None :return crop_slice: tuple (yslice, xslice) to use for image slicing.
- _interpolate_reference(video)[source]#
Interpolate the reference image.
Each ROI is interpolated in advanced to save computation costs. Meshgrid for every ROI (without padding) is also determined here and is later called in every time iteration for every point.
- Parameters:
video (object) – parent object
- pyidi.methods._directional_lucas_kanade.multi(video: VideoReader, idi_method: DirectionalLucasKanade, processes, configuration_keys: list)[source]#
Splitting the points to multiple processes and creating a pool of workers.
- Parameters:
video (VideoReader) – VideoReader object
idi_method (IDIMethod) – IDIMethod object
processes (int) – number of processes to run
configuration_keys (list) – list of configuration keys
Digital Image Correlation (DIC)#
Full-field 2D Digital Image Correlation method for pyidi.
This module is a port of the pyDIC library by the LADISK research group
(University of Ljubljana, Faculty of Mechanical Engineering) into pyidi’s
multi-point IDIMethod framework. The original pyDIC implementation lives
at:
Algorithmically, this module mirrors the original: Inverse Compositional
Gauss-Newton (IC-GN) optimization with the Zero Normalized Sum of Squared
Differences (ZNSSD) criterion, with both a 6-parameter affine and a
3-parameter rigid (translation + in-plane rotation) warp model. Per-point
precomputables (gradient, steepest-descent images, Hessian) and the warp
update equations follow pyDIC’s py_dic.dic and py_dic.dic_tools
modules.
Differences with respect to the upstream pyDIC implementation:
The single-ROI, function-call API of pyDIC is wrapped into a multi-point
IDIMethodsubclass (DIC) so that many subsets can be tracked in a single analysis with the standard pyidi configuration / checkpointing / multiprocessing infrastructure.The full converged warp parameters are exposed per point per frame as
self.warp_params(see theDICclass docstring).Subset coordinates are mean-centered so that, at the identity warp, the spline of the target frame is sampled exactly at each point’s center.
- class pyidi.methods._dic.DIC(video: VideoReader, *args, **kwargs)[source]#
Bases:
IDIMethodFull-field 2D Digital Image Correlation method using Inverse Compositional Gauss-Newton optimization with the Zero Normalized Sum of Squared Differences (ZNSSD) criterion.
Origin#
This class is a port of the pyDIC library (ladisk/pyDIC, LADISK research group, University of Ljubljana) into the pyidi multi-point
IDIMethodframework. The core math (gradient kernel, Jacobians, steepest-descent images, Hessian, inverse-compositional warp update, ZNSSD error image) follows pyDIC’spy_dic.dicandpy_dic.dic_toolsmodules. Please cite the underlying algorithm and the pyDIC repository when using this method.Outputs#
After
get_displacements()two arrays are populated on the instance:self.displacements: shape(n_points, n_frames, 2)with columns[dy, dx]. This is the standard pyidi output (subset-center translation only) and is the value returned byget_displacements.self.warp_params: shape(n_points, n_frames, n_param)holding the full converged warp parameter vector per point per frame.
The contents of
warp_paramsdepend on the chosen warp model:Affine (
warp='affine', default,n_param=6): columns are[du/dx, du/dy, u, dv/dx, dv/dy, v]whereu, vare the translations in x and y, anddu/dx,du/dy,dv/dx,dv/dyare the in-plane displacement gradients (first-order shape function). Useful derived quantities:eps_xx = warp_params[..., 0] # du/dx eps_yy = warp_params[..., 4] # dv/dy shear_xy = 0.5 * (warp_params[..., 1] + warp_params[..., 3]) rotation = 0.5 * (warp_params[..., 3] - warp_params[..., 1]) # rad
Green-Lagrange strains follow the standard formulae:
E_xx = du/dx + 0.5 * (du/dx**2 + dv/dx**2) E_yy = dv/dy + 0.5 * (du/dy**2 + dv/dy**2) E_xy = 0.5 * (du/dy + dv/dx + du/dx*du/dy + dv/dx*dv/dy)
Rigid (
warp='rigid',n_param=3): columns are[u, v, phi]wherephiis the in-plane rotation in radians.Persistence#
When
get_displacements(autosave=True)is used,warp_paramsis pickled towarp_params.pklnext toresults.pklin the analysis folder and is automatically reattached bypyidi.load_analysis.- configure(roi_size=(21, 21), pad=2, max_nfev=100, tol=1e-06, int_order=3, warp='affine', prefilter_gauss=True, verbose=1, show_pbar=True, processes=1, resume_analysis=False, reference_image=0, frame_range='full')[source]#
Configure the DIC method.
- Parameters:
roi_size (tuple, list, int, optional) – (h, w) height and width of the region of interest. ROI dimensions should be odd numbers. Defaults to (21, 21).
pad (int, optional) – padding around the ROI in px (interpolation safety).
max_nfev (int, optional) – maximum number of IC-GN iterations per point per frame.
tol (float, optional) – convergence threshold on the L2 norm of the parameter increment
dp.int_order (int, optional) – interpolation spline order for the target image.
warp (str, optional) – warp model name. Either
'affine'(6 parameters) or'rigid'(3 parameters). Defaults to'affine'.prefilter_gauss (bool, optional) – if True, use the Gauss-prefiltered finite difference kernel
[-0.446, 0, 0.446]for the reference gradient. Otherwise use[-0.5, 0, 0.5].verbose (int, optional) – show text while running.
show_pbar (bool, optional) – show progress bar.
processes (int, optional) – number of processes to run.
resume_analysis (bool, optional) – if True, the last analysis results are loaded and computation continues from the last computed time point.
reference_image (int or tuple or ndarray) – reference image. Index of a frame, tuple (slice) or numpy.ndarray.
frame_range (tuple or "full") – part of the video to process. If
'full', the full video is processed.
- calculate_displacements()[source]#
Calculate displacements for the configured points and ROI size.
Convention notes#
pyidi points are stored as
(y, x)(row, column).The warp matrix
Wis a 3x3 homogeneous transform whose first row drives the x coordinate and second row the y coordinate. The subset grid coordinates(xx, yy)are centered on zero, so whenW = Ithe spline is sampled exactly at each point’s center.After convergence,
W[0, 2]is the subpixel displacement in x andW[1, 2]is the subpixel displacement in y. These are stored as[dy, dx]inself.displacements, matching the LucasKanade output convention.
- _announce_run_state()[source]#
Print resume / new-analysis banner and reset
resume_analysisif needed.
- _run_time_loop(video, current_warps)[source]#
Iterate over frames, optimizing each point and storing results.
- _process_frame(G_spline, current_warps, frame_index, ii)[source]#
Optimize all points for a single frame and store outputs.
- _optimize_warp(G_spline, point, W_init, point_index, frame)[source]#
Run IC-GN optimization for a single point at the current frame.
- Parameters:
G_spline (scipy.interpolate.RectBivariateSpline) – spline of the target frame
Gevaluated in image coordinates.point (array_like of size 2) –
(y, x)image-space center of the subset.W_init (numpy.ndarray) – initial 3x3 warp matrix (subset-local coordinates).
point_index (int) – index of the current point (for diagnostics).
frame (int) – current frame index (for diagnostics).
- Returns:
converged 3x3 warp matrix.
- Return type:
numpy.ndarray
- _padded_slice(point, roi_size, image_shape, pad=None)[source]#
Return
(yslice, xslice)cropping an image aroundpoint.If the resulting slice would be out of bounds of the image (given by
image_shape), the slice is shifted to the image edge and a warning is issued.- Parameters:
point (array_like of size 2) – center coordinate of the desired ROI,
(y, x).roi_size (array_like of size 2) – size of the cropped image,
(h, w).image_shape (array_like of size 2) – shape of the image to be sliced,
(h, w).pad (int, optional) – pad border size in pixels. If None,
self.padis used.
- Returns:
(yslice, xslice)to use for image slicing.- Return type:
tuple of slice
- _set_reference_image(video: VideoReader, reference_image)[source]#
Set the reference image.
- _precompute_reference(video: VideoReader)[source]#
Precompute per-point reference quantities for the IC-GN loop.
For every point this stores the reference subset
F, its mean and standard deviation, the steepest-descent imagesSD, and the inverse Hessianinv_H.- Parameters:
video (VideoReader) – parent video object.
- pyidi.methods._dic._jacobian_affine(h, w)[source]#
Affine warp Jacobian on centered subset coordinates.
- Parameters:
h (int) – subset height.
w (int) – subset width.
- Returns:
array of shape
(2, 6, h, w).- Return type:
numpy.ndarray
- pyidi.methods._dic._jacobian_rigid(h, w)[source]#
Rigid warp Jacobian (evaluated at
p = 0) on centered coords.- Parameters:
h (int) – subset height.
w (int) – subset width.
- Returns:
array of shape
(2, 3, h, w).- Return type:
numpy.ndarray
- pyidi.methods._dic._sd_images(grad, jac)[source]#
Compute the steepest-descent images.
- Parameters:
grad (tuple of numpy.ndarray) – tuple
(gx, gy)of subset gradients with shape(h, w).jac (numpy.ndarray) – warp Jacobian with shape
(2, n_param, h, w).
- Returns:
SD images with shape
(n_param, h, w).- Return type:
numpy.ndarray
- pyidi.methods._dic._hessian(sd)[source]#
Compute the (Gauss-Newton) Hessian from the SD images.
- Parameters:
sd (numpy.ndarray) – SD images with shape
(n_param, h, w).- Returns:
Hessian with shape
(n_param, n_param).- Return type:
numpy.ndarray
- pyidi.methods._dic._affine_warp_matrix(p)[source]#
Build the 3x3 affine warp matrix from parameter vector
p.- Parameters:
p (array_like of size 6) – parameters
[du/dx, du/dy, u, dv/dx, dv/dy, v].- Returns:
3x3 warp matrix.
- Return type:
numpy.ndarray
- pyidi.methods._dic._rigid_warp_matrix(p)[source]#
Build the 3x3 rigid warp matrix from parameter vector
p.- Parameters:
p (array_like of size 3) – parameters
[u, v, phi].- Returns:
3x3 warp matrix.
- Return type:
numpy.ndarray
- pyidi.methods._dic._params_from_affine_matrix(M)[source]#
Extract the 6-component affine parameter vector from a 3x3 matrix.
- Parameters:
M (numpy.ndarray) – 3x3 affine warp matrix.
- Returns:
parameter vector
[du/dx, du/dy, u, dv/dx, dv/dy, v].- Return type:
numpy.ndarray
- pyidi.methods._dic._params_from_rigid_matrix(M)[source]#
Extract the 3-component rigid parameter vector from a 3x3 matrix.
- Parameters:
M (numpy.ndarray) – 3x3 rigid warp matrix.
- Returns:
parameter vector
[u, v, phi].- Return type:
numpy.ndarray
- pyidi.methods._dic._gradient_dic(image, prefilter_gauss=True)[source]#
Compute image gradients using a 1-D finite-difference kernel.
- Parameters:
image (numpy.ndarray) – input 2-D image.
prefilter_gauss (bool) – if True, use the Gauss-prefiltered kernel
[-0.446, 0, 0.446]. Otherwise use[-0.5, 0, 0.5].
- Returns:
tuple
(gx, gy)of arrays with the same shape asimage.- Return type:
tuple of numpy.ndarray
- pyidi.methods._dic._get_initial_guess(target_image, reference_subset)[source]#
Estimate an integer-pixel translation from FFT cross-correlation.
- Parameters:
target_image (numpy.ndarray) – full target image to search.
reference_subset (numpy.ndarray) – reference subset to locate in
target_image.
- Returns:
integer translation
(dy, dx)of the subset upper-left corner relative to its expected position (top-left(0, 0)).- Return type:
tuple of int
- pyidi.methods._dic.multi(video: VideoReader, idi_method: DIC, processes, configuration_keys: list)[source]#
Split the points across processes and run the DIC method in parallel.
- Parameters:
video (VideoReader) – VideoReader object.
idi_method (DIC) – DIC instance to clone for each worker.
processes (int) – number of processes to run.
configuration_keys (list) – list of configuration keys forwarded to workers.
- Returns:
tuple
(displacements, warp_params)concatenated across workers.- Return type:
tuple of numpy.ndarray
Postprocessing#
- pyidi.postprocessing._motion_magnification.mode_shape_magnification(displacements: ndarray, magnification_factor: int | float, idi: IDIMethod | None = None, image: ndarray | memmap | None = None, points: ndarray | None = None, background_brightness: float = 0.3, show_undeformed: bool = False) ndarray[source]#
Create an image of a magnified mode-shape of a structure. If a IDI method instance is passed as argument
idi, the argumentimageis set to the first image in sequence and the argumentpointsis set to the points stored in the IDI method instance. These values can be overwritten by specifying theimageandpointsarguments explicitly.- Parameters:
displacements (numpy.ndarray) – displacement (mode-shape) vector
magnification_factor (int or float) – magnification factor
idi (IDIMethod or None, optional) – IDI method instance, defaults to None
image (numpy.ndarray, numpy.memmap or None, optional) – the reference image, on which mode-shape magnification is performed, defaults to None
points (numpy.ndarray or None, optional) – image coordinates, where displacements ‘displacements’ are defined, defaults to None
background_brightness – brightness of the background, expected values in range [0, 1], defaults to 0.3
show_undeformed (bool, optional) – Show the reference image (argument ‘image’) underneath the magnified mode-shape, defaults to False
- Returns:
image of a magnified mode-shape of the structure
- Return type:
numpy.ndarray
- pyidi.postprocessing._motion_magnification.animate(displacements: ndarray, magnification_factor: int | float, idi: IDIMethod | None = None, image: ndarray | memmap | None = None, points: ndarray | None = None, fps: int = 30, n_periods: int = 3, filename: str = 'mode_shape_mag_video', output_format: str = 'gif', background_brightness: float = 0.3, show_undeformed: bool = False) None[source]#
Create a video of a magnified mode-shape of a structure. If a IDI method instance is passed as argument
idi, the argumentimageis set to the first image in sequence and the argumentpointsis set to the points stored in the IDI method instance. These values can be overwritten by specifying theimageandpointsarguments explicitly.- Parameters:
displacements (numpy.ndarray) – displacement vector
magnification_factor (int or float) – magnification factor
idi (IDIMethod or None, optional) – IDI method instance, defaults to None
image (numpy.ndarray, numpy.memmap or None, optional) – the reference image, on which mode-shape magnification is performed, defaults to None
points (numpy.ndarray or None, optional) – image coordinates, where displacements ‘displacements’ are defined, defaults to None
fps (int, optional) – framerate of the created video, defaults to 30
n_periods (int, optional) – number of periods of oscilation to be animated, defaults to 3
filename (str) – the name of the output video file defaults to ‘mode_shape_mag_video’
output_format (str, optional) – output format of the video, selected from ‘gif’, ‘mp4’, ‘avi’, ‘mov’, defaults to ‘gif’
background_brightness – brightness of the background, expected values in range [0, 1], defaults to 0.3
show_undeformed (bool, optional) – Show the reference image (argument ‘image’) underneath the magnified mode-shape, defaults to True
- pyidi.postprocessing._motion_magnification.create_mesh(points, disp, mag_fact)[source]#
Generates a planar mesh of triangles based on the input set of points. Then generates the deformed planar mesh of triangles based on the displacement vectors ‘disp’, scaled by the magnification factor ‘mag_fact’.
pyIDI base class#
- class pyidi.pyidi_legacy.pyIDI(input_file, root=None)[source]#
Bases:
object- __init__(input_file, root=None)[source]#
This class is no longer used in the new version of pyIDI.
Deprecated since version 1.0: Use
VideoReaderand method-specific classes instead.In version 1.0 of pyIDI, some changes were made in the API.
To convert the old code to the new version, you can use the following example:
Old version:
>>> from pyidi import pyIDI >>> video = pyIDI("path/to/file") >>> video.set_method(...) >>> video.set_points(...) >>> video.method.configure(...) >>> video.get_displacements()
New version:
>>> from pyidi import VideoReader, SimplifiedOpticalFlow, LucasKanade >>> video = VideoReader("path/to/file")
>>> idi = SimplifiedOpticalFlow(video) >>> idi.set_points(...) >>> idi.configure(...) >>> idi.get_displacements()
For more information, see the documentation at https://pyidi.readthedocs.io/en/latest/
- set_method(method)[source]#
This method is no longer used in the new version of pyIDI.
In version 1.0 of pyIDI, some changes were made in the API.
To convert the old code to the new version, you can use the following example:
Old version:
>>> from pyidi import pyIDI >>> video = pyIDI("path/to/file") >>> video.set_method(...) >>> video.set_points(...) >>> video.method.configure(...) >>> video.get_displacements()
New version:
>>> from pyidi import VideoReader, SimplifiedOpticalFlow, LucasKanade >>> video = VideoReader("path/to/file")
>>> idi = SimplifiedOpticalFlow(video) >>> idi.set_points(...) >>> idi.configure(...) >>> idi.get_displacements()
For more information, see the documentation at https://pyidi.readthedocs.io/en/latest/
- set_points(points)[source]#
This method is no longer used in the new version of pyIDI.
In version 1.0 of pyIDI, some changes were made in the API.
To convert the old code to the new version, you can use the following example:
Old version:
>>> from pyidi import pyIDI >>> video = pyIDI("path/to/file") >>> video.set_method(...) >>> video.set_points(...) >>> video.method.configure(...) >>> video.get_displacements()
New version:
>>> from pyidi import VideoReader, SimplifiedOpticalFlow, LucasKanade >>> video = VideoReader("path/to/file")
>>> idi = SimplifiedOpticalFlow(video) >>> idi.set_points(...) >>> idi.configure(...) >>> idi.get_displacements()
For more information, see the documentation at https://pyidi.readthedocs.io/en/latest/
- get_displacements(*args, **kwargs)[source]#
This method is no longer used in the new version of pyIDI.
In version 1.0 of pyIDI, some changes were made in the API.
To convert the old code to the new version, you can use the following example:
Old version:
>>> from pyidi import pyIDI >>> video = pyIDI("path/to/file") >>> video.set_method(...) >>> video.set_points(...) >>> video.method.configure(...) >>> video.get_displacements()
New version:
>>> from pyidi import VideoReader, SimplifiedOpticalFlow, LucasKanade >>> video = VideoReader("path/to/file")
>>> idi = SimplifiedOpticalFlow(video) >>> idi.set_points(...) >>> idi.configure(...) >>> idi.get_displacements()
For more information, see the documentation at https://pyidi.readthedocs.io/en/latest/