ericmjonas / pybm3d

Python wrapper around bm3d
GNU General Public License v3.0
132 stars 28 forks source link

demo not denoising successfully #11

Open batson opened 5 years ago

batson commented 5 years ago

Hello,

Running on a Mac, clean install today (required upgrading libpng, libjpeg, libtiff by hand for some reason).

When I run the demo from the README, I get poor performance:

import numpy as np
import skimage.data
from skimage.measure import compare_psnr

import pybm3d

noise_std_dev = 40
img = skimage.data.astronaut()
noise = np.random.normal(scale=noise_std_dev,
                         size=img.shape).astype(img.dtype)

noisy_img = img + noise

out = pybm3d.bm3d.bm3d(noisy_img, noise_std_dev)

noise_psnr = compare_psnr(img, noisy_img)
out_psnr = compare_psnr(img, out)

print("PSNR of noisy image: ", noise_psnr)
print("PSNR of reconstructed image: ", out_psnr)
PSNR of noisy image:  8.790840053416506
PSNR of reconstructed image:  9.694752220332331

If I convert to greyscale first with skimage.color.rgb2grey, and set sigma = 0.2, the perf is even worse:

PSNR of noisy image:  13.975934859277583
PSNR of reconstructed image:  27.27140695331532

I'm not sure how to debug this, any advice appreciated!

dxli94 commented 5 years ago

Got the same problem on Ubuntu 16.04. Python 3.5.

python3 bm3d.py gives

PSNR of noisy image:  8.778750540392096
PSNR of reconstructed image:  9.685388621312667
zaccharieramzi commented 5 years ago

Still got the same issue (Python 3.6, Ubuntu 16.04, I can give other versions if of interest), with the same results as @dxli94 .

For the record, this is not an error with scikit-image's PSNR computation, here is the "denoised" image: pybm3d_example

fvdnabee commented 5 years ago

The example in the README.md generates a faulty noisy_img due to numeric overflows when generating the white noise as well as when adding the noise to the input image. The first overflow is apparent when expecting the noise array (the negative elements are in fact 255+value). The 2nd overflow appears as artifacts in the black areas of noisy_image (table, visor). Both overflows can be avoided by applying PR #14.

Note you must also apply PR #13 for avoiding overflow in the output.

As an alternative for both PRs, you can use signed types for the input to bm3d as below (note the conversion of astronaut to int16):

import numpy as np
import skimage.data
from skimage.measure import compare_psnr

import pybm3d

noise_std_dev = 40
img = skimage.data.astronaut().astype(np.int16)
noise = np.random.normal(scale=noise_std_dev,
                         size=img.shape).astype(img.dtype)

noisy_img = img + noise

out = pybm3d.bm3d.bm3d(noisy_img, noise_std_dev)

noise_psnr = compare_psnr(img, noisy_img)
out_psnr = compare_psnr(img, out)

print("PSNR of noisy image: ", noise_psnr)
print("PSNR of reconstructed image: ", out_psnr)
zaccharieramzi commented 5 years ago

Note for anyone wanting to use the PRs created by @fvdnabee , you need to clone their repo with the --recurse-submodules since bm3d_src is a submodule.