如果我知道颜色(RGB),如何获取像素坐标?

9

我使用Python、OpenCV和PIL。

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

color = (235, 187, 7)

如果我知道像素的颜色,如何获取像素坐标(x,y)?

1
JPEG是有损压缩的。祝你好运。 - Ignacio Vazquez-Abrams
好的,我会使用PNG格式,谢谢。需要像素搜索。 - dr.dia
使用 cv2.inRange() 函数,参见此处的示例。 - alkasm
这个答案展示了如何简单快速地完成它... https://dev59.com/iqzka4cB1Zd3GeqP9oFx#51091479 - Mark Setchell
@AlexanderReynolds 如果您想要在特定范围内获取像素,则 cv2.inRange() 会有所帮助。在这里,OP希望获取特定像素颜色的所有坐标。 - Jeru Luke
5个回答

8
这里有一个numpythonic的解决方案。Numpy库可以尽可能地加速操作。
假设颜色为:color = (235, 187, 7) 我使用了numpy.where()方法来检索包含颜色(235, 187, 7)像素的x坐标和y坐标,并返回一个元组indices的两个数组。现在,indices返回类似以下内容:
(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))
  • 然后我使用zip()方法获取包含这些点的元组列表。

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

  • 但是,如果你注意到这是一个带有三个通道的彩色图像,每个坐标将被重复三次。我们只需要保留唯一的坐标。这可以使用set()方法完成。

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


4
尝试像这样做:

尝试像这样做:

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}!")

但是getpixel可能会很慢,因此请考虑使用像素访问对象

还要注意返回的值可能取决于图像类型。例如,由于GIF像素引用GIF颜色调色板中的256个值之一,因此使用pix[1, 1]返回单个值。

另请参见此SO帖子:Python和PIL像素值对GIF和JPEG有所不同,以及此PIL参考页面包含有关convert()函数的更多信息。

顺便说一句,您的代码对于.jpg图像也可以正常工作。


2

您可以使用以下内容:

    import numpy as np

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

输出(它重复三次相同的坐标(颜色数量)):

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

为了避免这种情况,请按照以下步骤操作(对于代码的可读性感到抱歉):

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

输出:

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

对于灰度图像,它看起来更好:

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

输出:

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

1
这里提供一种仅使用cv2库的解决方案。
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)

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])

考虑添加一些代码解释。此外,问题使用了OpenCV,请尝试说明为什么选择PIL。 - alexfertel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接