alex
alex

Reputation: 19

how to reduce the noise of an image on python?

This is my code so far. I am totally lost and not sure what to do. its python language. I cant use cv2 or matpolibic. I am only allowed to use cimpl and numpy

from Cimpl import*
import numpy as np 
def reduce_noise (image: Image) -> Image:
    new_image = copy(image)
    for pixel in image:
        X, Y, (r, g, b) = pixel

        r_list = [r, r1, r2, r3, r4]
        r_list.sort()
        new_r = r_list[2]
        
        g_list = [g, g1, g2, g3, g4]
        g_list.sort()
        new_g = g_list[2]
        
        b_list = [b, b1, b2, b3, b4]
        b_list.sort()
        new_b = b_list[2]
        reduce_noise = create_color(new_r, new_g, new_b)
        set_color(new_image, X, Y, reduce_noise)
        
    return new_image

image = load_image (choose_file())
show (image) 
new_image = reduce_noise(image)
show (new_image)

Upvotes: 1

Views: 4686

Answers (1)

Arty
Arty

Reputation: 16737

Part 1 (See also Part 2 below)

I decided to improve your attempt of denoising algorithm. As I can see by your code you tried (with coding mistakes) to implement median filter, taking median of several pixels around each pixel.

I implemented next algorithm in pure Numpy. But to read and write image from/to file I used PIL library, just replace this PIL usage with anything you like that reads and writes to file a numpy array. I used PIL only on first and last lines of code. PIL library just for testing can be installed by pip install pillow, it is one of the most popular imaging library in python.

In next algorithm strength of median filter is controlled by n parameter which equals to 7 in my case. Value n means that we take median among pixels of square of size n by n.

My code works both with gray and color images, see gray examples after the code and colored examples after gray examples.

Try it online!

def reduce_noise(a, n = 7):
    import numpy as np
    am = np.zeros(
        (n, n) + (a.shape[0] - n + 1, a.shape[1] - n + 1) + a.shape[2:],
        dtype = a.dtype
    )
    for i in range(n):
        for j in range(n):
            am[i, j] = a[i:i + am.shape[2], j:j + am.shape[3]]
    am = np.moveaxis(am, (0, 1), (-2, -1)).reshape(*am.shape[2:], -1)
    am = np.median(am, axis = -1)
    if am.dtype != a.dtype:
        am = (am.astype(np.float64) + 10 ** -7).astype(a.dtype)
    return am
    
import PIL.Image, numpy as np
a = np.array(PIL.Image.open('noised.jpg'))
a = reduce_noise(a)
PIL.Image.fromarray(a).save('noised_out.png')

Gray example (colored example afterwards):

Input:

enter image description here

Output:

enter image description here

Colored example:

Input:

enter image description here

Output:

enter image description here


Part 2

My appologies, by mistake I missread your question, instead of "I cant use cv2" I read "I can use cv2", and hence implemented next OpenCV algorithm as my first attempt to solve your task (Part-1 algorithm was implemented later).

According to this OpenCV denoising tutorial you can denoise your image like in code below. It uses cv2.fastNlMeansDenoisingColored() function, there is also grayscale variant of this function if you have gray image.

Degree of denoising is controlled by 20, 20, 14, 42 params in my code, it is very strong denoising, you can use default values (without providing these numbers), it will give smaller denoising degree. For your image start with default values of 3, 3, 7, 21, maybe they're enough, no need for very strong denoising, and experiment with these values.

Try it online!

import numpy as np, cv2
from matplotlib import pyplot as plt
img = cv2.imread('birds.png')
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
dst = cv2.fastNlMeansDenoisingColored(img, None, 20, 20, 14, 42)
cv2.imwrite('birds_out.png', cv2.cvtColor(dst, cv2.COLOR_RGB2BGR))
plt.subplot(121); plt.imshow(img)
plt.subplot(122); plt.imshow(dst)
plt.show()

Input:

enter image description here

Output:

enter image description here

Upvotes: 1

Related Questions