Je veux savoir si la couleur X apparaît dans une image. Dans ce cas, la couleur de l'étude sera verte, donc sa valeur RVB est (0.255.0).
J'applique le code suivant:
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)
En gros:
Ci-dessous, l'image du studio, puis ce qui est peint en rouge.
Image à étudier:
Résultat:
Pourquoi une boîte n'est-elle pas peinte de la même manière que le vert mais en rouge? Pourquoi juste ces petits points?
Merci!
3 Réponses :
Le problème est dû au fait que la zone verte n'est PAS construite uniquement à partir de [0, 255, 0] comme vous le pensez, OT21t.jpg est votre image d'entrée, lorsque J'ai fait:
import cv2
img = cv2.imread('OT21t.jpg')
print(img[950,1300])
J'ai [2 255 1] , donc ce n'est pas [0,255,0] . Gardez à l'esprit que lorsque des images .jpg sont enregistrées, le plus souvent il s'agit d'un processus avec perte - une partie des données peut être abandonnée, ce qui permet une taille de fichier plus petite (pour en savoir plus sur cette recherche de compression avec perte ).
voici un script qui fait ce que vous voulez, j'ai aussi utilisé numpy donc il ne sera pas difficile de l'adapter à vos besoins.
Ce script trouvera une couleur et la remplacera par une autre:
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")
Celui-ci sera noir avec seulement la correspondance colorée dans la couleur de remplacement:
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")
Ce qui manque à votre script, c'est une certaine tolérance , car votre vert n'est peut-être pas parfait.
Il est souvent plus approprié d'utiliser le système «Teinte, saturation et luminosité» plutôt que RVB pour séparer les couleurs des images - voir Article Wikipédia ici .
Vous pourriez donc envisager quelque chose comme ceci:
#!/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')