Source code for DICpy.DIC_2D._images

from DICpy.utils import _close
import numpy as np
import matplotlib.patches as patches
import matplotlib.pyplot as plt
import os
import skimage.io as sio
from matplotlib.widgets import Button
import cv2


[docs]class Images: """ This class contains the methods for reading and processing images used in digital image correlation (DIC). **Input:** **Attributes:** * **path_speckle** (`str`) Path to the speckle images. * **path_calibration** (`str`) Path to the calibration image. * **ref_image** (`ndarray`) Reference image. * **calibration_image** (`ndarray`) Calibration image. * **images** (`ndarray`) Gray images. * **images_normalized** (`ndarray`) Gray images normalized by 255. * **lx** (`int`) Number of columns of each image. * **ly** (`int`) Number of rows of each image. * **num_img** (`int`) Number of images. * **pixel_dim** (`float`) Size of each pixel in length dimension. **Methods:** """ def __init__(self): self.path_speckle = None self.path_calibration = None self.ref_image = None self.calibration_image = None self.images = None self.images_normalized = None self.lx = None self.ly = None self.num_img = None self.pixel_dim = 1
[docs] def read_speckle_images(self, path=None, extension=None, file_names=None, ref_id=0, verbose=False): """ Read the speckle images. **Input:** * **path** (`str`) Path for the images used in the DIC analysis. * **extension** (`str`) The extension of the files located in `path`. * **file_names** (`str`) Define the files to be read in the sequence of your preference. * **ref_id** (`int`) Define a file to be used as reference, the default is zero, which means that the first image in the stack will be used as reference. * **verbose** (`bool`) Boolean varible to print some information on screen. **Output/Returns:** """ if not isinstance(ref_id,int): raise TypeError('DICpy: ref_id must be an integer.') if ref_id < 0: raise ValueError('DICpy: ref_id is an integer larger than or equal to 0.') if path is None: path = os.getcwd() if extension is None: raise TypeError('DICpy: extension cannot be NoneType when using path.') self.path_speckle = path if file_names is None: file_names = [f for f in os.listdir(path) if f.endswith('.' + extension)] file_names = np.sort(file_names) if verbose: print('DICpy: reading speckle images.') images = [] images_normalized = [] for f in file_names: if verbose: print(f) im = cv2.imread(os.path.join(path, f), 0) images.append(im) images_normalized.append(im/255) self.images = images self.images_normalized = images_normalized (lx, ly) = np.shape(im) self.lx = lx self.ly = ly self.num_img = len(images) self.ref_image = images[ref_id]
@staticmethod def _read_calibration_images(path=None, file_name=None, verbose=True): """ Private method for reading the calibration image. **Input:** * **path** (`str`) Path for the calibration image used in the DIC analysis. * **file_names** (`str`) Name of the calibration image. * **verbose** (`bool`) Boolean varible to print some information on screen. **Output/Returns:** * **calibration_image** (`ndarray`) Calibration image. """ if path is None: path = os.getcwd() if file_name is None: raise TypeError('DICpy: file_name cannot be NoneType.') if verbose: print('DICpy: reading the calibration image.') im = sio.imread(os.path.join(path, file_name), as_gray=True) calibration_image = 255 * im return calibration_image
[docs] def calibration(self, ref_length=None, pixel_dim=None, path=None, file_name=None, point_a=None, point_b=None, verbose=True): """ Method for the analysis calibration. **Input:** * **ref_length** (`str`) Length used as reference. * **pixel_dim** (`float`) Size of each pixel in length dimension. * **path** (`str`) Path for the calibration image used in the DIC analysis. * **file_name** (`str`) Name of the calibration image. * **point_a** (`float`) First corner of the region of interest (ROI). * **point_b** (`float`) Corner opposed to point_b of the region of interest (ROI). * **verbose** (`bool`) Boolean variable to print some information on screen. **Output/Returns:** """ if pixel_dim is None: if ref_length is None: raise TypeError('DICpy: ref_length cannot be NoneType.') self.path_calibration = path cal_img = self._read_calibration_images(path=path, file_name=file_name, verbose=verbose) self.calibration_image = cal_img (lx, ly) = np.shape(cal_img) maxl = max(lx, ly) global rcirc, ax, fig, coords, cid rcirc = maxl / 160 if point_a is None or point_b is None: coords = [] fig = plt.figure() ax = fig.add_subplot(111) cid = fig.canvas.mpl_connect('button_press_event', self._mouse_click) plt.imshow(cal_img, cmap="gray") plt.show() point_a = coords[0] point_b = coords[1] else: fig = plt.figure() ax = fig.add_subplot(111) circle = plt.Circle(point_a, rcirc, color='red') ax.add_patch(circle) fig.canvas.draw() # this line was missing earlier circle = plt.Circle(point_b, rcirc, color='red') ax.add_patch(circle) fig.canvas.draw() # this line was missing earlier lx = (point_b[0] - point_a[0]) ly = (point_b[1] - point_a[1]) fig.canvas.draw() # this line was missing earlier plt.imshow(cal_img, cmap="gray") plt.show(block=False) plt.close() point_a = (round(point_a[0]),round(point_a[1])) point_b = (round(point_b[0]),round(point_b[1])) fig = plt.figure() ax = fig.add_subplot(111) lx = (point_b[0] - point_a[0]) ly = (point_b[1] - point_a[1]) circle = plt.Circle(point_a, rcirc, color='red') ax.add_patch(circle) fig.canvas.draw() # this line was missing earlier circle = plt.Circle(point_b, rcirc, color='red') ax.add_patch(circle) fig.canvas.draw() # this line was missing earlier ax.plot([point_a[0], point_b[0]], [point_a[1], point_b[1]], linewidth=2) fig.canvas.draw() plt.imshow(cal_img, cmap="gray") axclose = plt.axes([0.81, 0.05, 0.1, 0.075]) bclose = Button(axclose, 'Next') bclose.on_clicked(_close) plt.show() self.pixel_dim = ref_length/np.sqrt(lx**2 + ly**2) if verbose: print("Points: ",point_a,point_b) print("mm/pixel: ",self.pixel_dim) else: if ref_length is not None: raise Warning('DICpy: ref_length not used when pixel_dim is provided.') self.pixel_dim = pixel_dim if verbose: print("mm/pixel: ",self.pixel_dim)
@staticmethod def _mouse_click(event): """ Private method: mouse click to select the ROI. **Input:** * **event** (`event`) Click event. **Output/Returns:** """ global x, y x, y = event.xdata, event.ydata if event.button: circle = plt.Circle((event.xdata, event.ydata), rcirc, color='red') ax.add_patch(circle) fig.canvas.draw() # this line was missing earlier global coords coords.append((x, y)) if len(coords) == 2: fig.canvas.mpl_disconnect(cid) xa = coords[0][0] ya = coords[0][1] xb = coords[1][0] yb = coords[1][1] lx = (xb - xa) ly = (yb - ya) rect = patches.Rectangle((xa, ya), lx, ly, linewidth=1, edgecolor='None', facecolor='b', alpha=0.4) ax.add_patch(rect) fig.canvas.draw() # this line was missing earlier plt.close() return coords