首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在Python中添加不同粒度的噪声

在Python中添加不同粒度的噪声
EN

Stack Overflow用户
提问于 2022-04-10 15:35:28
回答 3查看 638关注 0票数 1

我试图添加噪音到图像中,以模仿真实世界的噪音产生的高ISO设置的相机。

代码语言:javascript
运行
复制
from skimage.util import random_noise
import random

val = random.uniform(0.036, 0.107)
noisy_img = random_noise(im_arr, mode='gaussian', var=val ** 2)
noisy_img = (255 * noisy_img).astype(np.uint8)

该代码运行良好,但噪声颗粒的大小始终为1像素。我真的想要不同大小的噪音颗粒。我怎样才能做到这一点?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-04-10 21:28:22

模拟高ISO环境下不同晶粒尺寸的噪声是很有挑战性的。

原因之一是,变化的晶粒的来源不是纯粹的物理效应。

其中一些颗粒来自于数字降噪(图像处理)的伪像,不同的相机和摄像机是不同的。

我想到了一个相对简单的解决方案:

resolutions.

  • Resize
  • 将不同分辨率的随机噪声加到原始图像大小上,
  • 将调整大小的图像从“噪声图像”(零均值)相加,
  • 将“噪声图像”添加到原始图像(干净)中。

需要进行大量的调整--选择分辨率,将不同的噪声设置到不同的分辨率,选择调整大小的插值方法。

我不认为这正是你想要的,但它应用了“不同粒度的噪音”,并可能给你一个线索。

代码示例:

代码语言:javascript
运行
复制
from skimage.util import random_noise
from skimage.io import imsave
from skimage.transform import resize
import random
import numpy as np

im_arr = np.full((256, 320), 0.5)  # Original image - use gray image for testing

rows, cols = im_arr.shape

val = 0.036 #random.uniform(0.036, 0.107) # Use constant variance (for testing).

# Full resolution
noise_im1 = np.zeros((rows, cols))
noise_im1 = random_noise(noise_im1, mode='gaussian', var=val**2, clip=False)

# Half resolution
noise_im2 = np.zeros((rows//2, cols//2))
noise_im2 = random_noise(noise_im2, mode='gaussian', var=(val*2)**2, clip=False)  # Use val*2 (needs tuning...)
noise_im2 = resize(noise_im2, (rows, cols))  # Upscale to original image size

# Quarter resolution
noise_im3 = np.zeros((rows//4, cols//4))
noise_im3 = random_noise(noise_im3, mode='gaussian', var=(val*4)**2, clip=False)  # Use val*4 (needs tuning...)
noise_im3 = resize(noise_im3, (rows, cols))  # What is the interpolation method?

noise_im = noise_im1 + noise_im2 + noise_im3  # Sum the noise in multiple resolutions (the mean of noise_im is around zero).

noisy_img = im_arr + noise_im  # Add noise_im to the input image.

noisy_img = np.round((255 * noisy_img)).clip(0, 255).astype(np.uint8)

imsave('noisy_img.png', noisy_img)

结果:

票数 3
EN

Stack Overflow用户

发布于 2022-04-11 03:12:48

你的问题意味着你想要空间相关的噪声,这样相邻的像素就可以共享一些信息。如果您并不真正关心相关结构是什么样子,您可以使用一个简单的平滑内核来生成粒度更粗的噪声。

实现这一目标的途径之一是:

代码语言:javascript
运行
复制
from skimage.data import shepp_logan_phantom
from skimage.util import random_noise
from scipy.ndimage import correlate
import numpy as np

# Granularity = 1
im_arr = shepp_logan_phantom()
val = 0.05
noisy_img = random_noise(im_arr, mode='gaussian', var=val)

# Correlated noise to increase granularity
# Generate random noise like skimage's random_noise does
noise = np.random.normal(scale=np.sqrt(val), size=im_arr.shape)
# Create a smoothing kernel
weights = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]]) / 5
# Apply it to the noise
noise_corr = correlate(noise, weights)
# Apply noise to image and clip
noisy_img_corr = np.clip(im_arr + noise_corr, 0, 1)


fig, (ax1, ax2) = plt.subplots(ncols=2)
ax1.imshow(noisy_img)
ax1.set_title("Uncorrelated noise")
ax1.axis("off")
ax2.imshow(noisy_img_corr)
ax2.set_title("Correlated noise")
ax2.axis("off")

或者,如果你知道相机里的噪音是从哪里来的,你也可以根据第一原理建立更好的噪声模型。这里有一些想法:https://graphics.stanford.edu/courses/cs178-10/lectures/noise-27apr10-150dpi-med.pdf

票数 1
EN

Stack Overflow用户

发布于 2022-04-11 03:41:30

Rotem的答案是最好的实现。

我(最初的海报)使用以下代码来扩展他对彩色图像的实现,并使用PIL作为导入,以防以后有人需要它:

代码语言:javascript
运行
复制
from skimage.transform import resize
import numpy as np
from skimage.util import random_noise
from PIL import Image

def gen_noise_mask(rows, cols):
    val = 0.036  # random.uniform(0.036, 0.107) # Use constant variance (for testing).
    # Full resolution
    noise_im1 = np.zeros((rows, cols))
    noise_im1 = random_noise(noise_im1, mode='gaussian', var=val ** 2, clip=False)

    # Half resolution
    noise_im2 = np.zeros((rows // 2, cols // 2))
    noise_im2 = random_noise(noise_im2, mode='gaussian', var=(val * 2) ** 2, clip=False)  # Use val*2 (needs tuning...)
    noise_im2 = resize(noise_im2, (rows, cols))  # Upscale to original image size

    # Quarter resolution
    noise_im3 = np.zeros((rows // 4, cols // 4))
    noise_im3 = random_noise(noise_im3, mode='gaussian', var=(val * 4) ** 2, clip=False)  # Use val*4 (needs tuning...)
    noise_im3 = resize(noise_im3, (rows, cols))  # What is the interpolation method?

    noise_im = noise_im1 + noise_im2 + noise_im3  # Sum the noise in multiple resolutions (the mean of noise_im is around zero).
    return noise_im


def noiseGenerator(im):
    im_arr = np.asarray(im)

    rows, cols, depth = im_arr.shape

    rgba_array = np.zeros((rows, cols, depth), 'float64')
    for d in range(0, depth):
        rgba_array[..., d] += gen_noise_mask(rows, cols)
    noisy_img = im_arr / 255 + rgba_array  # Add noise_im to the input image.
    noisy_img = np.round((255 * noisy_img)).clip(0, 255).astype(np.uint8)
    return Image.fromarray(noisy_img)
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71818076

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档