Example #1
0
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)
Example #2
0
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)
Example #3
0
 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)
Example #4
0
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,