Как создать шумные изображения для увеличения данных - PullRequest
2 голосов
/ 14 января 2020

Я последовал за самым голосуемым ответом на вопрос, касающийся добавления шума к изображению. Однако это не работает для меня. Я просто хочу наблюдать различные шумовые эффекты на изображении при использовании Python Как добавить шум (Gaussian / соль и перец и т.д. c) к изображению в Python с OpenCV

Из того, что я знаю, изображения являются чем-то типа uint8? Я не уверен, что этот тип может принимать десятичные дроби.

Часть соли и перца тоже не работает

from numpy import shape, asarray
import numpy as np
import cv2
from PIL import Image
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,sigma,(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 = np.copy(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

pic = Image.open('obamaface1.jpg')
pic = pic.convert('RGB')
pixels = asarray(pic)
image = Image.fromarray(pixels)

target = noisy('speckle', pixels)
target = Image.fromarray(target)
print(target)

Последняя строка - просто посмотреть, что выводит терминал , Это вывод

  File "C:\Users\Jerome Ariola\AppData\Local\Programs\Python\Python36\lib\site-packages\PIL\Image.py", line 2647, in fromarray
    raise TypeError("Cannot handle this data type")
TypeError: Cannot handle this data type

Комментирование target = Image.fromarray(target) дает мне:

[[[ 10.03013352   7.53745105  11.03977542]
  [  9.38952149   7.81507808  11.53212491]
  [  9.76439692   7.88213107  11.47620008]
  ...
  [  6.76471119   5.09559321   5.9144036 ]
  [  7.34123162   4.92342273   6.31726796]
  [255.13791218 253.89755922 255.15403824]]

 [[  9.90775807   8.49642977  10.86023707]
  [  9.71078442   7.94264649  11.18820572]
  [  9.91127254   8.15716707  11.04770154]
  ...
  [  7.05173864   4.89094663   5.67662439]
  [  7.10166986   5.47480635   6.11892638]
  [255.03879603 254.07485578 254.88072098]]

 [[  9.81995678   7.55439474  11.08609859]
  [ 10.32135236   7.5301714   11.03612056]
  [ 10.17215819   8.09537629  11.30984933]
  ...
  [  7.13999574   5.12009845   7.8678079 ]
  [  7.31635614   5.1527127    8.23318054]
  [255.12283461 254.01880276 254.76894074]]

 ...

 [[ 19.72596723  22.29694693  20.95524912]
  [ 19.30898519  21.61944993  20.85653566]
  [ 20.45174165  20.55101246  21.1739277 ]
  ...
  [ 13.89796331  11.73865315  12.50874487]
  [ 14.13985843  11.97177032  12.80855176]
  [255.04963076 254.23626115 254.75904336]]

 [[ 19.17915912  21.2224852   18.37260714]
  [ 19.1068802   20.2797369   17.96846182]
  [ 20.37263348  20.23856465  18.02893703]
  ...
  [ 14.48307596  12.46348446  15.43437954]
  [ 14.11840104  12.35783324  14.64863437]
  [254.99657596 253.95241488 255.34200558]]

 [[ 20.03354477  22.02402748  18.45595882]
  [ 19.74202893  22.59472663  19.19910502]
  [ 21.96931817  22.22425014  19.59694792]
  ...
  [ 14.68256917  12.37915145  15.07832362]
  [ 14.25010143  12.45545202  14.65549651]
  [254.96105357 254.17655349 255.29863654]]]

Я думал, что я бы также переписал его, например, с image.shape до np.shape(image)

def noisify(type, target):
    if type == 'gauss':
        row,col, ch = np.shape(target)
        mean = 0
        var = 0.1
        sigma = var**0.5
        gauss = np.random.normal(mean, sigma, (row,col,ch))
        noise = target + gauss
        return noise
    elif type == 'sap':
        row, col, ch = np.shape(target)
        s_vs_p = 0.5
        amount = 0.004
        out = np.copy(target)
        #salt
        num_salt = np.ceil(amount * np.size(target) * s_vs_p)
        coords = [np.random.randint(0,i-1, int(num_salt))
                for i in np.shape(target)]
        out[coords] = 1
        #pepper
        num_pepper = np.ceil(amount* np.size(target) * (1. - s_vs_p))
        coords = [np.random.randint(0,i-1, int(num_pepper))
                for i in np.shape(target)]
        out[coords] = 0
        return out
    elif type == 'poisson':
        vals = len(np.unique(target))
        vals = 2 ** np.ceil(np.log2(vals))
        noise = np.random.poisson(target * vals) / float(vals)
        return noise
    elif type == 'speckle':
        row, col, ch = np.shape(target)
        gauss = np.random.randn(row,col,ch)
        gauss = np.reshape(gauss,(row,col,ch))
        noise = target + target * gauss
        return noise

Любая помощь будет оценена.

1 Ответ

2 голосов
/ 15 января 2020

Вот векторизованный подход с использованием OpenCV + skimage.util.random_noise. Вы можете поэкспериментировать с шумовыми режимами, такими как localvar, pepper, s&p и speckle, чтобы получить желаемый результат. Вы можете установить пропорцию шума с помощью параметра amount. Вот пример использования s&p с amount=0.011:

Входное изображение

enter image description here

Результат

enter image description here

С amount=0.051:

enter image description here

import cv2
import numpy as np
from skimage.util import random_noise

# Load the image
image = cv2.imread('1.png', 0)

# Add salt-and-pepper noise to the image
noise = random_noise(image, mode='s&p', amount=0.011)

# The above function returns a floating-point image in the range [0, 1]
# so need to change it to 'uint8' with range [0,255]
noise = np.array(255 * noise, dtype=np.uint8)

cv2.imshow('noise',noise)
cv2.imwrite('noise.png',noise)
cv2.waitKey()
...