num_coef = 5 # Number of polynomial coefficients norm = False # Correct non-uniform background if True perspective = False # Correct perspective distortion if True # ----------------------------------------------------------------------------- # ----------------------------------------------------------------------------- # Load an image, get shape print("Load image: {}".format(file_path)) mat0 = io.load_image(file_path) (height, width) = mat0.shape # Optional step: correct non-uniform background for global thresholding method. # Background is generated by applying a strong low-pass filter to the image. # Then, the image is normalized with the background. if norm is True: mat1 = prep.normalization_fft(mat0, sigma=5, pad=30) else: mat1 = np.copy(mat0) # Binarization using Otsu's method if thres = None # Cropped image (30% of the size around the middle) is used for calculating # the threshold. This is to avoid a case which a dot-pattern doesn't # cover the whole field of view of a camera. mat1 = prep.binarization(mat1, ratio=0.3, thres=None) check = prep.check_num_dots(mat1) if check: raise ValueError( "Number of objects detected is not enough !!! Parameters of" " the binarization method need to be adjusted!!!") io.save_image(output_base + "/binarized_image.tif", mat1)
def get_cross_points_ver_lines(mat, slope_hor, dist_hor, ratio=1.0, norm=True, offset=0, bgr="bright", radius=7, sensitive=0.1, denoise=True, subpixel=True): """ Get points on vertical lines of a line-pattern image by intersecting with a list of generated horizontal-lines. Parameters ---------- mat : array_like 2D array. slope_hor : float Slope in Radian of generated horizontal lines. dist_hor : float Distance between two adjacent generated lines. ratio : float To adjust the distance between generated lines to get more/less lines. norm : bool, optional Apply background normalization to the array. offset : int Starting index of generated lines. bgr : {"bright", "dark"} Specify the brightness of the background against the lines. radius : int Search radius. Used to locate extremum points. sensitive : float To detect extremum points against random noise. Smaller is more sensitive. denoise : bool, optional Applying a smoothing filter if True. subpixel : bool, optional Locate points with subpixel accuracy. Returns ------- array_like List of (y,x)-coordinates of points. """ (height, width) = mat.shape if bgr == "bright": mat = np.max(mat) - mat if norm is True: mat = prep.normalization_fft(mat, 5) if denoise is True: mat = ndi.gaussian_filter(mat, 3) angle = np.arctan(slope_hor) min_col, max_col = _calc_index_range(height, width, -np.rad2deg(angle), direction="horizontal") offset = np.clip(offset, 0, min(height, width) // 8) list_points = [] for i in np.arange(min_col + offset, max_col - offset, ratio * dist_hor): xlist, ylist, profile = get_tilted_profile(mat, i, -np.rad2deg(angle), direction="horizontal") scale = np.sqrt((xlist[-1] - xlist[0])**2 + (ylist[-1] - ylist[0])**2) / (width - 1) rlist = get_local_extrema_points(profile, option="max", radius=radius, sensitive=sensitive, denoise=not denoise, norm=not norm, subpixel=subpixel) * scale xlist1 = rlist * np.cos(angle) + xlist[0] ylist1 = rlist * np.sin(angle) + ylist[0] list_points.extend(np.asarray(list(zip(ylist1, xlist1)))) return np.asarray(list_points)
def test_normalization_fft(self): mat_nor = prep.normalization_fft(self.bck, sigma=5, pad=10) std_val = np.std(mat_nor) self.assertTrue(std_val <= self.var)
import numpy as np import matplotlib.pyplot as plt import discorpy.losa.loadersaver as io import discorpy.prep.preprocessing as prep import discorpy.proc.processing as proc import discorpy.post.postprocessing as post # Initial parameters file_path = "C:/data/dot_pattern_06.jpg" output_base = "./for_demo_05/" num_coef = 4 # Number of polynomial coefficients mat0 = io.load_image(file_path) # Load image (height, width) = mat0.shape # Normalize background mat1 = prep.normalization_fft(mat0, sigma=20) # Segment dots threshold = prep.calculate_threshold(mat1, bgr="bright", snr=1.5) mat1 = prep.binarization(mat1, thres=threshold) io.save_image(output_base + "/segmented_dots.jpg", mat1) # Calculate the median dot size and distance between them. (dot_size, dot_dist) = prep.calc_size_distance(mat1) # Calculate the slopes of horizontal lines and vertical lines. hor_slope = prep.calc_hor_slope(mat1) ver_slope = prep.calc_ver_slope(mat1) print("Horizontal slope: {0}. Vertical slope: {1}".format( hor_slope, ver_slope)) # Group dots into lines. list_hor_lines0 = prep.group_dots_hor_lines(mat1,