9

I use Python, opencv and PIL.

image = cv2.imread('image.jpg')

color = (235, 187, 7)

How can I get pixel coordinates(x, y) if I know pixels color?

dr.dia
  • 91
  • 1
  • 1
  • 2

5 Answers5

8

Here is a numpythonic solution. Numpy library speeds up operations wherever possible.

  • Assuming the color to be: color = (235, 187, 7)

indices = np.where(img == color)

  • I used the numpy.where() method to retrieve a tuple indices of two arrays where the first array contains the x-coordinates of the pixels of color (235, 187, 7) and the second array contains the y-coordinates of those pixels.

Now indices returns something like the following:

(array([ 81,  81,  81, ..., 304, 304, 304], dtype=int64),
 array([317, 317, 317, ..., 520, 520, 520], dtype=int64),
 array([0, 1, 2, ..., 0, 1, 2], dtype=int64))
  • I then used the zip() method to get a list of tuples containing those points.

coordinates = zip(indices[0], indices[1])

  • But if you notice since this is a color image with three channels each coordinate will be repeated thrice. We have to keep only the unique coordinates. This can be accomplished using set() method.

unique_coordinates = list(set(list(coordinates)))

Jeru Luke
  • 20,118
  • 13
  • 80
  • 87
4

Try something like:

color = (235, 187, 7)
im = Image.open('image.gif')
rgb_im = im.convert('RGB')
for x in range(rgb_im.size()[0]):
    for y in range(rgb_im.size()[1]):
        r, g, b = rgb_im.getpixel((x, y))
        if (r,g,b) == colour:
            print(f"Found {colour} at {x},{y}!")

But getpixel can be slow, so look at using pixel access objects.

Also note that the value returned can depend on the image type. For example, a single value is returned with pix[1, 1] because GIF pixels refer to one of the 256 values in the GIF color palette.

See also this SO post: Python and PIL pixel values different for GIF and JPEG and this PIL Reference page contains more information on the convert() function.

By the way, your code would work just fine for .jpg images.

QA Collective
  • 2,222
  • 21
  • 34
2

you can use following:

    import numpy as np

    # for color image
    color = (75, 75, 75)
    pixels = np.argwhere(img == color)

output(it repeats the same coordinates three times(number of colors)):

[[   0   28    0]
 [   0   28    1]
 [   0   28    2]
 [   0   54    0]
 [   0   54    1]
 [   0   54    2]
 ................]

to avoid it do following(sorry for code readability):

    pixels = pixels[::3][:, [0, 1]]

output:

[[   0   28]
 [   0   54]
 ...........]

for gray scale image it looks better:

    color = (75)
    pixels = np.argwhere(img == color)

output:

[[   0   28]
 [   0   54]
 ...........]
apet
  • 958
  • 14
  • 16
1
import PIL #The reason I use PIL and not opencv is that I find pillow 
#(which is imported with 'PIL') a very useful library for image editing.

image = PIL.Image.open('Name_image') #the image is opened and named image
f = image.load() #I'm not sure what the load() operation exactly does, but it 
# is necesarry.

color = (235, 187, 7) # the Red Green Blue values that you want to find the 
#coordinates of
PixelCoordinates = [] # List in which all pixel coordinates that match 
#requirements will be added.

#The lines of code below check for each pixel in the image if the RGB-values 
# are equal to (235, 187, 7)
for x in image.size[0]:
    for y in image.size[1]:
        if f[x,y] == color:
            PixelCoordinates.append([x,y])
  • Consider adding some explanation of the code. Also, the question uses opencv, so try to say why did you choose PIL. – alexfertel Jun 09 '20 at 20:10
1

Here is a solution using cv2 library only

import cv2

blue = int(input("Enter blue value: "))
green = int(input("Enter green value: "))
red = int(input("Enter red value: "))
path = str(input("Enter image path with image extension:"))
img = cv2.imread(path)
img= cv2.resize(img,(150,150))
x,y,z = img.shape

for i in range(x):
  for j in range(y):
    if img[i,j,0]==blue & img[i,j,1]==green & img[i,j,1]==red:
      print("Found color at ",i,j)
shreyasm-dev
  • 2,711
  • 5
  • 16
  • 34