Home > Blockchain >  Replace specific pixels by rgb with white color
Replace specific pixels by rgb with white color

Time:03-08

There is an image like that enter image description here

I used a website to detect the rgb of the background and it is 42,44,54. Aiming at replacing the pixels with that rgb to white Here's my try but I didn't get the expected output

import cv2
import numpy as np

# Load image
im = cv2.imread('Sample.png')

# Make all perfectly green pixels white
im[np.all(im == (42,44,54), axis=-1)] = (255, 255, 255)

# Save result
cv2.imwrite('Output.png',im)

I have searched again and found the following code (works to somewhat)

from PIL import Image

img = Image.open("Sample.png")
img = img.convert("RGB")

datas = img.getdata()

new_image_data = []
for item in datas:
    # change all white (also shades of whites) pixels to yellow
    if item[0] in list(range(42, 44)):
        new_image_data.append((255, 255, 255))
    else:
        new_image_data.append(item)
        
# update image data
img.putdata(new_image_data)

# save new image
img.save("Output.png")

# show image in preview
img.show()

I need also to change any other rgb to be black except white pixels. Simply to get all colored characters into black after removing the background color

I am stil trying (waiting for experts to contribute and offer a better solution). The following is quite good but not so perfect till now

from PIL import Image
import numpy as np

img = Image.open("Sample.png")
width = img.size[0]
height = img.size[1]

for i in range(0,width):
    for j in range(0,height):
        data = img.getpixel((i,j))
        if (data[0]>=36 and data[0]<=45) and (data[1]>=38 and data[1]<=45) and (data[2]>=46 and data[2]<=58):
            img.putpixel((i,j),(255, 255, 255))
        if (data[0]==187 and data[1]==187 and data[2]==191):
            img.putpixel((i,j),(255, 255, 255))

img.save("Output.png")

I thought of converting the image to grayscale using Pillow

from PIL import Image

img = Image.open('Sample.png').convert('LA')
img.save('Grayscale.png')

The image became cleared but how to replace rgb pixels in such mode? I tried the same previous code and changed the rgb values but didn't work and there are errors as the mode is L

CodePudding user response:

You can do both steps in one go:

from PIL import Image

def is_background(item, bg):
    # Tweak the ranges if the result is still unsatisfying 
    return (item[0] in range(bg[0] - 20, bg[0]   20)) or \
           (item[1] in range(bg[1] - 20, bg[1]   20)) or \
           (item[2] in range(bg[2] - 20, bg[2]   20))

img = Image.open("Sample.png")
img = img.convert("RGB")
datas = img.getdata()

bg = [42, 44, 54] # Background RGB color
new_image_data = []
for item in datas:
    # change all background to white and keep all white
    if is_background(item, bg) or item == (255, 255, 255):
        new_image_data.append((255, 255, 255))
    else:
        # change non-background and non-white to black
        new_image_data.append((0, 0, 0))


img.putdata(new_image_data)
img.save("Output.png")
img.show()

Here is the result.

Note that:

  • We need is_background because the background is not of the exact same color, there is a very slight variation

  • This method of detecting background is very basic and there are much more sophisticated ones.

CodePudding user response:

The issue is OpenCV follows BGR format and your pixel value is RGB. Fix that as follows.

# Make all perfectly green pixels white
im[np.all(im == (54,44,42), axis=-1)] = (255, 255, 255)

  • Related