image-processing - como generar ruido gaussiano
Impulso, ruido gaussiano y sal y pimienta con OpenCV (6)
Estoy estudiando Procesamiento de imágenes en el famoso "Procesamiento de imágenes digitales" de Gonzales y hablando de restauración de imágenes, muchos ejemplos se hacen con ruido generado por computadora (gaussiano, sal y pimienta, etc.). En MATLAB hay algunas funciones integradas para hacerlo. ¿Qué pasa con OpenCV?
Función simple para agregar gaussiano, moteado de pimienta y ruido poisson a una imagen
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
aunque no hay funciones integradas como en matlab "imnoise (image, noiseType, NoiseLevel)", pero podemos agregar fácilmente la cantidad requerida de ruido de impulso aleatorio o sal y pimienta en una imagen manualmente. 1. para agregar ruido impulsivo aleatorio.
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
- para agregar ruido de sal y pimienta
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
'''' ''Nota: para imágenes en color: primera imagen dividida en tres o cuatro canales dependiendo de la imagen de entrada usando la función opencv: (B, G, R) = cv2.split (imagen)
(B, G, R, A) = cv2.split (imagen)
después de la división, realice las mismas operaciones en todos los canales. al final fusionar todos los canales: fusionada = cv2.merge ([B, G, R]) volver fusionada '''' ''Espero que esto ayude a alguien.
El ruido "Salt & Pepper" se puede agregar de una manera bastante simple usando operaciones de matriz 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
Hasta donde yo sé, no hay funciones integradas convenientes como en Matlab. Pero con solo unas pocas líneas de código puede crear esas imágenes usted mismo.
Por ejemplo, ruido gaussiano aditivo:
Mat gaussian_noise = img.clone();
randn(gaussian_noise,128,30);
Ruido de sal y pimienta:
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);
# 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'')
Los valores de media y sigma se pueden alterar para provocar un cambio específico en el ruido como el ruido gaussiano o de sal de pimienta, etc. Puede usar randn o randu de acuerdo con la necesidad. Eche un vistazo a la documentación: https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#cv2.randu
#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