Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-解析图像上的对象_Python_Opencv_Image Processing - Fatal编程技术网

Python-解析图像上的对象

Python-解析图像上的对象,python,opencv,image-processing,Python,Opencv,Image Processing,我需要从简单的游戏Chrome Dyno中检测图像上的对象。我正在使用Python和Selenium启动游戏,并加载画布图像。主塔克,在这张图像上探测物体,找到Dyno和Dyno屏障 我正在使用这段代码,使用OpenCV,cv2库解析图片上的所有对象。 下面是代码(两个主要功能),识别所有对象大约需要80-200毫秒(基于屏障大小) ` #基于模板仅查找恐龙对象。 #这可能在以后通过轮廓搜索进行优化 def find_dino__________________________________

我需要从简单的游戏Chrome Dyno中检测图像上的对象。我正在使用Python和Selenium启动游戏,并加载画布图像。主塔克,在这张图像上探测物体,找到Dyno和Dyno屏障

我正在使用这段代码,使用OpenCV,
cv2
库解析图片上的所有对象。 下面是代码(两个主要功能),识别所有对象大约需要80-200毫秒(基于屏障大小)

`

#基于模板仅查找恐龙对象。
#这可能在以后通过轮廓搜索进行优化
def find_dino____________________________________________
结果=cv2.matchTemplate(cv2_image.astype(np.uint8)、self.dino_image、cv2.TM_CCOEFF)
_,u,u,dino_top_left=cv2.minMaxLoc(结果)
恐龙右下=(恐龙左上[0]+self.dino_宽度,恐龙左上[1]+self.dino_高度)
返回GenericGameObject(恐龙左上、恐龙右下)
#根据位置查找其他障碍物对象,除
#这就是恐龙的位置。使用恐龙的位置。
def查找恐龙屏障(自我、cv2图像、恐龙对象):
img_fil=cv2.medianBlur(cv2.cvt彩色(cv2_图像,cv2.COLOR_bgr2灰色),13)
img_th=cv2.自适应阈值(img_fil,255,cv2.自适应阈值高斯C,cv2.阈值二进制,11,2)
im2,轮廓,层次=cv2.查找轮廓(img_th,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
对象=[]
对于范围内的i(透镜(轮廓)):
x、 y,w,h=cv2.boundingRect(等高线[i])
如果y设置。恐龙工作区[1]:
持续

如果x三个有助于提高速度的大建议都归结为一件事:为处理管道的不同部分分割图像的不同部分。通过寻找不同的对象可以获得额外的速度提升。这两个目标是找到恐龙的位置,并在图像中找到新对象的位置

加速1 移除图像中T-Rex和物体不在的部分。我指的是画面的上半部分。对象不在这里,这大大减少了搜索空间

加速2 我在你帖子的评论中提到了这一点。不要在整个画面中寻找霸王龙。你知道霸王龙会在画面的某些水平边界内粘住,只会垂直移动。模板匹配肯定是一个缓慢的过程,因此通过减少搜索区域,您将获得很大的加速。您可以通过使用更小的模板和更小的搜索区域来进一步完善此功能。同样,你知道霸王龙会在某一部分,这意味着你知道霸王龙的头部或尾巴会在某一个更小的区域——所以在该区域搜索头部或尾巴或其他任何东西。通过将搜索区域缩小到上一帧中的位置,可以再次对其进行进一步细化。例如,我做了这个;你可以看到白色的搜索区域框,它在最后一帧中马里奥头部所在的位置移动

加速3 请注意,您只需要找到新对象……您知道滚动的速度,因此您知道一旦检测到对象,对象的移动速度以及它们在下一帧中的最终位置。对象不是整个帧的宽度,它们一次只能填充部分帧。因此,事实上,你只需要在新对象从屏幕右侧进入时搜索它们。然后,您可以标记它们(它们的宽度、高度、位置),然后计算它们的位置,而不是在每一帧中再次找到它们。现在,您的轮廓搜索只发生在帧的较小子集中(更快),并且您要循环的轮廓更少(更快)

加速4 请注意,您可以通过“地面”线下方的仙人掌底部检测仙人掌。看起来相似高度的仙人掌有相似的宽度,所以如果你检测到一个块,比如说4像素宽,你就知道仙人掌实际上在两侧延伸出8个像素,高30像素,或者不管实际值是什么。这将使您的问题变成检测仙人掌的底部而不是整个仙人掌,并大大减少了您对仙人掌的搜索区域。此外,你甚至不需要用这种方法找到轮廓!您只需在图像底部查找块,当它们之间的距离小于某个预定义的距离时,将它们组合在一起。这应该快得多。如果你这样做,你可能不需要担心只在正确的边界检测对象,然后在新的帧中计算它们的新位置……如果你只看一个4px宽的条带,这可能不会比只在每一帧中找到它们快多少

其他建议
我真的不明白模糊和自适应阈值的意义。图像实际上已经是二进制的;黑色或非黑色像素。也许这是一种将多个单独的对象(如单个仙人掌)组合成一个组的方法?无论哪种方法,都可能有更好(更快)的方法;例如,如果你侵蚀了图像(扩展了暗像素),那么仙人掌就会合并。我想这会更快,但你需要测试一下。如果这样做,轮廓将比实际宽度大一点,但可以通过将边界框缩小多少像素来进行补偿。当然,如果您实施加速4,这并不重要,但需要考虑。

如果您的机器上有GPU,一个简单的步骤就是将OpenCV与Cuda/OpenCL一起使用。@Zindarod我打开了所有建议,稍后可能会与OpenCL一起检查。我甚至考虑暂停游戏(抛出激活/停用窗口)以节省对象识别过程中的时间。几个月前,我正在做一个类似的项目,在opencv的帮助下使用Pyautogui玩霸王龙机器人。该程序可以得分500分左右,但屏幕截图技术的缓慢过程会导致机器人死亡。这是电话号码
# Finding only dino object based on Template.
# This might be optimized later with searching by contours

def find_dino__(self, cv2_image):
    result = cv2.matchTemplate(cv2_image.astype(np.uint8), self.dino_image, cv2.TM_CCOEFF)
    _, _, _, dino_top_left = cv2.minMaxLoc(result)
    dino_bottom_right = (dino_top_left[0] + self.dino_width, dino_top_left[1] + self.dino_height)
    return GenericGameObject(dino_top_left, dino_bottom_right)

# Find other Barrier Objects, based on position, and except
# that, which behind Dino location. Use Dino position.
def find_dino_barriers__(self, cv2_image, dino_object):
    img_fil = cv2.medianBlur(cv2.cvtColor(cv2_image, cv2.COLOR_BGR2GRAY), 13)
    img_th = cv2.adaptiveThreshold(img_fil, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
    im2, contours, hierarchy = cv2.findContours(img_th, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)

    objects = []
    for i in range(len(contours)):
        x, y, w, h = cv2.boundingRect(contours[i])
        if y < Settings.DINO_WORKING_Y_AREA[0] \
                or y > Settings.DINO_WORKING_Y_AREA[1]:
            continue
        if x <= dino_object.top_right_point[0]\
                and y <= dino_object.top_right_point[1]:
            continue
        objects.append(GenericGameObject((x, y), (x + w, y + h)))

    return objects