在python中查找图像中的较小图像时出现CV2错误

时间:2013-05-05 08:50:08

标签: python numpy

这是一个简短的脚本,使用pyscreenshot(https://github.com/ponty/pyscreenshot)来获取屏幕图像,然后在其中查找较小的加载图像(本地文件' refresh.png',约32x32 px)

我需要在Chrome中复制标签,中间点击刷新才能完美无需重新加载。

当它到达手表的第二部分时,我收到错误C:\slave\WinInstallerMegaPack\src\opencv\modules\core\src\matrix.cpp:113: error: (-215) s >= 0。让整个屏幕检查工作,但只是屏幕的一部分然后检查是一个问题。即使在查看某些来源之后,我也不知道该错误意味着什么。在整个屏幕上查看' refresh.png'需要一点时间。然后它开始在部分屏幕screengrab检查失败,我无法弄清楚为什么或理解这个错误。只检查部分屏幕会更快。

从谷歌的唯一结果来看,我不得不猜测阵列中有太多变量,但我不知道怎么做。我添加了一些打印语句,显示问题是len 4的1个变量之前和之后的所有内容。

import Image, numpy
import cv2
import numpy as np
import pyscreenshot as ImageGrab
import os

from pymouse import PyMouse

from time import clock, sleep


def grabScreen(Bbox = None):  #unlike rect in pygame, bbox does top left (x,y), bottom right (x,y).  So the second x,y isn't width, height, it's width + x, height + y

    tempmousexy = m.position()  #get current mousexy
    m.move(0,0)                 #move pointer to the corner for screen shot  (change this if you put the refresh button in the very top left, weirdo

    if Bbox:
        screenshot = ImageGrab.grab(bbox=Bbox)  #grab part of screen
    else:
        screenshot = ImageGrab.grab()           #grab whole screen

    m.move(tempmousexy[0],tempmousexy[1])       #put mouse pointer back after screenshot

    return np.array(screenshot)


def saveScreen(savename = 'img.png'):  #not used right now, but a cool line
    ImageGrab.grab_to_file(savename)


def findMatch(img, template, closenesslimit = .001, method = cv2.TM_CCOEFF_NORMED):

    #convert to gray for faster processing - probably still accurate enough
    template = cv2.cvtColor(template, cv2.CV_32FC1)
    img = cv2.cvtColor(img, cv2.CV_32FC1)

    #check for match
    m = cv2.matchTemplate(template, img, cv2.cv.CV_TM_SQDIFF_NORMED)

    #we want the minimum squared difference - lower means less difference
    mn,_,mnLoc,_ = cv2.minMaxLoc(m)
    print 'RAW (best match, worst match, bestmXY, worstmXY):', str(cv2.minMaxLoc(m))

    #check if match is closer (less than) closenesslimit
    print 'Closest match (lower is better):', str(mn)
    if mn > closenesslimit: return False

    #else
    print '~Match found~  (closeness was better - less - than limit)'

    #find rectangle
    matchx, matchy = mnLoc
    matchw, matchh = template.shape[:2]

    print (matchx,matchy,matchx+matchw,matchy+matchh)   #checking what is about to be returned
    return (matchx,matchy,matchx+matchw,matchy+matchh)  #x1, y1, x2, y2


def checkScreen():
    print 'Checking whole screen'
    return findMatch(grabScreen(),templateimg)


def checkArea(checkrect):
    print 'Checking area'
    return findMatch(grabScreen(checkrect),templateimg)



global m

m = PyMouse()       #load PyMouse for mouse moves and position checks
guessxy = 0         #once a good x,y is detected, detection will start out there
startdelay = 3      #delay while waiting for first event
runningdelay = .2   #delay between repeating check events after first event

if os.name == 'nt':
    templateimg = cv2.imread('bensmall.png')
else:
    templateimg = cv2.imread('alexsmall.png')  #changes based on resolution, would be better if this scaled automatically based on screen res


print 'Global mouse set, small template (refresh button image) loaded'
while True:

    while not guessxy:  #check the whole screen until a location is found
        sleep(startdelay)
        guessxy = checkScreen()
        if not guessxy: print 'Nothing found yet, sleeping', str(startdelay)

    print 'GUESSXY:', str(guessxy)

    fails = 0
    faillimit = 5
    while guessxy:   #once location is found, guess near this area again
        sleep(runningdelay)  #sleep at the beginning avoids awkward pauses later when something is found but it has to sleep again before printing about it
        runstart = clock()
        temppos = m.position()
        print 'GUESSXY (limiting screenshot to this area):', str(guessxy)
        found = checkArea(guessxy)  #increase guessxy area by some small amount on each side later
        print found
        if found:
            guessxy = found
            print guessxy
            m.move(guessxy[0],guessxy[1])  #remove this line later
            print 'found'
        else:
            fails+=1
            print 'Not found,', str(fails)
            if fails>= faillimit:  #wasn't near the guess point, go back to checking whole screen
                print 'Too much fail, resetting...'
                guessxy = 0
        print clock()-runstart

0 个答案:

没有答案