web-dev-qa-db-fra.com

Bruit d'impulsion, gaussien, sel et poivre avec OpenCV

J'étudie le traitement d'image sur le célèbre Gonzales "Traitement d'image numérique" et, en parlant de restauration d'images, de nombreux exemples sont réalisés avec du bruit généré par ordinateur (gaussien, sel et poivre, etc.). Dans MATLAB, il existe des fonctions intégrées pour le faire. Qu'en est-il d'OpenCV?

22
nkint

Autant que je sache, il n’existe pas de fonctions intégrées pratiques comme dans Matlab. Mais avec seulement quelques lignes de code, vous pouvez créer ces images vous-même.

Par exemple, bruit gaussien additif:

Mat gaussian_noise = img.clone();
randn(gaussian_noise,128,30);

Bruit sel et poivre:

Mat saltpepper_noise = Mat::zeros(img.rows, img.cols,CV_8U);
randu(saltpepper_noise,0,255);

Mat black = saltpepper_noise < 30;
Mat white = saltpepper_noise > 225;

Mat saltpepper_img = img.clone();
saltpepper_img.setTo(255,white);
saltpepper_img.setTo(0,black);
28
sietschie

Fonction simple pour ajouter du bruit de gaussien, de poivre de sel et de poisson à une image

Parameters
----------
image : ndarray
    Input image data. Will be converted to float.
mode : str
    One of the following strings, selecting the type of noise to add:

    'gauss'     Gaussian-distributed additive noise.
    'poisson'   Poisson-distributed noise generated from the data.
    '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.

import numpy as np
import os
import cv2

def noisy(noise_typ,image):

if noise_typ == "gauss":
        row,col,ch= image.shape
        mean = 0
        #var = 0.1
       #sigma = var**0.5
        gauss = np.random.normal(mean,1,(row,col,ch))
        gauss = gauss.reshape(row,col,ch)
        noisy = image + gauss
        return noisy
    Elif noise_typ == "s&p":
        row,col,ch = image.shape
        s_vs_p = 0.5
        amount = 0.004
        out = image
        # Salt mode
        num_salt = np.ceil(amount * image.size * s_vs_p)
        coords = [np.random.randint(0, i - 1, int(num_salt))
                  for i in image.shape]
        out[coords] = 1

        # Pepper mode
        num_pepper = np.ceil(amount* image.size * (1. - s_vs_p))
        coords = [np.random.randint(0, i - 1, int(num_pepper))
                  for i in image.shape]
        out[coords] = 0
        return out
    Elif noise_typ == "poisson":
        vals = len(np.unique(image))
        vals = 2 ** np.ceil(np.log2(vals))
        noisy = np.random.poisson(image * vals) / float(vals)
        return noisy
    Elif noise_typ =="speckle":
        row,col,ch = image.shape
        gauss = np.random.randn(row,col,ch)
        gauss = gauss.reshape(row,col,ch)        
        noisy = image + image * gauss
        return noisy
11
Shubham Pachori

Le bruit "Salt & Pepper" peut être ajouté d'une manière assez simple en utilisant les opérations de matrice NumPy.

def add_salt_and_pepper(gb, prob):
    '''Adds "Salt & Pepper" noise to an image.
    gb: should be one-channel image with pixels in [0, 1] range
    prob: probability (threshold) that controls level of noise'''

    rnd = np.random.Rand(gb.shape[0], gb.shape[1])
    noisy = gb.copy()
    noisy[rnd < prob] = 0
    noisy[rnd > 1 - prob] = 1
    return noisy
5
Artem S

Il existe une fonction random_noise() du paquet scikit-image. Il comporte plusieurs modèles de bruit intégrés, tels que gaussian, s&p (pour le bruit de sel et de poivre), possion et speckle.

Ci-dessous, je montre un exemple d'utilisation de cette méthode.

from PIL import Image
import numpy as np
from skimage.util import random_noise

im = Image.open("test.jpg")
# convert PIL Image to ndarray
im_arr = np.asarray(im)

# random_noise() method will convert image in [0, 255] to [0, 1.0],
# inherently it use np.random.normal() to create normal distribution
# and adds the generated noised back to image
noise_img = random_noise(im_arr, mode='gaussian', var=0.05**2)
noise_img = (255*noise_img).astype(np.uint8)

img = Image.fromarray(noise_img)
img.show()

 enter image description here

Il existe également un package appelé imgaug qui est dédié à l’augmentation des images de différentes manières. Il fournit des augmentations de bruit gaussien, poissan et sel & poivre. Voici comment vous pouvez l'utiliser pour ajouter du bruit à l'image:

from PIL import Image
import numpy as np
from imgaug import augmenters as iaa


def main():
    im = Image.open("bg_img.jpg")
    im_arr = np.asarray(im)

    # gaussian noise
    # aug = iaa.AdditiveGaussianNoise(loc=0, scale=0.1*255)

    # poisson noise
    # aug = iaa.AdditivePoissonNoise(lam=10.0, per_channel=True)

    # salt and pepper noise
    aug = iaa.SaltAndPepper(p=0.05)

    im_arr = aug.augment_image(im_arr)

    im = Image.fromarray(im_arr).convert('RGB')
    im.show()


if __== "__main__":
    main()
2
jdhao
# Adding noise to the image    

import cv2
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

img = cv2.imread('./fruit.png',0)
im = np.zeros(img.shape, np.uint8) # do not use original image it overwrites the image
mean = 0
sigma = 10
cv2.randn(im,mean,sigma) # create the random distribution
Fruit_Noise = cv2.add(img, im) # add the noise to the original image
plt.imshow(Fruit_Noise, cmap='gray')

Les valeurs de mean et sigma peuvent être modifiées pour provoquer un changement de bruit spécifique, tel que le bruit gaussien ou bruit poivre-sel, etc. Vous pouvez utiliser randn ou randu en fonction des besoins. Consultez la documentation: https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#cv2.randu

0
Gokul Krishna

bien qu'il n'y ait pas de fonctions intégrées comme dans matlab "imnoise (image, noiseType, NoiseLevel)" mais on peut facilement ajouter la quantité requise aléatoire Bruit impulsif ou sel et poivre dans une image manuellement . 1. ajouter du bruit d'impulsion aléatoire.

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
  1. ajouter du bruit de sel et de poivre
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

'' 'Remarque: pour les images couleur: première image divisée en trois ou quatre canaux en fonction de l'image d'entrée en utilisant la fonction d'openv: (B, G, R) = cv2.split (image)
(B, G, R, A) = cv2.split (image)
après division, effectuez les mêmes opérations sur tous les canaux. à la fin, fusionnez tous les canaux: merged = cv2.merge ([B, G, R]) retourne fusionné '' ' J'espère que cela aidera quelqu'un. 

0
Ubaid Ismat
#Adding noise
[m,n]=img.shape
saltpepper_noise=zeros((m, n));
saltpepper_noise=Rand(m,n); #creates a uniform random variable from 0 to 1 
for i in range(0,m):
    for j in range(0,n):
        if saltpepper_noise[i,j]<=0.5:
            saltpepper_noise[i,j]=0
        else:
            saltpepper_noise[i,j]=255
0
Pou