如何获取OpenCV中显示的图像坐标

对不起,但标题似乎不太合理

我正在尝试制作一个AI,通过点击球使其弹跳。以下是应用程序的图片enter image description here

在游戏中,点击球后,球会向上然后再落下来,游戏的目标是保持球不落地。

我已经编写了一些代码,使用OpenCV将图像转换为掩码,以下是结果的图片

enter image description here

我现在需要做的是找到球的位置(以像素/坐标表示),这样我可以让鼠标移动到该位置并点击它。顺便说一下,球的左右两侧有边距,所以它不会只是直上直下,而是左右移动。另外,球不是动画,只是移动的图像。

如何获取球的位置(以像素/坐标表示),这样我可以移动鼠标到该位置。

这是我的代码副本:

import numpy as npfrom PIL import ImageGrabimport cv2import timeimport pyautoguidef draw_lines(img,lines):    for line in lines:        coords = line[0]        cv2.line(img, (coords[0], coords[1]), (coords[2], coords[3]), [255,255,255], 3)def process_img(original_image):    processed_img = cv2.cvtColor(original_image, cv2.COLOR_BGR2GRAY)    processed_img = cv2.Canny(processed_img, threshold1=200, threshold2=300)    vertices = np.array([[0,0],[0,800],[850,800],[850,0]                         ], np.int32)    processed_img = roi(processed_img, [vertices])    # more info: http://docs.opencv.org/3.0-beta/doc/py_tutorials/py_imgproc/py_houghlines/py_houghlines.html    #                          edges       rho   theta   thresh         # min length, max gap:            lines = cv2.HoughLinesP(processed_img, 1, np.pi/180, 180,      20,         15)    draw_lines(processed_img,lines)    return processed_imgdef roi(img, vertices):    #blank mask:    mask = np.zeros_like(img)    # fill the mask    cv2.fillPoly(mask, vertices, 255)    # now only show the area that is the mask    masked = cv2.bitwise_and(img, mask)    return maskeddef main():    last_time = time.time()    while(True):        screen =  np.array(ImageGrab.grab(bbox=(0,40, 800, 850)))        new_screen = process_img(screen)        print('Loop took {} seconds'.format(time.time()-last_time))        last_time = time.time()        cv2.imshow('window', new_screen)        #cv2.imshow('window2', cv2.cvtColor(screen, cv2.COLOR_BGR2RGB))        if cv2.waitKey(25) & 0xFF == ord('q'):            cv2.destroyAllWindows()            breakdef mouse_movement():    ##Set to move relative to where ball is    pyautogui.moveTo(300,400)    pyautogui.click();main()

对不起如果这让您感到困惑,但我的大脑已经停止工作了 🙁 谢谢


回答:

当您删除了另一个相关的问题时,我正在处理它,并且看到您在定位球时遇到了性能问题。由于您的球似乎在一个简单而干净的白色背景上(除了得分和右上角的close按钮),有更简单/更快的方法来找到球。

首先,使用灰度模式工作,这样您只需处理一个通道,而不是RGB的三个通道——这通常会更快。

然后,用白色像素覆盖右上角的得分和菜单,这样图像中只剩下球。现在反转图像,使所有白色变为黑色,然后您可以使用findNonZero()来找到任何不是背景的东西,即球。

现在找到y方向上的最低和最高坐标,并平均它们以确定球的中心,同样在x方向上找到另一方向的中心。

#!/usr/bin/env python3# Load image - work in greyscale as 1/3 as many pixelsim = cv2.imread('ball.png',cv2.IMREAD_GRAYSCALE)# Overwrite "Current Best" with white - these numbers will vary depending on what you captureim[134:400,447:714] = 255# Overwrite menu and "Close" button at top-right with white - these numbers will vary depending on what you captureim[3:107,1494:1726] = 255# Negate image so whites become blackim=255-im# Find anything not black, i.e. the ballnz = cv2.findNonZero(im)# Find top, bottom, left and right edge of balla = nz[:,0,0].min()b = nz[:,0,0].max()c = nz[:,0,1].min()d = nz[:,0,1].max()print('a:{}, b:{}, c:{}, d:{}'.format(a,b,c,d))# Average top and bottom edges, left and right edges, to give centrec0 = (a+b)/2c1 = (c+d)/2print('Ball centre: {},{}'.format(c0,c1))

这会得到:

a:442, b:688, c:1063, d:1304Ball centre: 565.0,1183.5

如果我在图像上画一个红色的框,会显示如下:

enter image description here

在我的Mac上处理时间为845微秒,或者不到一毫秒,这相当于每秒1,183帧。显然,您需要时间来捕获屏幕,但我无法控制这一点。

请注意,您还可以将图像按每个方向的4倍(或可能是8倍或16倍)缩小尺寸,并且仍然可以确定找到球,这可能会使处理速度更快。

关键词:球,追踪,定位,寻找,位置,图像,图像处理,Python,OpenCV,NumPy,边界框,bbox。

Related Posts

L1-L2正则化的不同系数

我想对网络的权重同时应用L1和L2正则化。然而,我找不…

使用scikit-learn的无监督方法将列表分类成不同组别,有没有办法?

我有一系列实例,每个实例都有一份列表,代表它所遵循的不…

f1_score metric in lightgbm

我想使用自定义指标f1_score来训练一个lgb模型…

通过相关系数矩阵进行特征选择

我在测试不同的算法时,如逻辑回归、高斯朴素贝叶斯、随机…

可以将机器学习库用于流式输入和输出吗?

已关闭。此问题需要更加聚焦。目前不接受回答。 想要改进…

在TensorFlow中,queue.dequeue_up_to()方法的用途是什么?

我对这个方法感到非常困惑,特别是当我发现这个令人费解的…

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注