Esempio n. 1
0
def main():
    # Experiment specifications
    imagename = 'image_Lena512rgb.png'

    # Load noise-free image
    y = np.array(Image.open(imagename)) / 255

    # Possible noise types to be generated 'gw', 'g1', 'g2', 'g3', 'g4', 'g1w',
    # 'g2w', 'g3w', 'g4w'.
    noise_type = 'g3'
    noise_var = 0.02  # Noise variance
    seed = 0  # seed for pseudorandom noise realization

    # Generate noise with given PSD
    noise, psd, kernel = get_experiment_noise(noise_type, noise_var, seed,
                                              y.shape)
    # N.B.: For the sake of simulating a more realistic acquisition scenario,
    # the generated noise is *not* circulant. Therefore there is a slight
    # discrepancy between PSD and the actual PSD computed from infinitely many
    # realizations of this noise with different seeds.

    # Generate noisy image corrupted by additive spatially correlated noise
    # with noise power spectrum PSD
    z = np.atleast_3d(y) + np.atleast_3d(noise)

    # Call BM3D With the default settings.
    y_est = bm3d_rgb(z, psd)

    # To include refiltering:
    # y_est = bm3d_rgb(z, psd, 'refilter');

    # For other settings, use BM3DProfile.
    # profile = BM3DProfile(); # equivalent to profile = BM3DProfile('np');
    # profile.gamma = 6;  # redefine value of gamma parameter
    # y_est = bm3d_rgb(z, psd, profile);

    # Note: For white noise, you may instead of the PSD
    # also pass a standard deviation
    # y_est = bm3d_rgb(z, sqrt(noise_var));

    # If the different channels have varying PSDs, you can supply a MxNx3 PSD or a list of 3 STDs:
    # y_est = bm3d_rgb(z, np.concatenate((psd1, psd2, psd3), 2))
    # y_est = bm3d_rgb(z, [sigma1, sigma2, sigma3])

    psnr = get_psnr(y, y_est)
    print("PSNR:", psnr)

    # PSNR ignoring 16-pixel wide borders (as used in the paper), due to refiltering potentially leaving artifacts
    # on the pixels near the boundary of the image when noise is not circulant
    psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
    print("PSNR cropped:", psnr_cropped)

    # Ignore values outside range for display (or plt gives an error for multichannel input)
    y_est = np.minimum(np.maximum(y_est, 0), 1)
    z_rang = np.minimum(np.maximum(z, 0), 1)

    plt.title("y, z, y_est")
    plt.imshow(np.concatenate((y, np.squeeze(z_rang), y_est), axis=1))
    plt.show()
Esempio n. 2
0
def generate_red_img(noisy_img, pred_psd, gt_img):
    noisy_img = np.array(noisy_img)
    noisy_img = noisy_img / 255.0
    gt_img = np.array(gt_img)
    gt_img = gt_img / 255.0
    profile = BM3DProfile()
    profile.bs_ht = random.choice([2, 4, 8])
    profile.transform_2d_wiener_name = random.choice(['dct', 'dst'])
    profile.bs_wiener = random.choice([4, 5, 6, 7, 8, 9, 10, 11, 12])
    cspace = random.choice(['opp', 'YCbCr'])
    cff = random.uniform(1, 15)

    red_img = bm3d_rgb(noisy_img,
                       cff * pred_psd[0],
                       profile,
                       colorspace=cspace)
    red_img = np.minimum(np.maximum(red_img, 0), 1)

    psnr = get_psnr(gt_img, red_img)

    red_img = Image.fromarray(np.uint8(red_img * 255.0))

    return red_img, cff, profile.bs_ht, cspace, profile.transform_2d_wiener_name, profile.bs_wiener, psnr
Esempio n. 3
0
def generate_red_img(noisy_img, pred_psd, gt_img):
    noisy_img = np.array(noisy_img)
    noisy_img = noisy_img / 255.0
    gt_img = np.array(gt_img)
    gt_img = gt_img / 255.0
    profile = BM3DProfile()
    profile.bs_ht = 4
    profile.transform_2d_wiener_name = 'dst'
    profile.bs_wiener = choose_neighborhood
    cspace = 'YCbCr'
    cff = choose_cff

    red_img = bm3d_rgb(noisy_img,
                       cff * pred_psd[0],
                       profile,
                       colorspace=cspace)
    red_img = np.minimum(np.maximum(red_img, 0), 1)

    psnr = get_psnr(gt_img, red_img)

    red_img = Image.fromarray(np.uint8(red_img * 255.0))

    return red_img, cff, profile.bs_ht, cspace, profile.transform_2d_wiener_name, profile.bs_wiener, psnr
Esempio n. 4
0
def main(t, sigma, args=None):
    # Experiment specifications
    #imagename = 'image_Lena512rgb.png'
    imagepath = args.path + '\\'
    imagename = imagepath + 'ref\\' + t + '_r.bmp'
    # Load noise-free image
    y = np.array(Image.open(imagename)) / 255

    # Possible noise types to be generated 'gw', 'g1', 'g2', 'g3', 'g4', 'g1w',
    # 'g2w', 'g3w', 'g4w'.
    noise_type = 'gw'
    noise_var = (sigma / 255)**2  # Noise variance 25 std
    seed = 0  # seed for pseudorandom noise realization

    # Generate noise with given PSD
    noise, psd, kernel = get_experiment_noise(noise_type, noise_var, seed,
                                              y.shape)
    # N.B.: For the sake of simulating a more realistic acquisition scenario,
    # the generated noise is *not* circulant. Therefore there is a slight
    # discrepancy between PSD and the actual PSD computed from infinitely many
    # realizations of this noise with different seeds.

    # Generate noisy image corrupted by additive spatially correlated noise
    # with noise power spectrum PSD
    z = np.atleast_3d(y) + np.atleast_3d(noise)

    z_rang = np.minimum(np.maximum(z, 0), 1)
    noisyimagename = imagepath + 'noisy\\' + t + '_g.bmp'
    plt.imsave(noisyimagename, z_rang)
    z = np.array(Image.open(noisyimagename)) / 255
    # Call BM3D With the default settings.
    y_est = bm3d_rgb(z, psd)

    # To include refiltering:
    # y_est = bm3d_rgb(z, psd, 'refilter');

    # For other settings, use BM3DProfile.
    # profile = BM3DProfile(); # equivalent to profile = BM3DProfile('np');
    # profile.gamma = 6;  # redefine value of gamma parameter
    # y_est = bm3d_rgb(z, psd, profile);

    # Note: For white noise, you may instead of the PSD
    # also pass a standard deviation
    # y_est = bm3d_rgb(z, sqrt(noise_var));

    # If the different channels have varying PSDs, you can supply a MxNx3 PSD or a list of 3 STDs:
    # y_est = bm3d_rgb(z, np.concatenate((psd1, psd2, psd3), 2))
    # y_est = bm3d_rgb(z, [sigma1, sigma2, sigma3])

    psnr = get_psnr(y, y_est)
    print("PSNR:", psnr)

    # PSNR ignoring 16-pixel wide borders (as used in the paper), due to refiltering potentially leaving artifacts
    # on the pixels near the boundary of the image when noise is not circulant
    psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
    print("PSNR cropped:", psnr_cropped)

    # Ignore values outside range for display (or plt gives an error for multichannel input)
    y_est = np.minimum(np.maximum(y_est, 0), 1)
    z_rang = np.minimum(np.maximum(z, 0), 1)
    opath = 'bm3d_{0}.bmp'.format(t)
    plt.imsave(opath.format(t), y_est)
    y_est = np.array(Image.open(opath.format(t))) / 255

    psnr = get_psnr(y, y_est)
    print("PSNR 2:", psnr)
    mse = ((y_est - y)**2).mean() * 255
    print("MSE:", mse)
    #plt.imsave(imagepath+ 'noisy\\' + t + '_g.bmp', z_rang)

    # TEST CV2 PSNR
    try:
        from skimage.metrics import structural_similarity as compare_ssim
    except Exception:
        from skimage.measure import compare_ssim
    import cv2
    opath = 'bm3d_{0}.bmp'.format(t)
    argref = imagename  # path of noisy image
    d = cv2.imread(opath)
    tref = cv2.imread(argref)
    (score, diff) = compare_ssim(tref, d, full=True, multichannel=True)
    psnr2 = cv2.PSNR(tref, d)
    print('#######################')
    print('CV2 PSNR, SSIM: {:.2f}, {:.2f}'.format(psnr2, score))
    print('#######################')
    print('')
    #plt.title("y, z, y_est")
    #plt.imshow(np.concatenate((y, np.squeeze(z_rang), y_est), axis=1))
    #plt.show()
    return psnr, mse
Esempio n. 5
0
seed = 0  # seed for pseudorandom noise realization

noise, psd, kernel = get_experiment_noise(noise_type, noise_var, seed, y.shape)
noise_cube, psd_cube, kernel_cube = get_experiment_noise(
    noise_type, noise_cube_var, seed, y_cube.shape)

# Generate noisy image corrupted by additive spatially correlated noise
# with noise power spectrum PSD
z = (np.atleast_3d(y) + np.atleast_3d(noise))

# Call BM3D With the default settings.
y_est = bm3d(z, psd)

# Note: For white noise, you may instead of the PSD
# also pass a standard deviation
# y_est = bm3d(z, sqrt(noise_var));

psnr = get_psnr(y, y_est)
print("PSNR:", psnr)

# PSNR ignoring 16-pixel wide borders (as used in the paper), due to refiltering potentially leaving artifacts
# on the pixels near the boundary of the image when noise is not circulant
psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
print("PSNR cropped:", psnr_cropped)

# Ignore values outside range for display (or plt gives an error for multichannel input)
y_est = np.minimum(np.maximum(y_est, 0), 1)
z_rang = np.squeeze(np.minimum(np.maximum(z, 0), 1))
plt.title("y, z, y_est")
plt.imshow(np.concatenate((y, z_rang, y_est), axis=1), cmap='gray')
plt.show()
Esempio n. 6
0
def main():
    # Experiment specifications

    # The multichannel example data is acquired from: http://www.bic.mni.mcgill.ca/brainweb/
    # (C.A. Cocosco, V. Kollokian, R.K.-S. Kwan, A.C. Evans,
    #  "BrainWeb: Online Interface to a 3D MRI Simulated Brain Database"
    # NeuroImage, vol.5, no.4, part 2/4, S425, 1997
    # -- Proceedings of 3rd International Conference on Functional Mapping of the Human Brain, Copenhagen, May 1997.
    data_name = 'brainslice.mat'
    table_name = 'slice_sample'

    # Load noise-free image
    # Data should be in same shape as with Image.open, but channel count can be any (M x N x channels)
    # Noise-free data should be between 0 and 1.
    y = loadmat(data_name)[table_name]
    # Possible noise types to be generated 'gw', 'g1', 'g2', 'g3', 'g4', 'g1w',
    # 'g2w', 'g3w', 'g4w'.
    noise_type = 'g2'
    noise_var = 0.02  # Noise variance
    seed = 0  # seed for pseudorandom noise realization

    # Generate noise with given PSD
    noise, psd, kernel = get_experiment_noise(noise_type, noise_var, seed,
                                              y.shape)
    # N.B.: For the sake of simulating a more realistic acquisition scenario,
    # the generated noise is *not* circulant. Therefore there is a slight
    # discrepancy between PSD and the actual PSD computed from infinitely many
    # realizations of this noise with different seeds.

    # Generate noisy image corrupted by additive spatially correlated noise
    # with noise power spectrum PSD
    z = np.atleast_3d(y) + np.atleast_3d(noise)

    # Call BM3D With the default settings.
    # The call is identical to that of the grayscale BM3D.
    y_est = bm3d(z, psd)

    # To include refiltering:
    # y_est = bm3d(z, psd, 'refilter');

    # For other settings, use BM3DProfile.
    # profile = BM3DProfile(); # equivalent to profile = BM3DProfile('np');
    # profile.gamma = 6;  # redefine value of gamma parameter
    # y_est = bm3d(z, psd, profile);

    # Note: For white noise, you may instead of the PSD
    # also pass a standard deviation
    # y_est = bm3d(z, sqrt(noise_var));

    # Instead of passing a singular PSD, you may also pass equal number of PSDs to the channels:
    # y_est = bm3d(z, np.concatenate((psd1, psd2, psd3, psd4, psd5), 2))
    # y_est = bm3d(z, [sigma1, sigma2, sigma3, sigma4, sigma5])

    psnr = get_psnr(y, y_est)
    print("PSNR:", psnr)

    # PSNR ignoring 16-pixel wide borders (as used in the paper), due to refiltering potentially leaving artifacts
    # on the pixels near the boundary of the image when noise is not circulant
    psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
    print("PSNR cropped:", psnr_cropped)

    # Ignore values outside range for display (or plt gives an error for multichannel input)
    y_est = np.minimum(np.maximum(y_est, 0), 1)
    z_rang = np.minimum(np.maximum(z, 0), 1)
    plt.title("y, z, y_est")
    disp_mat = np.concatenate([
        np.concatenate(
            (y[:, :, i], np.squeeze(z_rang[:, :, i]), y_est[:, :, i]), axis=1)
        for i in range(y_est.shape[2])
    ],
                              axis=0)

    plt.imshow(disp_mat)
    plt.show()
Esempio n. 7
0
def main():
    # Experiment specifications
    imagename = 'cameraman256.png'

    # Load noise-free image
    y = np.array(Image.open(imagename)) / 255

    # Generate blurry + noisy image
    experiment_number = 3

    if experiment_number == 1:
        sigma = np.sqrt(2) / 255
        v = np.zeros((15, 15))
        for x1 in range(-7, 8, 1):
            for x2 in range(-7, 8, 1):
                v[x1 + 7, x2 + 7] = 1 / (x1 ** 2 + x2 ** 2 + 1)

        v = v / np.sum(v)

    elif experiment_number == 2:
        sigma = np.sqrt(8) / 255
        s1 = 0
        v = np.zeros((15, 15))
        for a1 in range(-7, 8, 1):
            s1 = s1 + 1
            s2 = 0
            for a2 in range(-7, 8, 1):
                s2 = s2 + 1
                v[s1-1, s2-1] = 1 / (a1 ** 2 + a2 ** 2 + 1)

    elif experiment_number == 3:
        bsnr = 40
        sigma = -1  # if "sigma=-1", then the value of sigma deps on the BSNR
        v = np.ones((9, 9))
        v = v / np.sum(v)

    elif experiment_number == 4:
        sigma = 7 / 255
        v = np.atleast_2d(np.array([1, 4, 6, 4, 1])).T @ np.atleast_2d(np.array([1, 4, 6, 4, 1]))
        v = v / np.sum(v)

    elif experiment_number == 5:
        sigma = 2 / 255
        v = gaussian_kernel((25, 25), 1.6)

    else:  # 6 +
        sigma = 8 / 255
        v = gaussian_kernel((25, 25), 0.4)

    y_blur = correlate(np.atleast_3d(y), np.atleast_3d(v), mode='wrap')  # performs blurring (by circular convolution)

    if sigma == -1:  # check whether to use BSNR in order to define value of sigma
        sigma = np.sqrt(np.linalg.norm(np.ravel(y_blur - np.mean(y_blur)), 2) ** 2 / (y.shape[0] * y.shape[1] * 10 ** (bsnr / 10)))

    z = y_blur + sigma * np.random.normal(size=y_blur.shape)

    # Call BM3D deblurring With the default settings.
    y_est = bm3d_deblurring(z, sigma, v)

    # To include refiltering:
    # y_est = bm3d_deblurring(z, sigma, v, 'refilter');

    # For other settings, use BM3DProfile.
    # profile = BM3DProfile(); # equivalent to profile = BM3DProfile('np');
    # profile.gamma = 6;  # redefine value of gamma parameter
    # y_est = bm3d_deblurring(z, sigma, v, profile);

    # Note: You may also pass a PSD
    # y_est = bm3d_deblurring(z, psd, v);

    psnr = get_psnr(y, y_est)
    print("PSNR:", psnr)

    # PSNR ignoring 16-pixel wide borders (as used in the paper), due to refiltering potentially leaving artifacts
    # on the pixels near the boundary of the image when noise is not circulant
    psnr_cropped = get_cropped_psnr(y, y_est, [16, 16])
    print("PSNR cropped:", psnr_cropped)

    # Ignore values outside range for display (or plt gives an error for multichannel input)
    y_est = np.minimum(np.maximum(y_est, 0), 1)
    z_rang = np.minimum(np.maximum(z, 0), 1)

    plt.title("y, z, y_est")
    plt.imshow(np.concatenate((y, np.squeeze(z_rang), y_est), axis=1), cmap='gray')
    plt.show()