3

I need to add noise to multiple of coloured images (file format is ppm; source: http://benchmark.ini.rub.de/Dataset/GTSRB_Final_Training_Images.zip) in python. The noised output images should be still in colour.

I tryed the following:

from scipy import misc
import numpy as np
import cv2
import imageio

# Read image ('00000_00030.ppm') from file system
image  = misc.imread('./00000/00000_00030.ppm', mode="RGB")

# Add noise to the input image
noised_image = image + 3 * image.std() * np.random.random(image.shape)

# Plot original and noisy images
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
f, axarr = plt.subplots(2, 2)

axarr[0, 0].imshow(image)
axarr[0, 0].set_title('Original image')

axarr[0, 1].imshow(noised_image)
axarr[0, 1].set_title('Noised image')

plt.show() 

# Save noised image to file system
saved_image = cv2.imwrite("./noised.ppm", noised_image)

But first of all the problem is that the noised image won't be plotted correctly in jupyter notebook (see figure 1):

figure 1

The second problem is that the RG-channels (Red and Green) were be lost (in saved file):

figure 2

So how can I preserve all RGB colors in noised image?

After searching for a long time I have the solution now - the saved file preserves now all RGB-colours (See Line 8 in following code; see figure 3):

from scipy import misc
import numpy as np
import cv2
import imageio

# Read image ('00000_00030.ppm') from file system
# image  = misc.imread('./00000/00000_00030.ppm', mode="RGB")
image = cv2.imread('./00000/00000_00030.ppm',1)

# Add noise to the input image
noised_image = image + 3 * image.std() * np.random.random(image.shape)

# Plot original and noisy images
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
f, axarr = plt.subplots(2, 2)

axarr[0, 0].imshow(image)
axarr[0, 0].set_title('Original image')

axarr[0, 1].imshow(noised_image)
axarr[0, 1].set_title('Noised image')

plt.show() 

# Save noised image to file system
saved_image = cv2.imwrite("./noised1.ppm", noised_image)

Figure 3

But the plotted figures are still wrong:

Figure 4

Here is the final Code to add noise to RGB images in python, and plot them correctly:

from scipy import misc
import numpy as np
import cv2
import imageio

# Read image ('00000_00030.ppm') from file system
# image  = misc.imread('./00000/00000_00030.ppm', mode="RGB")
image = cv2.imread('./00000/00000_00030.ppm',1)

# Add noise to the input image
noised_image = image + 3 * image.std() * np.random.random(image.shape)

RGB_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)

# Plot original and noisy images
import matplotlib.pyplot as plt
plt.figure(figsize=(10, 10))
f, axarr = plt.subplots(2, 2)

axarr[0, 0].imshow(RGB_image)
axarr[0, 0].set_title('Original image')

axarr[0, 1].imshow(noised_image)
axarr[0, 1].set_title('Noised image')

plt.show() 

# Save noised image to file system
saved_image = cv2.imwrite("./noised1.ppm", noised_image)
Peter
  • 157
  • 4
  • 11
  • 1
    what did you try and where did you fail? there are several libraries to read images, several libraries e.g. numpy to generate random array of same size as your image. You can simply add random matrix to the image. – Dinesh Feb 26 '18 at 14:22
  • See edited initial problem description – Peter Feb 26 '18 at 19:22
  • I tried your code, but I think it still doesn't solve the problem. The problem is solved by imwrite rather than the plot – teddy May 28 '18 at 23:49

1 Answers1

0

This will take the pixel values of the given image and start encoding the noise that you give as input to the least significant bits in the pixel. The image output would vary slightly.

def asciiToBin(ascii):
    return ''.join(str(bin(ord(byte)))[2:].zfill(8) for byte in ascii)

def hide(img, data, outName):
    dataBin = asciiToBin(data)
    pixels, mode = list(img.getdata()), img.mode
    newPixels = []

    for i in range(len(dataBin)):
        newPixel = list(pixels[i])
        newPixel[i%len(mode)] = setLSB(newPixel[i%len(mode)], dataBin[i])
        newPixels.append(tuple(newPixel))

        newData = newPixels + pixels[len(newPixels):]

        img.putdata(newData)
        img.save(outName, "PNG")

   def setLSB(target, value):
        binary = str(bin(target))[2:]
        if binary[-1] != value:
            binary = binary[:-1] + value
        return int(binary, 2)
Jongware
  • 22,200
  • 8
  • 54
  • 100