Image processing OpenCV的脉冲、高斯和椒盐噪声

Image processing OpenCV的脉冲、高斯和椒盐噪声,image-processing,opencv,Image Processing,Opencv,我正在研究著名的图像处理和谈论图像恢复,很多例子都是用计算机产生的噪声(高斯、椒盐等)来完成的。在MATLAB中,有一些内置函数可以实现这一点。OpenCV呢?据我所知,没有像Matlab那样方便的内置函数。但只需几行代码,您就可以自己创建这些图像 例如,加性高斯噪声: Mat gaussian_noise = img.clone(); randn(gaussian_noise,128,30); 椒盐噪音: Mat saltpepper_noise = Mat::zeros(img.rows,

我正在研究著名的图像处理和谈论图像恢复,很多例子都是用计算机产生的噪声(高斯、椒盐等)来完成的。在MATLAB中,有一些内置函数可以实现这一点。OpenCV呢?

据我所知,没有像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);
Mat saltpepper\u noise=Mat::零(img.rows、img.cols、CV\u 8U);
randu(Saltu噪音,0255);
Mat black=盐雾噪声<30;
Mat white=盐胡椒噪声>225;
Mat saltpepper_img=img.clone();
盐胡椒粉(255,白色);
盐胡椒(0,黑色);
#添加噪音
[m,n]=img.shape
saltpepper_噪声=零((m,n));
噪声=兰特(m,n)#创建从0到1的统一随机变量
对于范围(0,m)内的i:
对于范围(0,n)内的j:
如果噪声[i,j]
向图像添加高斯、椒盐斑点和泊松噪声的简单函数

可以使用NumPy矩阵运算以非常简单的方式添加“Salt&Pepper”噪声

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
def添加盐和胡椒粉(gb,prob):
''向图像添加“椒盐”噪声。
gb:应为单通道图像,像素在[0,1]范围内
问题:控制噪音级别“”的概率(阈值)
rnd=np.random.rand(gb.shape[0],gb.shape[1])
noised=gb.copy()
噪声[rnd1-概率]=1
回音嘈杂
均值和西格玛的值可以改变,以引起噪声的特定变化,如高斯噪声或椒盐噪声等。 您可以根据需要使用randn或randu。请查看文档:

虽然没有像matlab中那样的内置函数 “imnoise(图像、noiseType、NoiseLevel)”但我们可以轻松地随机添加所需数量 手动将有值脉冲噪声或椒盐输入图像。 1.添加随机值脉冲噪声

将随机导入为r
def addRvinGray(图像,n):#在灰度中添加随机值脉冲噪声
''参数:
image:type=numpy数组。要在其中添加噪波的输入图像。
n:噪声级(百分比)“”
k=0#计数器变量
ih=图像.形状[0]
iw=image.shape[1]
noisepixels=(ih*iw*n)/100#这里我们计算要改变的像素数。
对于范围内的i(ih*iw):
如果k有来自scikit映像包的功能。它有几种内置的噪声模式,例如
gaussian
s&p
(用于椒盐噪声),
possion
spoke

下面我展示了一个如何使用此方法的示例

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()

还有一个名为的包,专门用于以各种方式增强图像。它提供高斯、泊松和椒盐噪声增强。以下是如何使用它向图像添加噪波:

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 __name__ == "__main__":
    main()


我对@Shubham Pachori的代码做了一些修改。将图像读取到numpy阵列中时,默认的数据类型为uint8,在图像上添加噪波时会导致换行

import numpy as np
from PIL import Image

"""
image: read through PIL.Image.open('path')
sigma: variance of gaussian noise
factor: the bigger this value is, the more noisy is the poisson_noised image

##IMPORTANT: when reading a image into numpy arrary, the default dtype is uint8,
which can cause wrapping when adding noise onto the image. 
E.g,  example = np.array([128,240,255], dtype='uint8')
     example + 50 = np.array([178,44,49], dtype='uint8')
Transfer np.array to dtype='int16' can solve this problem.
"""


def gaussian_noise(image, sigma):
    img = np.array(image)
    noise = np.random.randn(img.shape[0], img.shape[1], img.shape[2])
    img = img.astype('int16')
    img_noise = img + noise * sigma
    img_noise = np.clip(img_noise, 0, 255)
    img_noise = img_noise.astype('uint8')
    return Image.fromarray(img_noise)


def poisson_noise(image, factor):
    factor = 1 / factor
    img = np.array(image)
    img = img.astype('int16')
    img_noise = np.random.poisson(img * factor) / float(factor)
    np.clip(img_noise, 0, 255, img_noise)
    img_noise = img_noise.astype('uint8')
    return Image.fromarray(img_noise)

所以这个问题不是关于MATLAB的…?不,你是对的,我删除了标记MATLAB当我使用高斯类型时,我的图像变成全白色。我是这样做的:image=cv2.imread(fn)noise\u gauss=noise(“高斯”,image)cv2.imshow(“高斯”,noise\u gauss)。似乎产生的噪音不是同一类型的,加起来会引起一些奇怪的问题transformation@Lxu你能展示这个转换是什么样子吗?@Lxu我相信这是因为numpy数组类型变成了
float64
。在你把它传递给cv2.imshow之前,只需写下
noise\u gauss=noise\u gauss.astype('uint8')
,实际上把大部分问题放在一个URL中(可能会消失)是不好的风格,所以请不要在回答问题时重复这一点!尝试在输入框中编写基本解决方案,并使用代码格式化来格式化代码。您的代码确实可以完成这项工作,但只能在一个通道中完成。您需要mean/sigma是一组值,比如:sigma=(10,10,10)
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
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()
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 __name__ == "__main__":
    main()
skimage.util.random_noise(image, mode='gaussian', seed=None, clip=True, **kwargs)
import numpy as np
from PIL import Image

"""
image: read through PIL.Image.open('path')
sigma: variance of gaussian noise
factor: the bigger this value is, the more noisy is the poisson_noised image

##IMPORTANT: when reading a image into numpy arrary, the default dtype is uint8,
which can cause wrapping when adding noise onto the image. 
E.g,  example = np.array([128,240,255], dtype='uint8')
     example + 50 = np.array([178,44,49], dtype='uint8')
Transfer np.array to dtype='int16' can solve this problem.
"""


def gaussian_noise(image, sigma):
    img = np.array(image)
    noise = np.random.randn(img.shape[0], img.shape[1], img.shape[2])
    img = img.astype('int16')
    img_noise = img + noise * sigma
    img_noise = np.clip(img_noise, 0, 255)
    img_noise = img_noise.astype('uint8')
    return Image.fromarray(img_noise)


def poisson_noise(image, factor):
    factor = 1 / factor
    img = np.array(image)
    img = img.astype('int16')
    img_noise = np.random.poisson(img * factor) / float(factor)
    np.clip(img_noise, 0, 255, img_noise)
    img_noise = img_noise.astype('uint8')
    return Image.fromarray(img_noise)