コード例 #1
0
def adaptive_otsu(im):
    im_h, _ = im.shape
    s = (im_h // 200) | 1
    ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (s, s))
    background = cv2.morphologyEx(im, cv2.MORPH_DILATE, ellipse)
    bg_float = background.astype(np.float64)
    debug_imwrite('bg.png', background)
    C = np.percentile(im, 30)
    normalized = clip_u8(C / (bg_float + 1e-10) * im)
    debug_imwrite('norm.png', normalized)
    return otsu(normalized)
コード例 #2
0
def lu2010(im):
    im_h, im_w = im.shape

    # im_bg_row = polynomial_background_easy(im)  # TODO: implement full
    # im_bg = polynomial_background_easy(im_bg_row.T).T
    # im_bg = im_bg.clip(0.1, 255)
    IM = cv2.erode(niblack(im, window_size=61, k=0.2), rect33)
    inpainted, modified = inpaint.inpaint_ng14(im, -IM)
    im_bg = (inpainted & ~IM) | (modified & IM)
    im_bg = im_bg.astype(np.float32).clip(0.1, 255)
    debug_imwrite('bg.png', im_bg)

    C = np.percentile(im, 30)
    I_bar = clip_u8(C / im_bg * im)
    debug_imwrite('ibar.png', I_bar)
    I_bar_padded = np.pad(I_bar, (1, 1), 'edge')

    V_h = cv2.absdiff(I_bar_padded[2:, 1:-1], I_bar_padded[:-2, 1:-1])
    V_v = cv2.absdiff(I_bar_padded[1:-1, 2:], I_bar_padded[1:-1, :-2])
    V = V_h + V_v
    V[V < V_h] = 255  # clip overflow
    _, stroke_edges = cv2.threshold(V, 0, 255,
                                    cv2.THRESH_BINARY | cv2.THRESH_OTSU)
    # 1 if high contrast, 0 otherwise.
    E_inv = stroke_edges & 1
    E_inv_255 = E_inv * 255
    debug_imwrite('e_inv.png', E_inv_255)
    im_high = im & E_inv_255
    debug_imwrite('im_high.png', im_high)

    # calculate stroke width
    H, _ = np.histogram(nonzero_distances_row(E_inv), np.arange(im_h / 100))
    H[1] = 0  # don't use adjacent pix
    W = H.argmax()
    print('stroke width:', W)
    size = 2 * W
    N_min = W

    if size >= 16:
        E_inv = E_inv.astype(np.uint16)
    window = (size | 1, size | 1)
    N_e = cv2.boxFilter(E_inv, -1, window, normalize=False)
    debug_imwrite('n_e.png', bool_to_u8(N_e >= N_min))

    E_mean = cv2.boxFilter(im_high, cv2.CV_32S, window,
                           normalize=False) / (N_e.astype(np.float64) + 0.1)
    debug_imwrite('i_bar_e_mean.png', bool_to_u8(I_bar <= E_mean))

    out = ~bool_to_u8((N_e >= N_min) & (I_bar <= E_mean))
    debug_imwrite('lu2010.png', out)
    return out
コード例 #3
0
def print_dict(filename, D_T):
    K, W_sq = D_T.shape
    W = int(np.sqrt(W_sq))
    assert W_sq == W**2

    D_T_s = D_T - np.percentile(D_T, 5)
    ratio = 255 / np.percentile(D_T_s, 95)
    patches = lib.clip_u8(ratio * D_T_s.reshape(K, W, W))

    sqrtK = int(np.ceil(np.sqrt(K)))
    padding = ((0, sqrtK**2 - K), (1, 1), (1, 1))
    patches_padded = np.pad(patches, padding, 'constant', constant_values=127)
    dict_square = patches_padded.reshape(sqrtK, sqrtK, W + 2, W + 2) \
        .transpose(0, 2, 1, 3).reshape(sqrtK * (W + 2), sqrtK * (W + 2))

    lib.debug_imwrite(filename, dict_square)
コード例 #4
0
def ng2014_normalize(im):
    IM = niblack(im, window_size=61, k=-0.2)
    debug_imwrite('niblack.png', IM)
    IM = cv2.erode(IM, rect33)
    debug_imwrite('dilated.png', IM)

    inpainted_min, inpainted_avg, modified = inpaint.inpaint_ng14(im, -IM)
    debug_imwrite('inpainted_min.png', inpainted_min)
    debug_imwrite('inpainted_avg.png', inpainted_avg)

    bg = (inpainted_min & ~IM) | (modified & IM)
    debug_imwrite('bg.png', bg)
    bgp = (inpainted_avg & ~IM) | (modified & IM)
    debug_imwrite('bgp.png', bg)

    im_f = im.astype(float) + 1
    bg_f = bg.astype(float) + 1
    F = im_f / bg_f
    N = clip_u8(255 * (F - F.min()))
    debug_imwrite('N.png', N)

    return N, bgp
コード例 #5
0
out_dir = sys.argv[3]

N_IMG = 1000
theta_range = [-np.pi / 45, np.pi / 45]  # +/- 4 deg
KERNELS = [(1, 1), (3, 3), (5, 1), (3, 7)]
NOISE = 15

imgs_base = [fn for fn in os.listdir(sys.argv[1]) if fn.endswith('.png')]
for i in range(N_IMG):
    fn_base = np.random.choice(imgs_base)
    print(i, fn_base)
    im = cv2.imread(os.path.join(hi_dir, fn_base), cv2.IMREAD_UNCHANGED)

    theta = (theta_range[1] - theta_range[0]) * np.random.random() \
        + theta_range[0]

    rotated = algorithm.safe_rotate(im, theta)
    cv2.imwrite(os.path.join(out_dir, 'im{}.png'.format(i)), rotated)

    kernel_std = KERNELS[np.random.choice(len(KERNELS))]
    blurred = cv2.GaussianBlur(rotated, (0, 0), kernel_std[0], kernel_std[1])
    noisy = lib.clip_u8(
        blurred.astype(np.float64) + 10 * np.random.randn(*blurred.shape))
    downsampled = cv2.resize(noisy, (0, 0),
                             None,
                             0.5,
                             0.5,
                             interpolation=cv2.INTER_AREA)
    # _, binarized = cv2.threshold(downsampled, 140, 255, cv2.THRESH_BINARY)
    cv2.imwrite(os.path.join(in_dir, 'im{}.png'.format(i)), downsampled)