Reputation: 31
I want to know if X color appears in an image. In this case, the color of the study will be green, therefore its RGB value is (0.255.0).
I apply the following code:
img = cv2.imread('img.jpg')
L1 = [0, 255, 0]
matches = np.all(img == L1, axis=2)
result = np.zeros_like(img)
print(result.any())
result[matches] = [255, 0, 255]
cv2.imwrite('resultado.jpg', result)
Basically:
Below is shown the studio image and then what is painted red.
Image to study:
Result:
Why is not a box painted the same as green but in red? Why just that little dots?
Thank you!
Upvotes: 3
Views: 205
Reputation: 207903
I is often more appropriate to use the "Hue, Saturation and Lightness" system rather than RGB to separate out colours in images - see Wikipedia article here.
So you might consider something like this:
#!/usr/local/bin/python3
import numpy as np
from PIL import Image
# Open image and make RGB and HSV versions
RGBim = Image.open("seaside.jpg")
HSVim = RGBim.convert('HSV')
# Make numpy versions
RGBna = np.array(RGBim)
HSVna = np.array(HSVim)
# Extract Hue
H = HSVna[:,:,0]
# Find all green pixels, i.e. where 110 < Hue < 130
lo,hi = 110,130
# Rescale to 0-255, rather than 0-360 because we are using uint8
lo = int((lo * 255) / 360)
hi = int((hi * 255) / 360)
green = np.where((H>lo) & (H<hi))
# Make all green pixels red in original image
RGBna[green] = [255,0,0]
count = green[0].size
print("Pixels matched: {}".format(count))
Image.fromarray(RGBna).save('result.png')
Upvotes: 1
Reputation: 3265
here is a script that does what you want, I used numpy too so it won't be difficult to adapt it for your needs.
This script will find a colour and replace it by another:
import numpy
from PIL import Image
im = numpy.array(Image.open("/path/to/img.jpg"))
tol = 4 # tolerence (0 if you want an exact match)
target_color = [0, 255, 0, 255] # color to change
replace_color = [255, 0, 255, 255] # color to use to paint the zone
for y, line in enumerate(im):
for x, px in enumerate(line):
if all((abs(px[i] - target_color[i]) < tol for i in range(3))):
im[y][x] = replace_color
Image.fromarray(im).save("./Desktop/img.png")
This one will be black with only the match coloured in the replace colour:
import numpy
from PIL import Image
im = numpy.array(Image.open("/path/to/img.jpg"))
new_im = numpy.zeros_like(im)
tol = 4 # tolerence (0 if you want an exact match)
target_color = [0, 255, 0, 255] # color to change
replace_color = [255, 0, 255, 255] # color to use to paint the zone
for y, line in enumerate(im):
for x, px in enumerate(line):
if all((abs(px[i] - target_color[i]) < tol for i in range(3))):
new_im[y][x] = replace_color
Image.fromarray(new_im).save("./Desktop/img.png")
What is missing from your script is some tolerance, because your green might not be a perfect green.
Upvotes: 1
Reputation: 36735
Problem is caused by that green area is NOT build only from [0, 255, 0]
as do you think, OT21t.jpg
is your input image, when I did:
import cv2
img = cv2.imread('OT21t.jpg')
print(img[950,1300])
I got [ 2 255 1]
, so it is not [0,255,0]
. Keep in mind that when .jpg
images are saved, most often it is lossy process - part of data might be jettisoned allowing smaller file size (for more about that search for lossy compression
).
Upvotes: 1