0

I found something reasonably close to what I want to do here: Python: PIL replace a single RGBA color

However, in my scenario I have images that were originally grayscale with color annotations added to the image (an x-ray with notes in color). I would like to replace any pixel that is not grayscale with random noise. My main problem is replacing values with noise and not a single color.

Edit: I figured out the random noise part, now just trying to figure out how to separate the color pixels from the pixels that were originally in grayscale.

from PIL import Image
import numpy as np

im = Image.open('test.jpg')

data = np.array(im)   # "data" is a height x width x 3 numpy array
red, green, blue = data.T # Temporarily unpack the bands for readability


# Replace white with random noise...
white_areas = (red == 255) & (blue == 255) & (green == 255)
Z = random.random(data[...][white_areas.T].shape)
data[...][white_areas.T] = Z

im2 = Image.fromarray(data)
im2.show()
Beaker
  • 2,804
  • 5
  • 33
  • 54
  • "now just trying to figure out how to separate the color pixels from the pixels that were originally in grayscale": `mask = (data == np.repeat(255,3)).all(axis=-1)`; `color_pixels = data[~mask]` – kevinkayaks Apr 07 '19 at 21:28
  • The RAM usage goes off the charts when I use your code snippet in the above code. – Beaker Apr 07 '19 at 21:38
  • odd. `mask` shouldn't be any larger than your `white_areas` as far as I can see, I'm interested if you discovered why. You might compare to `grey = np.repeat(255,3)`; `mask=(data==grey).all(axis=-1)`, to see if the overhead stems from recomputing `np.repeat(255,3)` at every pixel. Otherwise it seems a more compact way to compute `white_areas` – kevinkayaks Apr 08 '19 at 06:32

2 Answers2

0

You could try

col_areas = np.logical_or(np.not_equal(red, blue), np.not_equal(red, green))
SpghttCd
  • 10,510
  • 2
  • 20
  • 25
0

You could use this Pixel Editing python module

from PixelMenu import ChangePixels as cp
im = Image.open('test.jpg')
grayscalergb=(128, 128, 128) #RGB value of gray in your image
noise=(100,30,5) #You can adjust the noise based upon your requirements
outputimg=cp(im, col=grayscalergb, col2=noise, save=False,tolerance=100) #Adjust the tolerance until you get the right amount of noise in your image

Also:

I'd suggest you to use png images instead of jpg images because JPEG is designed with compression, everytime you load the image the RGB values change making it hard for your code to function perfectly everytime

Community
  • 1
  • 1
DankCoder
  • 369
  • 1
  • 4
  • 15