Импульс, Гаусс и соль и перец шум с OpenCV
Я изучаю обработку изображений по знаменитому Гонсалесу "Цифровая обработка изображений" и говорю о восстановлении изображений много примеров сделано с помощью компьютерного шума (Гаусса, соли и перца и т. д.). В MATLAB для этого есть несколько встроенных функций. А как насчет OpenCV?
6 ответов:
Насколько я знаю, нет удобных встроенных функций, как в Matlab. Но с помощью всего лишь нескольких строк кода Вы можете создать эти образы самостоятельно.
Например аддитивный гауссов шум:
Mat gaussian_noise = img.clone(); randn(gaussian_noise,128,30);Соль и перец шум:
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);
Простая функция для добавления гауссова, сольно-перечного спекла и пуассоновского шума к изображению
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
Шум"соль и перец" можно добавить довольно простым способом, используя операции матрицы 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
#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
Значения среднего и Сигмы могут быть изменены, чтобы вызвать определенное изменение в шуме, таком как гауссовский или перцово-солевой шум и т. д. Вы можете использовать randn или ранду по необходимости. Взгляните на документацию: https://docs.opencv.org/2.4/modules/core/doc/operations_on_arrays.html#cv2.randu# 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')
Хотя нет встроенных функций, как в matlab "imnoise (image, noiseType, NoiseLevel)", но мы можем легко добавить необходимое количество случайных ценится импульсный шум или соль и перец в изображение вручную. 1. чтобы добавить случайный значимый импульсный шум.
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
- добавить соль и перец шум
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"' Примечание: Для цветных изображений: сначала разбейте изображение на три или четыре канала в зависимости от входного изображения с помощью opencv функция: (B, G, R) = cv2.split (image)
(B, G, R, A) = cv2.split (image)
после расщепления выполните те же операции на всех каналах. в конце сольются все каналы: слияние = cv2.слияние([B, G, R]) возвращение слилось"' Надеюсь, это кому-то поможет.
Comments