ericmjonas / pybm3d

Python wrapper around bm3d
GNU General Public License v3.0
133 stars 29 forks source link

pybm3d not working properly on ubuntu #8

Open paggers opened 7 years ago

paggers commented 7 years ago

Working on a remote server running Ubuntu 16.04.3 LTS (GNU/Linux 4.4.0-79-generic x86_64) I am able to install pybm3d using pip, but once I run it on the example provided the result is all zeros (black image of same dimension).

I can provide more details about the system is required.

timmeinhardt commented 6 years ago

I just tested the example on a Linux machine with the same specifications and got a reasonable output. Is the direct result all zeros or only after saving the image? How is the input formatted (data type, normalized etc.)?

timmeinhardt commented 6 years ago

@paggers Did you manage to get it running?

paggers commented 6 years ago

I was running it locally on my Mac which worked fine, but I was unable to get good results and so I had to halt for a bit.

On a side note, not too long ago I've received a beta version of bm3d implemented in python from Prof. Foi of Tampere University, one of the people from the original group which published BM3D. Just wanted to give you the heads up.

If I get a chance I'll try to run it again on our linux machine, take care!

debinz commented 6 years ago

@paggers I also encounter the same question, , Can you please give me the beta version of bm3d implemented in python from Prof. Foi ? Thanks a lot!

timmeinhardt commented 6 years ago

@debinz Since I can not reproduce the Linux problems could you please give me some more info regarding your problem? In particular whether the direct result are all zeros or only after saving the image? How is the input formatted (data type, normalized etc.)?

debinz commented 6 years ago

@timmeinhardt OK! I have downloaded the source code, and used "$python setup build", "$python setup install" to setup the pybm3d. After that, I wrote a test.py to denoise a png picture: 000

the test.py is as follow:

import cv2
import pybm3d
noise_std_dev = 40

noisy_img = cv2.imread('./picture/000.png')
out = pybm3d.bm3d.bm3d(noisy_img, noise_std_dev)
cv2.imwrite('./picture/000_denoised.png',out)

Then I got the output picture: 000_denoised

I once thought that parts of the codes that 'convert the input image' and 'convert the output image' in bm3d.pyx were wrong because I found the style handling image vector in 'bm3d.cpp' was chnls first, then height, and width last. These parts of codes in bm3d.pyx are as follow:

    # convert the input image
    input_image.resize(input_array.size)
    pos = 0
    for i in range(input_array.shape[0]):
        for j in range(input_array.shape[1]):
            for k in range(input_array.shape[2]):
                input_image[pos] = input_array[i, j, k]
                pos +=1

    # convert the output image   
    pos = 0
    for i in range(input_array.shape[0]):
        for j in range(input_array.shape[1]):
            for k in range(input_array.shape[2]):
                output_array[i, j, k] = output_image[pos]
                pos +=1

So I changed these codes, and resetup it.

    # convert the input image
    input_image.resize(input_array.size)
    pos = 0
    for i in range(input_array.shape[2]):
        for j in range(input_array.shape[0]):
            for k in range(input_array.shape[1]):
                input_image[pos] = input_array[j, k, i]
                pos +=1

    # convert the output image 
    pos = 0
    for i in range(input_array.shape[2]):
        for j in range(input_array.shape[0]):
            for k in range(input_array.shape[1]):
                output_array[j, k, i] = output_image[pos]
                pos +=1

Then I got the output image: 000_denoised1

Could you please give me some advice to deal with this issue? Thank you very much!

leimingyu commented 6 years ago

yes. I had the same issue when I tested on the astronaut image.

screenshot_2018-08-08_21-07-42

Suraj-R commented 5 years ago

same issue for me too: printing out ----------

array([[[0, 0, 0], [0, 0, 0], [0, 0, 0], ..., [0, 0, 0], [0, 0, 0], [0, 0, 0]],

   [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0],
    ...,
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]],

   [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0],
    ...,
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]],

   ...,

   [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0],
    ...,
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]],

   [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0],
    ...,
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]],

   [[0, 0, 0],
    [0, 0, 0],
    [0, 0, 0],
    ...,
    [0, 0, 0],
    [0, 0, 0],
    [0, 0, 0]]], dtype=uint8)
ghost commented 5 years ago

Reporting same problem on remote machine with ubuntu 16.04, but on my local ubuntu 18.04 it works without problems.

491506870 commented 5 years ago

@timmeinhardt hi~i met the same problem with them, would you mind fixing it? i think this package is very helpful~

TalHadad commented 5 years ago

Hi, I'm using Ubuntu 18.04, Python 3.6 and I had the same issue. @Dexerius how did you saved the image? I tried with PIL and cv2, they both produced the same black image.

My code:

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 im = Image.fromarray(noisy_img, 'RGB') im.save('noisy_img.png')

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

cv2.imwrite('out_cv2.png', out)

im = Image.fromarray(out, 'RGB') im.save('out_PIL.png')

Output:

[[[0 0 0] [0 0 0] [0 0 0] ... ... [0 0 0] [0 0 0] [0 0 0]]] PSNR of noisy image: 8.786579608939476 PSNR of reconstructed image: 5.184803539791517

Has anyone solved the problem?

WKrauze commented 5 years ago

The same problem on Linux Manjaro 18.0.4 and Python=3.6. Depending on the input data type, the output is either array of zeros or array with erronous values like in example shown by @leimingyu. Implemented PRs #13 and #14, however the issue remains.

Tokariew commented 5 years ago

I made some testing, and it seems that it's problem when python use mkl for numeric libraries instead of opeblas. When tested with opeblas it's worked fine on mine machine, but when tested with mkl the output was messed. And somewhere in code below mkl struggle when communicating with bm3d, I wasn't able to identify if it was when transferring to or out of bm3d problem happen, but output_image is different between mkl and openblas. input_image was the same in both version.

ret = run_bm3d(sigma, input_image, basic_image, output_image,
                   width, height, chnls,
                   useSD_h, useSD_w,
                   tau_2D_hard_i, tau_2D_wien_i,
                   color_space_i,
                   patch_size,
                   verbose)
    if ret != 0:
        raise Exception("run_bmd3d returned an error, ret_val=%d" % ret)

    cdef np.ndarray output_array = np.zeros([height, width, chnls],
                                            dtype=np.float32)

    pos = 0
    for i in range(input_array.shape[0]):
        for j in range(input_array.shape[1]):
            for k in range(input_array.shape[2]):
                output_array[i, j, k] = output_image[pos]
                pos +=1

    return output_array
johanjeppsson commented 4 years ago

I think there is another issue with the order of the channels for color images. The only way I am able to get results that are similar between the python wrapper and stand alone c++ implementation is to loop over the color channel in the outer loop (which seems to be consistent with the color conversions in the cpp code for bd3m).

i.e. I think the correct order should be

    for k in range(input_array.shape[2]):
        for i in range(input_array.shape[0]):
            for j in range(input_array.shape[1]):
                output_array[i, j, k] = output_image[pos]
                pos +=1

for both the input and output.

I don't know if it is worth submitting a pull request for this as the repo seems to be pretty dead. Perhaps we should fork it instead?