Python中的imnoise?

3 投票
4 回答
14800 浏览
提问于 2025-04-18 02:03

我想在对一张图片应用低通滤波器之后,给它加上一些白噪声。我知道怎么在matlab里做到这一点,但在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)

我还需要导入什么吗?或者有没有其他方法可以添加噪声呢?

4 个回答

1

虽然没有像matlab那样的内置函数,比如“imnoise(image,noiseType,Amount_of_Noise)”,但我们可以很简单地手动给图像添加所需的随机脉冲噪声或者盐和胡椒噪声。

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

> 添加盐和胡椒噪声

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

注意:对于彩色图像,首先要根据输入图像将图像分成三或四个通道,使用opencv的函数: (B, G, R) = cv2.split(image) 或者 (B, G, R, A) = cv2.split(image)。分开后,对所有通道执行相同的操作。最后再把所有通道合并起来:merged = cv2.merge([B, G, R]),然后返回合并后的结果。我希望这能帮助到某些人。

2
  1. 代码示例。

    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. 更多信息:http://scikit-image.org/docs/0.13.x/api/skimage.util.html#skimage.util.random_noise

10

scikit-image 提供了一个叫做 random_noise 的函数,这个函数和 MATLAB 里的 imnoise 很相似。

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

它支持以下几种噪声模式:

‘gaussian’:高斯分布的加性噪声。

‘localvar’:高斯分布的加性噪声,每个图像的点都有指定的局部方差。

‘poisson’:从数据中生成的泊松分布噪声。

‘salt’:随机像素被替换为 1。

‘pepper’:随机像素被替换为 0。

‘s&p’:随机像素被替换为 0 或 1。

‘speckle’:乘法噪声,计算方式是 out = image + n*image,其中 n 是具有指定均值和方差的均匀噪声。

注意,这个函数和 MATLAB 的 imnoise 的一个不同之处在于,输出的图像总是浮点型的。

举个例子,如果输入的图像是 uint8 的灰度图像,它会先被转换为浮点型,但输出的图像不会被转换回和输入图像相同的类型。

所以如果你在意图像的类型,记得自己转换输出,比如可以使用 skimage.img_as_ubyte

3

在讨论去噪的时候,这个教程通过给一张图片添加白噪声来演示,代码是 noisy = l + 0.4 * l.std() * np.random.random(l.shape),其中 l 就是那张图片。

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

一般来说,你可以通过把一个充满噪声的矩阵加到原图上,来简单地添加噪声。

撰写回答