【问题标题】:Pixel is there but .getpixel isn't detecting it像素在那里,但 .getpixel 没有检测到它
【发布时间】:2021-03-27 00:42:10
【问题描述】:

我的程序目前存在问题,我不太确定如何解决。

我正在做以下事情:

x = 0
y = 0
im = ImageGrab.grab()
time.sleep(1)
while True:
    xy = (x, y)
    x = x + 1
    if im.getpixel(xy) == (0,158,187):
        time.sleep(0.3)
        pyautogui.click(x,y)
        break
    if x >= 1200:
        x = 0
        y = y + 1
        print('cant find pixel')
    if y >= 950:
        y = 0
        x = 0

它在大约 90% 的时间里工作,然后有这个随机时间它只是说它无法检测到像素,尽管像素在那里 100%。

编辑:设法在它发生的 10% 中捕获以下错误:

AttributeError: 'NoneType' object has no attribute 'getpixel'

这没有任何意义,因为我事先在做 im = ImageGrab.grab() 并且它在 90% 的时间里都有效

【问题讨论】:

  • 问题不在于它无法检测到像素。问题是ImageGrab.grab 失败了。您可能需要检查并稍后重试。为什么抓屏后要等一秒再搜索位图?
  • @TimRoberts 没有具体原因,问题是如果需要,该程序将不间断运行 8 小时,我不能让 ImageGrab.grab 无缘无故随机失败。我通过这样做找到了一个半修复: while True: if im is None: im = ImageGrab.grab() else: break 问题是它有时仍然会以某种方式发生......

标签: python python-3.x python-imaging-library cv2


【解决方案1】:

您应该在使用数据之前检查您的ImageGrab() 是否成功,例如:

im = ImageGrab.grab()
if im is not None:
   processImage

如果您在图像上运行两次for 循环并为每个图像调用一个函数,您将在那里一整天!尝试养成在 Python 中对图像使用 Numpy 矢量化代码的习惯。

基本上,您似乎是在测试 1200x950 图像中的任何像素是否与所有三个 RGB 分量 (0,158,187) 匹配。

你可以像这样用 Numpy 做到这一点:

 np.any(np.all(na==(0,158,187), axis=-1))

在下面的演示中,双 for 循环需要 800 毫秒,而 Numpy 测试需要 20 毫秒,因此快了 40 倍。

#!/usr/bin/env python3

import numpy as np
from PIL import Image

def loopy(im):
   for x in range(im.width):
      for y in range(im.height):
         if im.getpixel((x,y)) == crucialPixel:
            return True

   return False


def me(im):
    # Make image into Numpy array
    na = np.array(im)
    # Test if there is any pixel where all RGB components match crucialPixel
    return np.any(np.all(na==crucialPixel, axis=-1))

# Define our beloved crucial pixel
crucialPixel = (0,158,187)

# Construct a new, solid black image
im = Image.new('RGB', (1200,950))

# Neither should find crucialPixel in black image
result = loopy(im)
result = me(im)

# Insert the crucial pixel
im.putpixel((600,475), crucialPixel)

# Both should find crucialPixel
result = loopy(im)
result = me(im)

【讨论】:

  • 完全有效,但没有解决实际问题。
  • 哇,这真是令人印象深刻,快了 40 倍。不知道你可以用 numpy 做到这一点,真的让我想到了所有我还不知道的事情,这些事情可以让我的程序快 10 倍哈哈哈
  • @MadPhysicist 感谢您让我保持“直截了当”。我试图改进我的答案。
  • @MarkSetchell 有没有办法让 numpy 返回像素的坐标?我需要它,因为我需要鼠标点击这些坐标
  • 尝试将np.any(...) 替换为Y, X = np.argwhere(np.all(na==crucialPixel, axis=-1)) 并查看X 和Y 的第一个元素(如果它们不是None)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 1970-01-01
  • 2013-07-29
  • 2021-01-06
  • 1970-01-01
  • 1970-01-01
  • 2017-09-13
相关资源
最近更新 更多