简体   繁体   中英

Replace specific pixels by rgb with white color

There is an image like that在此处输入图像描述

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

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.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM