0 Replies - 592 Views - Last Post: 05 May 2013 - 02:04 AM Rate Topic: -----

#1 witeboy724  Icon User is offline

  • New D.I.C Head

Reputation: 6
  • View blog
  • Posts: 35
  • Joined: 21-June 12

CV2 (error -215) while comparing images

Posted 05 May 2013 - 02:04 AM

This is a short script using pyscreenshot (https://github.com/ponty/pyscreenshot) to get the screen image then looks for a smaller loaded image (local file 'refresh.png', about 32x32 px) inside of it.

I need to duplicate tabs in Chrome and middle clicking refresh does this wonderfully without any reloads.

I get error "C:\slave\WinInstallerMegaPack\src\opencv\modules\core\src\matrix.cpp:113: error: (-215) s >= 0" when it gets to second part of the watch. Getting the whole screen the checking works, but getting just part of the screen then checking is a problem. I have no idea what that error means, even after looking at some source. Checking the whole screen for 'refresh.png' takes a bit over a second. Afterwards it starts failing on the partial screen screengrab check and I can't figure out why or understand this error. Checking just part of the screen would go much faster.

From the only results on Google I'd have to guess that the array has too many variables, but I don't get how. I added some print statements that show everything before and after the problem is 1 variable of len 4.


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):  #bbox is 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 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)  #not a pygame rect! - 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





Is This A Good Question/Topic? 0
  • +

Page 1 of 1