Question

I'm trying to add white noise to an image after applying a lowpass filter. I know how to do it in matlab but don't know what to call for it to work in python.

import matplotlib.pyplot as plt
import numpy as np
import scipy.misc
from scipy import ndimage
import Image 

J = imnoise(im,'salt & pepper',0.02);
figure.imshow(J)

What else do I need to import? Or is there another way to add noise?

Was it helpful?

Solution 2

in discussing denoising, this tutorial adds white noise to an image with noisy = l + 0.4 * l.std() * np.random.random(l.shape) where l is the image.

http://scipy-lectures.github.io/advanced/image_processing/#denoising

In general, you should be able to add noise simply by adding a matrix filled with the noise that you want to use to the original picture.

OTHER TIPS

scikit-image provides a function random_noise which is similar to imnoise in MATLAB.

skimage.util.random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)

It supports the following modes:

‘gaussian’ Gaussian-distributed additive noise.

‘localvar’ Gaussian-distributed additive noise, with specified local variance at each point of image

‘poisson’ Poisson-distributed noise generated from the data.

‘salt’ Replaces random pixels with 1.

‘pepper’ Replaces random pixels with 0.

‘s&p’ Replaces random pixels with 0 or 1.

‘speckle’ Multiplicative noise using out = image + n*image, where n is uniform noise with specified mean & variance.

Note that one difference from imnoise in MATLAB is that the output of this function would always be a floating-point image.

If the input image is a uint8 grayscale image for instance, it would be converted to float at first, but the output image wouldn't be converted to the same class as the input image.

Therefore if you care about the class of image, you should convert the output by yourself, for example using skimage.img_as_ubyte.

  1. code sample.

    import numpy as np
    import cv2
    from matplotlib import pyplot as plt
    from skimage.util import random_noise
    
    I = cv2.imread('image.jpg', 1); # 1/ -1: color mode; 0: gray mode
    gauss = random_noise(I, mode='gaussian', seed=None, clip=True)
    sp = random_noise(I, mode='s&p', seed=None, clip=True)
    
    plt.subplot(231), plt.imshow(I), plt.title('Origin')
    plt.subplot(232), plt.imshow(gauss), plt.title('Gaussian')
    plt.subplot(233), plt.imshow(sp), plt.title('Salt & Pepper')
    plt.show();
    
  2. more info: http://scikit-image.org/docs/0.13.x/api/skimage.util.html#skimage.util.random_noise

Although there is no built-in functions like in matlab "imnoise(image,noiseType,Amount_of_Noise)" but we can easily add required amount of random valued impulse noise or salt and pepper into an image manually.

1. to add random valued impulse noise.

import random as r
def addRvinGray(image,n): # add random valued impulse noise in grayscale 
    '''parameters: 
            image: type=numpy array. input image in which you want add noise.
            n:  noise level (in percentage)'''
    k=0                  # counter variable 
    ih=image.shape[0]    
    iw=image.shape[1]
    noisypixels=(ih*iw*n)/100      # here we calculate the number of pixels to be altered.

    for i in range(ih*iw):
        if k<noisypixels:
                image[r.randrange(0,ih)][r.randrange(0,iw)]=r.randrange(0,256) #access random pixel in the image gives random intensity (0-255)              
            k+=1
        else:
            break
    return image

> to add salt and pepper noise

import random as r
def addSaltGray(image,n): #add salt-&-pepper noise in grayscale image

    k=0
    salt=True
    ih=image.shape[0]
    iw=image.shape[1]
    noisypixels=(ih*iw*n)/100

    for i in range(ih*iw):
        if k<noisypixels:  #keep track of noise level
                if salt==True:
                        image[r.randrange(0,ih)][r.randrange(0,iw)]=255
                        salt=False
                else:
                        image[r.randrange(0,ih)][r.randrange(0,iw)]=0
                        salt=True
                k+=1
        else:
            break
    return image

Note: for color images: first split image in to three or four channels depending on the input image using opencv function: (B, G, R) = cv2.split(image) (B, G, R, A) = cv2.split(image) after spliting perform the same operations on all channels. at the end merge all the channels: merged = cv2.merge([B, G, R]) return merged I hope this will help someone.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top