How to use evaluatePreprocessFilter method in fMBT

Best Python code snippet using fMBT_python

eyenfinger.py

Source:eyenfinger.py Github

copy

Full Screen

...32python -c '33from eyenfinger import *34autoconfigure("screenshot.png", ["Try", "to", "find", "these", "words"])35'36evaluatePreprocessFilter() highlights words detected on given image. Example:37python -c '38from eyenfinger import *39evaluatePreprocessFilter("screenshot.png", "-sharpen 5 -resize 1600x", ["File", "View"])40'41setPreprocessFilter() sets given filter to be used when reading text from images.42Debugging43---------44iClickWord() capture parameter visualises coordinates to be clicked. Example:45python -c '46from eyenfinger import *47setPreprocessFilter("-sharpen 5 -filter Mitchell -resize 1600x -level 40%,50%,3.0")48iRead(source="screenshot.png")49iClickWord("[initial", clickPos=(-2,3), capture="highlight.png", dryRun=True)50'51"""52import distutils.sysconfig53import time54import subprocess55import re56import math57import htmlentitydefs58import sys59import os60import tempfile61import atexit62import shutil63import ctypes64import platform65import struct66import warnings67def _DEPRECATED():68 warnings.warn("eyenfinger.py API is deprecated, use fmbtx11 instead.",69 DeprecationWarning, stacklevel=2)70_g_preprocess = "-sharpen 5 -filter Mitchell -resize 1920x1600 -level 40%%,70%%,5.0 -sharpen 5"71_g_readImage = None72_g_origImage = None73_g_hocr = ""74_g_words = None75_g_lastWindow = None76_g_defaultClickDryRun = False77_g_defaultDelayedDrawing = False78_g_defaultIconMatch = 1.079_g_defaultIconColorMatch = 1.080_g_defaultIconOpacityLimit = 0.081_g_defaultInputKeyDevice = None82_g_defaultReadWithOCR = True83# windowsOffsets maps window-id to (x, y) pair.84_g_windowOffsets = {None: (0,0)}85# windowsSizes maps window-id to (width, height) pair.86_g_windowSizes = {None: (0,0)}87# screenSize is a (width, height) pair.88_g_screenSize = (0, 0)89_g_tempdir = tempfile.mkdtemp(prefix="eyenfinger.%s." % (os.getpid(),))90SCREENSHOT_FILENAME = _g_tempdir + "/screenshot.png"91LOG_FILENAME = _g_tempdir + "/eyenfinger.log"92MOUSEEVENT_MOVE, MOUSEEVENT_CLICK, MOUSEEVENT_DOWN, MOUSEEVENT_UP = range(4)93# Xkeys contains key names known to X11, see keysymdef.h.94Xkeys = [95 "BackSpace", "Tab", "Linefeed", "Clear", "Return", "Pause",96 "Scroll_Lock", "Sys_Req", "Escape", "Delete", "Home", "Left",97 "Up", "Right", "Down", "Prior", "Page_Up", "Next", "Page_Down",98 "End", "Begin", "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8",99 "F9", "F10", "F11", "F12", "Shift_L", "Shift_R", "Control_L",100 "Control_R", "Caps_Lock", "Shift_Lock", "Meta_L", "Meta_R",101 "Alt_L", "Alt_R", "space", "exclam", "quotedbl", "numbersign",102 "dollar", "percent", "ampersand", "apostrophe", "quoteright",103 "parenleft", "parenright", "asterisk", "plus", "comma", "minus",104 "period", "slash", "0", "1", "2", "3", "4", "5", "6", "7", "8",105 "9", "colon", "semicolon", "less", "equal", "greater", "question",106 "at", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L",107 "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y",108 "Z", "bracketleft", "backslash", "bracketright", "asciicircum",109 "underscore", "grave", "quoteleft", "a", "b", "c", "d", "e", "f",110 "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s",111 "t", "u", "v", "w", "x", "y", "z", "braceleft", "bar",112 "braceright"]113# InputKeys contains key names known to input devices, see114# linux/input.h or http://www.usb.org/developers/hidpage. The order is115# significant, because keyCode = InputKeys.index(keyName).116InputKeys = [117 "RESERVED", "ESC","1", "2", "3", "4", "5", "6", "7", "8", "9", "0",118 "MINUS", "EQUAL", "BACKSPACE", "TAB",119 "Q", "W", "E", "R", "T", "Y", "U", "I", "O", "P",120 "LEFTBRACE", "RIGHTBRACE", "ENTER", "LEFTCTRL",121 "A", "S", "D", "F", "G", "H", "J", "K", "L",122 "SEMICOLON", "APOSTROPHE", "GRAVE", "LEFTSHIFT", "BACKSLASH",123 "Z", "X", "C", "V", "B", "N", "M",124 "COMMA", "DOT", "SLASH", "RIGHTSHIFT", "KPASTERISK", "LEFTALT",125 "SPACE", "CAPSLOCK",126 "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F10",127 "NUMLOCK", "SCROLLLOCK",128 "KP7", "KP8", "KP9", "KPMINUS",129 "KP4", "KP5", "KP6", "KPPLUS",130 "KP1", "KP2", "KP3", "KP0", "KPDOT",131 "undefined0",132 "ZENKAKUHANKAKU", "102ND", "F11", "F12", "RO",133 "KATAKANA", "HIRAGANA", "HENKAN", "KATAKANAHIRAGANA", "MUHENKAN",134 "KPJPCOMMA", "KPENTER", "RIGHTCTRL", "KPSLASH", "SYSRQ", "RIGHTALT",135 "LINEFEED", "HOME", "UP", "PAGEUP", "LEFT", "RIGHT", "END", "DOWN",136 "PAGEDOWN", "INSERT", "DELETE", "MACRO",137 "MUTE", "VOLUMEDOWN", "VOLUMEUP",138 "POWER",139 "KPEQUAL", "KPPLUSMINUS", "PAUSE", "SCALE", "KPCOMMA", "HANGEUL",140 "HANGUEL", "HANJA", "YEN", "LEFTMETA", "RIGHTMETA", "COMPOSE"]141_inputKeyShorthands = {142 "-": "MINUS", "=": "EQUAL",143 "[": "LEFTBRACE", "]": "RIGHTBRACE", "\n": "ENTER",144 ";": "SEMICOLON",145 ",": "COMMA", ".": "DOT", "/": "SLASH",146 " ": "SPACE" }147class EyenfingerError(Exception):148 pass149class BadMatch (EyenfingerError):150 pass151class BadWindowName (EyenfingerError):152 pass153class BadSourceImage(EyenfingerError):154 pass155class BadIconImage(EyenfingerError):156 pass157class NoOCRResults(EyenfingerError):158 pass159try:160 import fmbt161 def _log(msg):162 fmbt.adapterlog("eyenfinger: %s" % (msg,))163except ImportError:164 def _log(msg):165 file(LOG_FILENAME, "a").write("%13.2f %s\n" %166 (time.time(), msg))167try:168 import ctypes169 _libpath = ["",170 ".",171 os.path.join(".", ".libs"),172 os.path.dirname(__file__),173 os.path.join(os.path.dirname(__file__), ".libs"),174 distutils.sysconfig.get_python_lib(plat_specific=1)]175 for _dirname in _libpath:176 try:177 eye4graphics = ctypes.CDLL(os.path.join(_dirname, "eye4graphics.so"))178 break179 except: pass180 else:181 raise ImportError("%s cannot load eye4graphics.so" % (__file__,))182 class Bbox(ctypes.Structure):183 _fields_ = [("left", ctypes.c_int32),184 ("top", ctypes.c_int32),185 ("right", ctypes.c_int32),186 ("bottom", ctypes.c_int32),187 ("error", ctypes.c_int32)]188except Exception, e:189 Bbox = None190 eye4graphics = None191 _log('Loading icon recognition library failed: "%s".' % (e,))192# See struct input_event in /usr/include/linux/input.h193if platform.architecture()[0] == "32bit":194 _InputEventStructSpec = 'IIHHi'195else:196 _InputEventStructSpec = 'QQHHi'197# Event and keycodes are in input.h, too.198_EV_KEY = 0x01199# _inputKeyNameCodeMap is a dictionary keyName -> keyCode200_inputKeyNameCodeMap = {}201for code, name in enumerate(InputKeys):202 _inputKeyNameCodeMap[name] = code203def _inputKeyNameToCode(keyName):204 if keyName in _inputKeyNameCodeMap:205 return _inputKeyNameCodeMap[keyName]206 elif keyName in _inputKeyShorthands:207 return _inputKeyNameCodeMap[_inputKeyShorthands[keyName]]208 else:209 raise ValueError('Invalid key name "%s"' % (keyName,))210def error(msg, exitstatus=1):211 sys.stderr.write("eyenfinger: %s\n" % (msg,))212 sys.exit(1)213def printEventsFromFile(filename):214 fd = os.open(filename, os.O_RDONLY)215 try:216 while 1:217 evString = os.read(fd, struct.calcsize(_InputEventStructSpec))218 if not evString: break219 tim, tus, typ, cod, val = struct.unpack(_InputEventStructSpec, evString)220 if cod < len(InputKeys):221 nam = InputKeys[cod]222 else:223 nam = "N/A"224 print "time: %8s, susc: %8s, type: %8s, keyCode: %5s name: %10s value: %8s" % \225 (tim, tus, typ, cod, nam, val)226 finally:227 os.close(fd)228def printEventsFromDevice(deviceName):229 devices = dict(_listInputDevices())230 if not deviceName in devices:231 error('Unknown device "%s". Available devices: %s' %232 (deviceName, sorted(devices.keys())))233 else:234 printEventsFromFile(devices[deviceName])235def _exitHandler():236 shutil.rmtree(_g_tempdir, ignore_errors=True)237atexit.register(_exitHandler)238def _runcmd(cmd):239 p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)240 output = p.stdout.read()241 exit_status = p.wait()242 if p.wait() != 0:243 _log("runcmd: " + cmd)244 _log("exit status: " + str(exit_status))245 _log("stdout: " + output)246 _log("stderr: " + p.stderr.read())247 else:248 p.stderr.read()249 return exit_status, output250def _runDrawCmd(inputfilename, cmd, outputfilename):251 if not _g_defaultDelayedDrawing:252 return _runcmd("convert %s %s %s" % (inputfilename, cmd, outputfilename))253 # Do delayed drawing to save test execution time. If the output254 # file does not exist, just copy inputfile to outputfile and start255 # logging delayed draw commands to256 # outputfile.delayeddraw. Otherwise append latest command to257 # outputfile.delayeddraw.258 delayedCmd = "convert %s %s %s\n" % (outputfilename, cmd, outputfilename)259 delayedDrawFilename = outputfilename + ".delayeddraw"260 try:261 if os.access(outputfilename, os.R_OK) == False:262 shutil.copy(inputfilename, outputfilename)263 file(delayedDrawFilename, "w").write(delayedCmd)264 else:265 file(delayedDrawFilename, "a").write(delayedCmd)266 except:267 _log("error on delayed drawing: %s" % (delayedCmd,))268 raise269 _log("delayed drawing: %s" % (delayedCmd,))270 return (0, "")271def _safeForShell(s):272 # convert all non-ascii and bad chars to _273 try: s = unicode(s, "utf-8")274 except: pass275 return ''.join([(c, "_")[ord(c)>128 or c in "'\"\\`"] for c in s])276def _coordsToInt((x,y), (width, height)=(None, None)):277 """278 Convert percentages to screen coordinates279 """280 if (width == None or height == None):281 width, height = screenSize()282 if 0.0 <= x <= 1.0 and type(x) == float:283 x = int(round(x * width))284 else:285 x = int(x)286 if 0.0 <= y <= 1.0 and type(y) == float:287 y = int(round(y * height))288 else:289 y = int(y)290 return (x, y)291def setPreprocessFilter(preprocess):292 global _g_preprocess293 _g_preprocess = preprocess294def iSetDefaultClickDryRun(dryRun):295 """296 Set the default value for optional dryRun parameter for iClick*297 functions.298 """299 global _g_defaultClickDryRun300 _g_defaultClickDryRun = dryRun301def iSetDefaultDelayedDrawing(delayedDrawing):302 """303 Set the default for delaying drawing operations on captured304 screenshots.305 If delayedDrawing == False, drawing actions on screenshots (like306 highlighting icon and clicked coordinates) takes place during the307 function execution (like iClickIcon).308 If delayedDrawing == True, the screenshot is saved without309 highlighted areas, and <screenshot filename>.delayeddraw file310 contains all draw commands that can be executed after the test311 run. This may save a lot test execution time and CPU on the device312 that runs eyenfinger.313 The default is False.314 """315 global _g_defaultDelayedDrawing316 _g_defaultDelayedDrawing = delayedDrawing317def iSetDefaultIconMatch(match):318 """319 Set the default icon matching value, ranging from 0 to 1. The320 value will be used in iClickIcon and iVerifyIcon, if the optional321 match parameter is omitted. Value 1.0 will use pixel-perfect322 matching (the default), values below 1.0 will use fuzzy matching.323 Fuzzy matching is EXPERIMENTAL.324 """325 global _g_defaultIconMatch326 _g_defaultIconMatch = match327def iSetDefaultIconColorMatch(colorMatch):328 """329 Set the default color matching value, ranging from 0 to 1. When330 using pixel-perfect matching this will allow given error in pixel331 colors.332 For instance, when comparing 24 bit RGB images, value 0.97 will333 allow 256 - int(256 * .97) = 8 difference on each color channel.334 """335 global _g_defaultIconColorMatch336 _g_defaultIconColorMatch = colorMatch337def iSetDefaultIconOpacityLimit(opacityLimit):338 """339 Set the default minimum opacity for pixels to be matched. Defaults340 to 0.0, all pixels are matched independently of their opacity.341 """342 global _g_defaultIconOpacityLimit343 _g_defaultIconOpacityLimit = opacityLimit344def iSetDefaultInputKeyDevice(deviceName):345 """346 Use deviceName as a default input device for iInputKey.347 iSetDefaultInputKeyDevice("/dev/input/event0")348 iInputKey(["enter"])349 """350 global _g_defaultInputKeyDevice351 _g_defaultInputKeyDevice = deviceName352def iSetDefaultReadWithOCR(ocr):353 """354 Set the default for using OCR when reading images or windows.355 """356 global _g_defaultReadWithOCR357 _g_defaultReadWithOCR = ocr358def screenSize():359 """360 Returns the size of the screen as a pair (width, height).361 """362 if _g_screenSize == (0, 0):363 _getScreenSize()364 return _g_screenSize365def windowSize():366 """367 Returns the size of the window as a pair (width, height).368 Choose a window first, for instance with iRead() or iUseWindow().369 """370 if _g_lastWindow == None:371 raise BadWindowName("undefined window")372 return _g_windowSizes[_g_lastWindow]373def windowXY():374 """375 Returns screen coordinates of the top-left corner of the window as376 a pair (x, y).377 Choose a window first, for instance with iRead() or iUseWindow().378 """379 if _g_lastWindow == None:380 raise BadWindowName("undefined window")381 return _g_windowOffsets[_g_lastWindow]382def imageSize(imageFilename):383 """384 Returns image size as pair (width, height).385 """386 struct_bbox = Bbox(0,0,0,0,0)387 err = eye4graphics.imageDimensions(ctypes.byref(struct_bbox),388 imageFilename)389 if err != 0:390 return None, None391 return struct_bbox.right, struct_bbox.bottom392def iRead(windowId = None, source = None, preprocess = None, ocr=None, capture=None, ocrArea=(0, 0, 1.0, 1.0), ocrPageSegModes=(3,)):393 """394 DEPRECATED - use fmbtx11.Screen.refreshScreenshot instead.395 Read the contents of the given window or other source. If neither396 of windowId or source is given, reads the contents of active397 window. iClickWord and iVerifyWord can be used after reading with398 OCR.399 Parameters:400 windowId id (0x....) or the title of the window to be read.401 Defaults to None.402 source name of the file to be read, for instance a screen403 capture. Defaults to None.404 preprocess preprocess specification to override the default405 that is set using setPreprocessFilter. Defaults406 to None. Set to "" to disable preprocessing before407 OCR.408 ocr words will be read using OCR if True409 (the default). Read object can be used with410 iClickIcon and iVerifyIcon without OCR, too.411 capture save image with read words highlighted to this412 file. Default: None (nothing is saved).413 ocrArea (top, left, right, bottom) coordinates -414 area of the image to be read with OCR.415 ocrPageSegModes416 tuple of integers, see tesseract -pagesegmodes417 Returns list of words detected by OCR from the read object.418 """419 global _g_hocr420 global _g_lastWindow421 global _g_words422 global _g_readImage423 global _g_origImage424 _g_words = None425 _g_readImage = None426 _g_origImage = None427 if ocr == None:428 ocr = _g_defaultReadWithOCR429 if not source:430 iUseWindow(windowId)431 # take a screenshot432 _runcmd("xwd -root -screen -out %s.xwd && convert %s.xwd -crop %sx%s+%s+%s +repage '%s'" %433 (SCREENSHOT_FILENAME, SCREENSHOT_FILENAME,434 _g_windowSizes[_g_lastWindow][0], _g_windowSizes[_g_lastWindow][1],435 _g_windowOffsets[_g_lastWindow][0], _g_windowOffsets[_g_lastWindow][1],436 SCREENSHOT_FILENAME))437 source = SCREENSHOT_FILENAME438 else:439 iUseImageAsWindow(source)440 _g_origImage = source441 orig_width, orig_height = _g_windowSizes[_g_lastWindow][0], _g_windowSizes[_g_lastWindow][1]442 x1, y1 = _coordsToInt(ocrArea[:2], (orig_width, orig_height))443 x2, y2 = _coordsToInt(ocrArea[2:], (orig_width, orig_height))444 if x2 <= x1 or y2 <= y1:445 raise EyenfingerError("Invalid area size: %s => %s" % (ocrArea, (x1, y1, x2, y2)))446 if orig_width <= 0 or orig_height <= 0:447 raise EyenfingerError("Invalid image size: %sx%s" % (orig_width, orig_height))448 if not ocr:449 if capture:450 drawWords(_g_origImage, capture, [], [])451 return []452 if preprocess == None:453 preprocess = _g_preprocess454 # convert to text455 _g_readImage = _g_origImage + "-pp.png"456 if ocrArea == (0, 0, 1.0, 1.0):457 croparea = ""458 wordXOffset = 0459 wordYOffset = 0460 else:461 croparea = "-crop %sx%s+%s+%s +repage" % (x2-x1, y2-y1, x1, y1)462 wordXOffset = x1463 wordYOffset = y1464 # rescale possible resize preprocessing parameter465 resize_m = re.search('-resize ([0-9]+)x([0-9]*)', preprocess)466 if resize_m:467 origXResize = int(resize_m.group(1))468 newXResize = int(origXResize/float(orig_width) * (x2-x1))469 preprocess = (preprocess[:resize_m.start()] +470 ("-resize %sx" % (newXResize,)) +471 preprocess[resize_m.end():])472 _g_words = {}473 for psm in ocrPageSegModes:474 cmd = "convert %s %s %s %s && tesseract %s %s -l eng -psm %s hocr" % (475 _g_origImage, croparea, preprocess, _g_readImage,476 _g_readImage, SCREENSHOT_FILENAME, psm)477 _, _g_hocr = _runcmd(cmd)478 hocr_filename = SCREENSHOT_FILENAME + ".html"479 if not os.access(hocr_filename, os.R_OK):480 raise NoOCRResults("HOCR output missing. Tesseract OCR 3.02 or greater required.")481 # store every word and its coordinates482 _g_words.update(_hocr2words(file(hocr_filename).read()))483 # convert word coordinates to the unscaled pixmap484 try:485 ocr_page_line = [line for line in file(hocr_filename).readlines() if "class='ocr_page'" in line][0]486 except IndexError:487 raise NoOCRResults("Could not read ocr_page class information from %s" % (hocr_filename,))488 scaled_width, scaled_height = re.findall('bbox 0 0 ([0-9]+)\s*([0-9]+)', ocr_page_line)[0]489 scaled_width, scaled_height = float(scaled_width) / (float(x2-x1)/orig_width), float(scaled_height) / (float(y2-y1)/orig_height)490 for word in sorted(_g_words.keys()):491 for appearance, (wordid, middle, bbox) in enumerate(_g_words[word]):492 _g_words[word][appearance] = \493 (wordid,494 (int(middle[0]/scaled_width * orig_width) + wordXOffset,495 int(middle[1]/scaled_height * orig_height) + wordYOffset),496 (int(bbox[0]/scaled_width * orig_width) + wordXOffset,497 int(bbox[1]/scaled_height * orig_height) + wordYOffset,498 int(bbox[2]/scaled_width * orig_width) + wordXOffset,499 int(bbox[3]/scaled_height * orig_height) + wordYOffset))500 _log('found "' + word + '": (' + str(bbox[0]) + ', ' + str(bbox[1]) + ')')501 if capture:502 drawWords(_g_origImage, capture, _g_words, _g_words)503 return sorted(_g_words.keys())504def iVerifyWord(word, match=0.33, appearance=1, capture=None):505 """506 DEPRECATED - use fmbtx11.Screen.verifyOcrText instead.507 Verify that word can be found from previously iRead() image.508 Parameters:509 word word that should be checked510 appearance if word appears many times, appearance to511 be clicked. Defaults to the first one.512 match minimum matching score513 capture save image with verified word highlighted514 to this file. Default: None (nothing is saved).515 Returns pair: ((score, matchingWord), (left, top, right, bottom)), where516 score score of found match (1.0 for perfect match)517 matchingWord corresponding word detected by OCR518 (left, top, right, bottom)519 bounding box of the word in read image520 Throws BadMatch error if word is not found.521 Throws NoOCRResults error if there are OCR results available522 on the current screen.523 """524 if _g_words == None:525 raise NoOCRResults('iRead has not been called with ocr=True')526 score, matching_word = findWord(word)527 if capture:528 drawWords(_g_origImage, capture, [word], _g_words)529 if score < match:530 raise BadMatch('No matching word for "%s". The best candidate "%s" with score %.2f, required %.2f' %531 (word, matching_word, score, match))532 return ((score, matching_word), _g_words[matching_word][appearance-1][2])533def iVerifyText(text, match=0.33, capture=None):534 """535 DEPRECATED - use fmbtx11.Screen.verifyOcrText instead.536 Verify that text can be found from previously iRead() image.537 Parameters:538 text multiple words that should be checked539 match minimum matching score540 capture save image with verified text highlighted541 to this file. Default: None (nothing is saved).542 Returns pair:543 ((score, matchingText), (left, top, right, bottom)), where544 score score of found match (1.0 for perfect match)545 matchingText corresponding text detected by OCR546 (left, top, right, bottom)547 bounding box of the text in read image548 Throws BadMatch error if text is not found.549 Throws NoOCRResults error if there are OCR results available550 on the current screen.551 """552 if _g_words == None:553 raise NoOCRResults('iRead has not been called with ocr=True')554 score_text_bbox_list = findText(text, match)555 if len(score_text_bbox_list) == 0:556 raise BadMatch('No match >= %s for text "%s"' % (score, text))557 score, text, bbox = score_text_box_list[0]558 if capture:559 drawBbox(_g_origImage, capture, bbox, "%.2f %s" % (score, text))560 return ((score, matching_text), bbox)561def iVerifyIcon(iconFilename, match=None, colorMatch=None, opacityLimit=None, capture=None, area=(0.0, 0.0, 1.0, 1.0), _origin="iVerifyIcon"):562 """563 DEPRECATED - use fmbtx11.Screen.verifyBitmap instead.564 Verify that icon can be found from previously iRead() image.565 Parameters:566 iconFilename name of the icon file to be searched for567 match minimum matching score between 0 and 1.0,568 1.0 is perfect match (default)569 colorMatch 1.0 (default) requires exact color match. Value570 below 1.0 defines maximum allowed color571 difference. See iSetDefaultIconColorMatch.572 opacityLimit 0.0 (default) requires exact color values573 independently of opacity. If lower than 1.0,574 pixel less opaque than given value are skipped575 in pixel perfect comparisons.576 capture save image with verified icon highlighted577 to this file. Default: None (nothing is saved).578 area rectangle (left, top, right, bottom). Search579 icon inside this rectangle only. Values can be580 absolute coordinates, or floats in range [0.0,581 1.0] that will be scaled to image dimensions.582 The default is (0.0, 0.0, 1.0, 1.0), that is583 full rectangle.584 Returns pair: (score, (left, top, right, bottom)), where585 score score of found match (1.0 for perfect match)586 (left, top, right, bottom)587 bounding box of found icon588 Throws BadMatch error if icon is not found.589 """590 if not eye4graphics:591 _log('ERROR: %s("%s") called, but eye4graphics not loaded.' % (_origin, iconFilename))592 raise EyenfingerError("eye4graphics not available")593 if not _g_origImage:594 _log('ERROR %s("%s") called, but source not defined (iRead not called).' % (_origin, iconFilename))595 raise BadSourceImage("Source image not defined, cannot search for an icon.")596 if not (os.path.isfile(iconFilename) and os.access(iconFilename, os.R_OK)):597 _log('ERROR %s("%s") called, but the icon file is not readable.' % (_origin, iconFilename))598 raise BadIconImage('Icon "%s" is not readable.' % (iconFilename,))599 if match == None:600 match = _g_defaultIconMatch601 if match > 1.0:602 _log('ERROR %s("%s"): invalid match value, must be below 1.0. ' % (_origin, iconFilename,))603 raise ValueError("invalid match value: %s, should be 0 <= match <= 1.0" % (match,))604 if colorMatch == None:605 colorMatch = _g_defaultIconColorMatch606 if not 0.0 <= colorMatch <= 1.0:607 _log('ERROR %s("%s"): invalid colorMatch value, must be between 0 and 1. ' % (_origin, iconFilename,))608 raise ValueError("invalid colorMatch value: %s, should be 0 <= colorMatch <= 1.0" % (colorMatch,))609 if opacityLimit == None:610 opacityLimit = _g_defaultIconOpacityLimit611 if not 0.0 <= opacityLimit <= 1.0:612 _log('ERROR %s("%s"): invalid opacityLimit value, must be between 0 and 1. ' % (_origin, iconFilename,))613 raise ValueError("invalid opacityLimit value: %s, should be 0 <= opacityLimit <= 1.0" % (opacityLimit,))614 if area[0] > area[2] or area[1] >= area[3]:615 raise ValueError("invalid area: %s, should be rectangle (left, top, right, bottom)" % (area,))616 leftTopRightBottomZero = (_coordsToInt((area[0], area[1]), windowSize()) +617 _coordsToInt((area[2], area[3]), windowSize()) +618 (0,))619 struct_area_bbox = Bbox(*leftTopRightBottomZero)620 struct_bbox = Bbox(0,0,0,0,0)621 threshold = int((1.0-match)*20)622 err = eye4graphics.findSingleIcon(ctypes.byref(struct_bbox),623 _g_origImage, iconFilename, threshold,624 ctypes.c_double(colorMatch),625 ctypes.c_double(opacityLimit),626 ctypes.byref(struct_area_bbox))627 bbox = (int(struct_bbox.left), int(struct_bbox.top),628 int(struct_bbox.right), int(struct_bbox.bottom))629 if err == -1 or err == -2:630 msg = '%s: "%s" not found, match=%.2f, threshold=%s, closest threshold %s.' % (631 _origin, iconFilename, match, threshold, int(struct_bbox.error))632 if capture:633 drawIcon(_g_origImage, capture, iconFilename, bbox, 'red')634 _log(msg)635 raise BadMatch(msg)636 elif err != 0:637 _log("%s: findSingleIcon returned %s" % (_origin, err,))638 raise BadMatch("%s not found, findSingleIcon returned %s." % (iconFilename, err))639 if threshold > 0:640 score = (threshold - int(struct_bbox.error)) / float(threshold)641 else:642 score = 1.0643 if capture:644 drawIcon(_g_origImage, capture, iconFilename, bbox, area=leftTopRightBottomZero[:4])645 return (score, bbox)646def iClickIcon(iconFilename, clickPos=(0.5,0.5), match=None,647 colorMatch=None, opacityLimit=None,648 mouseButton=1, mouseEvent=MOUSEEVENT_CLICK, dryRun=None, capture=None):649 """650 DEPRECATED - use fmbtx11.Screen.tapBitmap instead.651 Click coordinates relative to the given icon in previously iRead() image.652 Parameters:653 iconFilename read icon from this file654 clickPos position to be clicked,655 relative to word top-left corner of the bounding656 box around the word. X and Y units are relative657 to width and height of the box. (0,0) is the658 top-left corner, (1,1) is bottom-right corner,659 (0.5, 0.5) is the middle point (default).660 Values below 0 or greater than 1 click outside661 the bounding box.662 match 1.0 (default) requires exact match. Value below 1.0663 defines minimum required score for fuzzy matching664 (EXPERIMENTAL). See iSetDefaultIconMatch.665 colorMatch 1.0 (default) requires exact color match. Value666 below 1.0 defines maximum allowed color667 difference. See iSetDefaultIconColorMatch.668 opacityLimit 0.0 (default) requires exact color values669 independently of opacity. If lower than 1.0,670 pixel less opaque than given value are skipped671 in pixel perfect comparisons.672 mouseButton mouse button to be synthesized on the event, default is 1.673 mouseEvent event to be synthesized, the default is MOUSEEVENT_CLICK,674 others: MOUSEEVENT_MOVE, MOUSEEVENT_DOWN, MOUSEEVENT_UP.675 dryRun if True, does not synthesize events. Still returns676 coordinates of the clicked position and illustrates677 the clicked position on the capture image if678 given.679 capture name of file where image of highlighted icon and680 clicked point are saved.681 Returns pair (score, (clickedX, clickedY)), where682 score score of found match (1.0 for perfect match)683 (clickedX, clickedY)684 X and Y coordinates of clicked position on the685 screen.686 Throws BadMatch error if could not find a matching word.687 """688 _DEPRECATED()689 score, bbox = iVerifyIcon(iconFilename, match=match,690 colorMatch=colorMatch, opacityLimit=opacityLimit,691 capture=capture, _origin="iClickIcon")692 clickedXY = iClickBox(bbox, clickPos, mouseButton, mouseEvent, dryRun,693 capture, _captureText = iconFilename)694 return (score, clickedXY)695def iClickWord(word, appearance=1, clickPos=(0.5,0.5), match=0.33,696 mouseButton=1, mouseEvent=1, dryRun=None, capture=None):697 """698 DEPRECATED - use fmbtx11.Screen.tapOcrText instead.699 Click coordinates relative to the given word in previously iRead() image.700 Parameters:701 word word that should be clicked702 appearance if word appears many times, appearance to703 be clicked. Defaults to the first one.704 clickPos position to be clicked,705 relative to word top-left corner of the bounding706 box around the word. X and Y units are relative707 to width and height of the box. (0,0) is the708 top-left corner, (1,1) is bottom-right corner,709 (0.5, 0.5) is the middle point (default).710 Values below 0 or greater than 1 click outside711 the bounding box.712 capture name of file where image of highlighted word and713 clicked point are saved.714 Returns pair: ((score, matchingWord), (clickedX, clickedY)), where715 score score of found match (1.0 for perfect match)716 matchingWord corresponding word detected by OCR717 (clickedX, clickedY)718 X and Y coordinates of clicked position on the719 screen.720 Throws BadMatch error if could not find a matching word.721 Throws NoOCRResults error if there are OCR results available722 on the current screen.723 """724 _DEPRECATED()725 (score, matching_word), bbox = iVerifyWord(word, appearance=appearance, match=match, capture=False)726 clickedX, clickedY = iClickBox(bbox, clickPos, mouseButton, mouseEvent, dryRun, capture=False)727 windowId = _g_lastWindow728 _log('iClickWord("%s"): word "%s", match %.2f, bbox %s, window offset %s, click %s' %729 (word, matching_word, score,730 bbox, _g_windowOffsets[windowId],731 (clickedX, clickedY)))732 if capture:733 drawWords(_g_origImage, capture, [word], _g_words)734 drawClickedPoint(capture, capture, (clickedX, clickedY))735 return ((score, matching_word), (clickedX, clickedY))736def iClickBox((left, top, right, bottom), clickPos=(0.5, 0.5),737 mouseButton=1, mouseEvent=1, dryRun=None,738 capture=None, _captureText=None):739 """740 DEPRECATED - use fmbtx11.Screen.tapItem instead.741 Click coordinates relative to the given bounding box, default is742 in the middle of the box.743 Parameters:744 (left, top, right, bottom)745 coordinates of the box inside the window.746 (0, 0) is the top-left corner of the window.747 clickPos (offsetX, offsetY) position to be clicked,748 relative to the given box. (0, 0) is the749 top-left, and (1.0, 1.0) is the lower-right750 corner of the box. The default is (0.5, 0.5),751 that is, the middle point of the box. Values752 smaller than 0 and bigger than 1 are allowed,753 too.754 mouseButton mouse button to be synthesized on the event, default is 1.755 mouseEvent event to be synthesized, the default is MOUSEEVENT_CLICK,756 others: MOUSEEVENT_MOVE, MOUSEEVENT_DOWN, MOUSEEVENT_UP.757 dryRun if True, does not synthesize events. Still returns758 coordinates of the clicked position and illustrates759 the clicked position on the capture image if760 given.761 capture name of file where the last screenshot with762 clicked point highlighted is saved. The default763 is None (nothing is saved).764 Returns pair (clickedX, clickedY)765 X and Y coordinates of clicked position on the766 screen.767 """768 clickWinX = int(left + clickPos[0]*(right-left))769 clickWinY = int(top + clickPos[1]*(bottom-top))770 (clickedX, clickedY) = iClickWindow((clickWinX, clickWinY),771 mouseButton, mouseEvent,772 dryRun, capture=False)773 if capture:774 if _captureText == None:775 _captureText = "Box: %s, %s, %s, %s" % (left, top, right, bottom)776 drawIcon(_g_origImage, capture, _captureText, (left, top, right, bottom))777 drawClickedPoint(capture, capture, (clickedX, clickedY))778 return (clickedX, clickedY)779def iClickWindow((clickX, clickY), mouseButton=1, mouseEvent=1, dryRun=None, capture=None):780 """781 DEPRECATED - use fmbtx11.Screen.tap instead.782 Click given coordinates in the window.783 Parameters:784 (clickX, clickY)785 coordinates to be clicked inside the window.786 (0, 0) is the top-left corner of the window.787 Integer values are window coordinates. Floating788 point values from 0.0 to 1.0 are scaled to window789 coordinates: (0.5, 0.5) is the middle of the790 window, and (1.0, 1.0) the bottom-right corner of791 the window.792 mouseButton mouse button to be synthesized on the event, default is 1.793 mouseEvent event to be synthesized, the default is MOUSEEVENT_CLICK,794 others: MOUSEEVENT_MOVE, MOUSEEVENT_DOWN, MOUSEEVENT_UP.795 dryRun if True, does not synthesize events. Still796 illustrates the clicked position on the capture797 image if given.798 capture name of file where the last screenshot with799 clicked point highlighted is saved. The default800 is None (nothing is saved).801 Returns pair (clickedX, clickedY)802 X and Y coordinates of clicked position on the803 screen.804 """805 # Get the size of the window806 wndSize = windowSize()807 (clickX, clickY) = _coordsToInt((clickX, clickY), wndSize)808 # Get the position of the window809 wndPos = windowXY()810 # If coordinates are given as percentages, convert to window coordinates811 clickScrX = clickX + wndPos[0]812 clickScrY = clickY + wndPos[1]813 iClickScreen((clickScrX, clickScrY), mouseButton, mouseEvent, dryRun, capture)814 return (clickScrX, clickScrY)815def iClickScreen((clickX, clickY), mouseButton=1, mouseEvent=1, dryRun=None, capture=None):816 """817 DEPRECATED - use fmbtx11.Screen.tap instead.818 Click given absolute coordinates on the screen.819 Parameters:820 (clickX, clickY)821 coordinates to be clicked on the screen. (0, 0)822 is the top-left corner of the screen. Integer823 values are screen coordinates. Floating point824 values from 0.0 to 1.0 are scaled to screen825 coordinates: (0.5, 0.5) is the middle of the826 screen, and (1.0, 1.0) the bottom-right corner of827 the screen.828 mouseButton mouse button to be synthesized on the event, default is 1.829 mouseEvent event to be synthesized, the default is MOUSEEVENT_CLICK,830 others: MOUSEEVENT_MOVE, MOUSEEVENT_DOWN, MOUSEEVENT_UP.831 dryRun if True, does not synthesize events. Still832 illustrates the clicked position on the capture833 image if given.834 capture name of file where the last screenshot with835 clicked point highlighted is saved. The default836 is None (nothing is saved).837 """838 _DEPRECATED()839 if mouseEvent == MOUSEEVENT_CLICK:840 params = "'mouseclick %s'" % (mouseButton,)841 elif mouseEvent == MOUSEEVENT_DOWN:842 params = "'mousedown %s'" % (mouseButton,)843 elif mouseEvent == MOUSEEVENT_UP:844 params = "'mouseup %s'" % (mouseButton,)845 else:846 params = ""847 clickX, clickY = _coordsToInt((clickX, clickY))848 if capture:849 drawClickedPoint(_g_origImage, capture, (clickX, clickY))850 if dryRun == None:851 dryRun = _g_defaultClickDryRun852 if not dryRun:853 # use xte from the xautomation package854 _runcmd("xte 'mousemove %s %s' %s" % (clickX, clickY, params))855def iGestureScreen(listOfCoordinates, duration=0.5, holdBeforeGesture=0.0, holdAfterGesture=0.0, intermediatePoints=0, capture=None, dryRun=None):856 """857 DEPRECATED - use fmbtx11.Screen.drag instead.858 Synthesizes a gesture on the screen.859 Parameters:860 listOfCoordinates861 The coordinates through which the cursor moves.862 Integer values are screen coordinates. Floating863 point values from 0.0 to 1.0 are scaled to screen864 coordinates: (0.5, 0.5) is the middle of the865 screen, and (1.0, 1.0) the bottom-right corner of866 the screen.867 duration gesture time in seconds, excluding868 holdBeforeGesture and holdAfterGesture times.869 holdBeforeGesture870 time in seconds to keep mouse down before the871 gesture.872 holdAfterGesture873 time in seconds to keep mouse down after the874 gesture.875 intermediatePoints876 the number of intermediate points to be added877 between each of the coordinates. Intermediate878 points are added to straight lines between start879 and end points.880 capture name of file where the last screenshot with881 the points through which the cursors passes is882 saved. The default is None (nothing is saved).883 dryRun if True, does not synthesize events. Still884 illustrates the coordinates through which the cursor885 goes.886 """887 _DEPRECATED()888 # The params list to be fed to xte889 params = []890 # The list of coordinates through which the cursor has to go891 goThroughCoordinates = []892 for pos in xrange(len(listOfCoordinates)):893 x, y = _coordsToInt(listOfCoordinates[pos])894 goThroughCoordinates.append((x,y))895 if pos == len(listOfCoordinates) - 1:896 break # last coordinate added897 nextX, nextY = _coordsToInt(listOfCoordinates[pos+1])898 (x,y), (nextX, nextY) = (x, y), (nextX, nextY)899 for ip in range(intermediatePoints):900 goThroughCoordinates.append(901 (int(round(x + (nextX-x)*(ip+1)/float(intermediatePoints+1))),902 int(round(y + (nextY-y)*(ip+1)/float(intermediatePoints+1)))))903 # Calculate the time (in micro seconds) to sleep between moves.904 if len(goThroughCoordinates) > 1:905 moveDelay = 1000000 * float(duration) / (len(goThroughCoordinates)-1)906 else:907 moveDelay = 0908 if not dryRun:909 # Build the params list.910 params.append("'mousemove %d %d'" % goThroughCoordinates[0])911 params.append("'mousedown 1 '")912 if holdBeforeGesture > 0:913 params.append("'usleep %d'" % (holdBeforeGesture * 1000000,))914 for i in xrange(1, len(goThroughCoordinates)):915 params.append("'usleep %d'" % (moveDelay,))916 params.append("'mousemove %d %d'" % goThroughCoordinates[i])917 if holdAfterGesture > 0:918 params.append("'usleep %d'" % (holdAfterGesture * 1000000,))919 params.append("'mouseup 1'")920 # Perform the gesture921 _runcmd("xte %s" % (" ".join(params),))922 if capture:923 intCoordinates = [ _coordsToInt(point) for point in listOfCoordinates ]924 drawLines(_g_origImage, capture, intCoordinates, goThroughCoordinates)925 return goThroughCoordinates926def iGestureWindow(listOfCoordinates, duration=0.5, holdBeforeGesture=0.0, holdAfterGesture=0.0, intermediatePoints=0, capture=None, dryRun=None):927 """928 DEPRECATED - use fmbtx11.Screen.drag instead.929 Synthesizes a gesture on the window.930 Parameters:931 listOfCoordinates932 The coordinates through which the cursor moves.933 Integer values are window coordinates. Floating934 point values from 0.0 to 1.0 are scaled to window935 coordinates: (0.5, 0.5) is the middle of the936 window, and (1.0, 1.0) the bottom-right corner of937 the window.938 duration gesture time in seconds, excluding939 holdBeforeGesture and holdAfterGesture times.940 holdBeforeGesture941 time in seconds to keep mouse down before the942 gesture.943 holdAfterGesture944 time in seconds to keep mouse down after the945 gesture.946 intermediatePoints947 the number of intermediate points to be added948 between each of the coordinates. Intermediate949 points are added to straight lines between start950 and end points.951 capture name of file where the last screenshot with952 the points through which the cursors passes is953 saved. The default is None (nothing is saved).954 dryRun if True, does not synthesize events. Still955 illustrates the coordinates through which the cursor956 goes.957 """958 screenCoordinates = [ _windowToScreen(*_coordsToInt((x,y),windowSize())) for (x,y) in listOfCoordinates ]959 return iGestureScreen(screenCoordinates, duration, holdBeforeGesture, holdAfterGesture, intermediatePoints, capture, dryRun)960def iType(word, delay=0.0):961 """962 DEPRECATED - use fmbtx11.Screen.type instead.963 Send keypress events.964 Parameters:965 word is either966 - a string containing letters and numbers.967 Each letter/number is using press and release events.968 - a list that contains969 - keys: each key is sent using press and release events.970 - (key, event)-pairs: the event (either "press" or "release")971 is sent.972 - (key1, key2, ..., keyn)-tuples. 2n events is sent:973 key1 press, key2 press, ..., keyn press,974 keyn release, ..., key2 release, key1 release.975 Keys are defined in eyenfinger.Xkeys, for complete list976 see keysymdef.h.977 delay is given as seconds between sent events978 Examples:979 iType('hello')980 iType([('Shift_L', 'press'), 'h', 'e', ('Shift_L', 'release'), 'l', 'l', 'o'])981 iType([('Control_L', 'Alt_L', 'Delete')])982 """983 _DEPRECATED()984 args = []985 for char in word:986 if type(char) == tuple:987 if char[1].lower() == 'press':988 args.append("'keydown %s'" % (char[0],))989 elif char[1].lower() == 'release':990 args.append("'keyup %s'" % (char[0],))991 else:992 rest = []993 for key in char:994 args.append("'keydown %s'" % (key,))995 rest.insert(0, "'keyup %s'" % (key,))996 args = args + rest997 else:998 # char is keyname or single letter/number999 args.append("'key %s'" % (char,))1000 usdelay = " 'usleep %s' " % (int(delay*1000000),)1001 _runcmd("xte %s" % (usdelay.join(args),))1002def iInputKey(*args, **kwargs):1003 """1004 DEPRECATED - use fmbtx11.Screen.pressKey instead.1005 Send keypresses using Linux evdev interface1006 (/dev/input/eventXX).1007 iInputKey(keySpec[, keySpec...], hold=<float>, delay=<float>, device=<str>)1008 Parameters:1009 keySpec is one of the following:1010 - a string of one-character-long key names:1011 "aesc" will send four keypresses: A, E, S and C.1012 - a list of key names:1013 ["a", "esc"] will send two keypresses: A and ESC.1014 Key names are listed in eyenfinger.InputKeys.1015 - an integer:1016 116 will press the POWER key.1017 - "_" or "^":1018 only press or release event will be generated1019 for the next key, respectively.1020 If a key name inside keySpec is prefixed by "_"1021 or "^", only press or release event is generated1022 for that key.1023 hold time (in seconds) to hold the key before1024 releasing. The default is 0.1.1025 delay delay (in seconds) after key release. The default1026 is 0.1.1027 device name of the input device or input event file to1028 which all key presses are sent. The default can1029 be set with iSetDefaultInputKeyDevice(). For1030 instance, "/dev/input/event0" or a name of a1031 device in /proc/bus/input/devices.1032 """1033 _DEPRECATED()1034 hold = kwargs.get("hold", 0.1)1035 delay = kwargs.get("delay", 0.1)1036 device = kwargs.get("device", _g_defaultInputKeyDevice)1037 inputKeySeq = []1038 press, release = 1, 11039 for a in args:1040 if a == "_": press, release = 1, 01041 elif a == "^": press, release = 0, 11042 elif type(a) == str:1043 for char in a:1044 if char == "_": press, release = 1, 01045 elif char == "^": press, release = 0, 11046 else:1047 inputKeySeq.append((press, release, _inputKeyNameToCode(char.upper())))1048 press, release = 1, 11049 elif type(a) in (tuple, list):1050 for keySpec in a:1051 if type(keySpec) == int:1052 inputKeySeq.append((press, release, keySpec))1053 press, release = 1, 11054 else:1055 if keySpec.startswith("_"):1056 press, release = 1, 01057 keySpec = keySpec[1:]1058 elif keySpec.startswith("^"):1059 press, release = 0, 11060 keySpec = keySpec[1:]1061 if keySpec:1062 inputKeySeq.append((press, release, _inputKeyNameToCode(keySpec.upper())))1063 press, release = 1, 11064 elif type(a) == int:1065 inputKeySeq.append((press, release, a))1066 press, release = 1, 11067 else:1068 raise ValueError('Invalid keySpec "%s"' % (a,))1069 if inputKeySeq:1070 _writeInputKeySeq(_deviceFilename(device), inputKeySeq, hold=hold, delay=delay)1071def _deviceFilename(deviceName):1072 if not _deviceFilename.deviceCache:1073 _deviceFilename.deviceCache = dict(_listInputDevices())1074 if not deviceName in _deviceFilename.deviceCache:1075 return deviceName1076 else:1077 return _deviceFilename.deviceCache[deviceName]1078_deviceFilename.deviceCache = {}1079def _listInputDevices():1080 nameAndFile = []1081 for l in file("/proc/bus/input/devices"):1082 if l.startswith("N: Name="):1083 nameAndFile.append([l.split('"')[1]])1084 elif l.startswith("H: Handlers=") and "event" in l:1085 try:1086 eventFilename = re.findall("(event[0-9]+)", l)[0]1087 nameAndFile[-1].append("/dev/input/%s" % (eventFilename,))1088 except:1089 _log('WARNING: Could not recognise event[0-9] filename from row "%s".' % (l.strip(),))1090 return nameAndFile1091def _writeInputKeySeq(filename, keyCodeSeq, hold=0.1, delay=0.1):1092 if type(filename) != str or len(filename) == 0:1093 raise ValueError('Invalid input device "%s"' % (filename,))1094 fd = os.open(filename, os.O_WRONLY | os.O_NONBLOCK)1095 for press, release, keyCode in keyCodeSeq:1096 if press:1097 bytes = os.write(fd, struct.pack(_InputEventStructSpec,1098 int(time.time()), 0, _EV_KEY, keyCode, 1))1099 if bytes > 0:1100 bytes += os.write(fd, struct.pack(_InputEventStructSpec,1101 0, 0, 0, 0, 0))1102 time.sleep(hold)1103 if release:1104 bytes += os.write(fd, struct.pack(_InputEventStructSpec,1105 int(time.time()), 0, _EV_KEY, keyCode, 0))1106 if bytes > 0:1107 bytes += os.write(fd, struct.pack(_InputEventStructSpec,1108 0, 0, 0, 0, 0))1109 time.sleep(delay)1110 os.close(fd)1111def findWord(word, detected_words = None, appearance=1):1112 """1113 Returns pair (score, corresponding-detected-word)1114 """1115 if detected_words == None:1116 detected_words = _g_words1117 if _g_words == None:1118 raise NoOCRResults()1119 scored_words = []1120 for w in detected_words:1121 scored_words.append((_score(w, word), w))1122 scored_words.sort()1123 if len(scored_words) == 0:1124 raise BadMatch("No words found.")1125 return scored_words[-1]1126def findText(text, detected_words = None, match=-1):1127 def biggerBox(bbox_list):1128 left, top, right, bottom = bbox_list[0]1129 for l, t, r, b in bbox_list[1:]:1130 left = min(left, l)1131 top = min(top, t)1132 right = max(right, r)1133 bottom = max(bottom, b)1134 return (left, top, right, bottom)1135 words = text.split()1136 word_count = len(words)1137 detected_texts = [] # strings of <word_count> words1138 if detected_words == None:1139 detected_words = _g_words1140 if _g_words == None:1141 raise NoOCRResults()1142 # sort by numeric word id1143 words_by_id = []1144 for word in detected_words:1145 for wid, middle, bbox in detected_words[word]:1146 words_by_id.append(1147 (int(wid.split("_")[1]), word, bbox))1148 words_by_id.sort()1149 for i in xrange(len(words_by_id)-word_count+1):1150 detected_texts.append(1151 (" ".join([w[1] for w in words_by_id[i:i+word_count]]),1152 biggerBox([w[2] for w in words_by_id[i:i+word_count]])))1153 norm_text = " ".join(words) # normalize whitespace1154 scored_texts = []1155 for t in detected_texts:1156 scored_texts.append((_score(t[0], norm_text), t[0], t[1]))1157 scored_texts.sort()1158 return [st for st in scored_texts if st[0] >= match]1159def _score(w1, w2):1160 closeMatch = {1161 '1l': 0.1,1162 '1I': 0.2,1163 'Il': 0.21164 }1165 def levenshteinDistance(w1, w2):1166 m = [range(len(w1)+1)]1167 for j in xrange(len(w2)+1):1168 m.append([])1169 m[-1].append(j+1)1170 i, j = 0, 01171 for j in xrange(1, len(w2)+1):1172 for i in xrange(1, len(w1)+1):1173 if w1[i-1] == w2[j-1]:1174 m[j].append(m[j-1][i-1])1175 else:1176 # This is not part of Levenshtein:1177 # if characters often look similar,1178 # don't add full edit distance (1.0),1179 # use the value in closeMatch instead.1180 chars = ''.join(sorted(w1[i-1] + w2[j-1]))1181 if chars in closeMatch:1182 m[j].append(m[j-1][i-1]+closeMatch[chars])1183 else:1184 # Standard Levenshtein continues...1185 m[j].append(min(1186 m[j-1][i] + 1, # delete1187 m[j][i-1] + 1, # insert1188 m[j-1][i-1] + 1 # substitute1189 ))1190 return m[j][i]1191 return 1 - (levenshteinDistance(w1, w2) / float(max(len(w1),len(w2))))1192def _hocr2words(hocr):1193 rv = {}1194 hocr = hocr.replace("<strong>","").replace("</strong>","").replace("<em>","").replace("</em>","")1195 hocr.replace("&#39;", "'")1196 for name, code in htmlentitydefs.name2codepoint.iteritems():1197 if code < 128:1198 hocr = hocr.replace('&' + name + ';', chr(code))1199 ocr_word = re.compile('''<span class=['"]ocrx?_word["'] id=['"]([^']*)["'] title=['"]bbox ([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)["'][^>]*>([^<]*)</span>''')1200 for word_id, bbox_left, bbox_top, bbox_right, bbox_bottom, word in ocr_word.findall(hocr):1201 bbox_left, bbox_top, bbox_right, bbox_bottom = \1202 int(bbox_left), int(bbox_top), int(bbox_right), int(bbox_bottom)1203 if not word in rv:1204 rv[word] = []1205 middle_x = (bbox_right + bbox_left) / 2.01206 middle_y = (bbox_top + bbox_bottom) / 2.01207 rv[word].append((word_id, (middle_x, middle_y),1208 (bbox_left, bbox_top, bbox_right, bbox_bottom)))1209 return rv1210def _getScreenSize():1211 global _g_screenSize1212 _, output = _runcmd("xwininfo -root | awk '/Width:/{w=$NF}/Height:/{h=$NF}END{print w\" \"h}'")1213 s_width, s_height = output.split(" ")1214 _g_screenSize = (int(s_width), int(s_height))1215def iUseWindow(windowIdOrName = None):1216 global _g_lastWindow1217 if windowIdOrName == None:1218 if _g_lastWindow == None:1219 _g_lastWindow = iActiveWindow()1220 elif windowIdOrName.startswith("0x"):1221 _g_lastWindow = windowIdOrName1222 else:1223 _g_lastWindow = _runcmd("xwininfo -name '%s' | awk '/Window id: 0x/{print $4}'" %1224 (windowIdOrName,))[1].strip()1225 if not _g_lastWindow.startswith("0x"):1226 raise BadWindowName('Cannot find window id for "%s" (got: "%s")' %1227 (windowIdOrName, _g_lastWindow))1228 _, output = _runcmd("xwininfo -id %s | awk '/Width:/{w=$NF}/Height:/{h=$NF}/Absolute upper-left X/{x=$NF}/Absolute upper-left Y/{y=$NF}END{print x\" \"y\" \"w\" \"h}'" %1229 (_g_lastWindow,))1230 offset_x, offset_y, width, height = output.split(" ")1231 _g_windowOffsets[_g_lastWindow] = (int(offset_x), int(offset_y))1232 _g_windowSizes[_g_lastWindow] = (int(width), int(height))1233 _getScreenSize()1234 return _g_lastWindow1235def iUseImageAsWindow(imageFilename):1236 global _g_lastWindow1237 global _g_screenSize1238 if not eye4graphics:1239 _log('ERROR: iUseImageAsWindow("%s") called, but eye4graphics not loaded.' % (imageFilename,))1240 raise EyenfingerError("eye4graphics not available")1241 if not os.access(imageFilename, os.R_OK):1242 raise BadSourceImage("The input file could not be read or not present.")1243 _g_lastWindow = imageFilename1244 imageWidth, imageHeight = imageSize(imageFilename)1245 if imageWidth == None:1246 _log('iUseImageAsWindow: Failed reading dimensions of image "%s".' % (imageFilename,))1247 raise BadSourceImage('Failed to read dimensions of "%s".' % (imageFilename,))1248 _g_windowOffsets[_g_lastWindow] = (0, 0)1249 _g_windowSizes[_g_lastWindow] = (imageWidth, imageHeight)1250 _g_screenSize = _g_windowSizes[_g_lastWindow]1251 return _g_lastWindow1252def iActiveWindow(windowId = None):1253 """ return id of active window, in '0x1d0f14' format """1254 if windowId == None:1255 _, output = _runcmd("xprop -root | awk '/_NET_ACTIVE_WINDOW\(WINDOW\)/{print $NF}'")1256 windowId = output.strip()1257 return windowId1258def drawBbox(inputfilename, outputfilename, bbox, caption):1259 """1260 Draw bounding box1261 """1262 if inputfilename == None:1263 return1264 draw_commands = ""1265 left, top, right, bottom = bbox1266 color = "green"1267 draw_commands += """ -stroke %s -fill blue -draw "fill-opacity 0.2 rectangle %s,%s %s,%s" """ % (1268 color, left, top, right, bottom)1269 draw_commands += """ -stroke none -fill %s -draw "text %s,%s '%s'" """ % (1270 color, left, top, _safeForShell(caption))1271 _runDrawCmd(inputfilename, draw_commands, outputfilename)1272def drawWords(inputfilename, outputfilename, words, detected_words):1273 """1274 Draw boxes around words detected in inputfilename that match to1275 given words. Result is saved to outputfilename.1276 """1277 if inputfilename == None:1278 return1279 draw_commands = ""1280 for w in words:1281 score, dw = findWord(w, detected_words)1282 left, top, right, bottom = detected_words[dw][0][2]1283 if score < 0.33:1284 color = "red"1285 elif score < 0.5:1286 color = "brown"1287 else:1288 color = "green"1289 draw_commands += """ -stroke %s -fill blue -draw "fill-opacity 0.2 rectangle %s,%s %s,%s" """ % (1290 color, left, top, right, bottom)1291 draw_commands += """ -stroke none -fill %s -draw "text %s,%s '%s'" """ % (1292 color, left, top, _safeForShell(w))1293 draw_commands += """ -stroke none -fill %s -draw "text %s,%s '%.2f'" """ % (1294 color, left, bottom+10, score)1295 _runDrawCmd(inputfilename, draw_commands, outputfilename)1296def drawIcon(inputfilename, outputfilename, iconFilename, bboxes, color='green', area=None):1297 if inputfilename == None:1298 return1299 if type(bboxes) == tuple:1300 bboxes = [bboxes]1301 show_number = False1302 else:1303 show_number = True1304 draw_commands = ""1305 for index, bbox in enumerate(bboxes):1306 left, top, right, bottom = bbox[0], bbox[1], bbox[2], bbox[3]1307 draw_commands += """ -stroke %s -fill blue -draw "fill-opacity 0.2 rectangle %s,%s %s,%s" """ % (color, left, top, right, bottom)1308 if show_number:1309 caption = "%s %s" % (index+1, iconFilename)1310 else:1311 caption = iconFilename1312 draw_commands += """ -stroke none -fill %s -draw "text %s,%s '%s'" """ % (1313 color, left, top, caption)1314 if area != None:1315 draw_commands += """ -stroke yellow -draw "fill-opacity 0.0 rectangle %s,%s %s,%s" """ % (area[0]-1, area[1]-1, area[2], area[3])1316 _runDrawCmd(inputfilename, draw_commands, outputfilename)1317def drawClickedPoint(inputfilename, outputfilename, clickedXY):1318 """1319 clickedXY contains absolute screen coordinates1320 """1321 if inputfilename == None:1322 return1323 x, y = clickedXY1324 x -= _g_windowOffsets[_g_lastWindow][0]1325 y -= _g_windowOffsets[_g_lastWindow][1]1326 draw_commands = """ -stroke red -fill blue -draw "fill-opacity 0.2 circle %s,%s %s,%s" """ % (1327 x, y, x + 20, y)1328 draw_commands += """ -stroke none -fill red -draw "point %s,%s" """ % (x, y)1329 _runDrawCmd(inputfilename, draw_commands, outputfilename)1330def _screenToWindow(x,y):1331 """1332 Converts from absolute coordinats to window coordinates1333 """1334 offsetX = _g_windowOffsets[_g_lastWindow][0]1335 offsetY = _g_windowOffsets[_g_lastWindow][1]1336 return (x-offsetX, y-offsetY)1337def _windowToScreen(x,y):1338 """1339 Converts from window coordinates to screen coordinates1340 """1341 offsetX = _g_windowOffsets[_g_lastWindow][0]1342 offsetY = _g_windowOffsets[_g_lastWindow][1]1343 return (x+offsetX, y+offsetY)1344def drawLines(inputfilename, outputfilename, orig_coordinates, final_coordinates):1345 """1346 coordinates contains the coordinates connected by lines1347 """1348 if inputfilename == None:1349 return1350 # The command which will be run1351 drawCommand = ''1352 for pos in xrange(len(final_coordinates)-1):1353 # Get the pair coordinates1354 (x, y) = (final_coordinates[pos][0], final_coordinates[pos][1])1355 (nextX, nextY) = (final_coordinates[pos+1][0], final_coordinates[pos+1][1])1356 # Convert to window coordinates1357 (drawX, drawY) = _screenToWindow(x,y)1358 (drawnextX, drawnextY) = _screenToWindow(nextX, nextY)1359 # Draw a pair of circles. User-given points are blue1360 if (x, y) in orig_coordinates:1361 drawCommand += "-fill blue -stroke red -draw 'fill-opacity 0.2 circle %d, %d %d, %d' " % (drawX, drawY, drawX-5, drawY-5)1362 # Computer-generated points are white1363 else:1364 drawCommand += "-fill white -stroke red -draw 'fill-opacity 0.2 circle %d, %d %d, %d' " % (drawX, drawY, drawX-5, drawY-5)1365 # Draw the line between the points1366 drawCommand += "-stroke black -draw 'line %d, %d, %d, %d' " % (drawX, drawY, drawnextX, drawnextY)1367 if len(final_coordinates) > 0:1368 lastIndex = len(final_coordinates)-11369 (finalX, finalY) = _screenToWindow(final_coordinates[lastIndex][0], final_coordinates[lastIndex][1])1370 drawCommand += "-fill blue -stroke red -draw 'fill-opacity 0.2 circle %d, %d %d, %d' " % (finalX, finalY, finalX-5, finalY-5)1371 _runDrawCmd(inputfilename, drawCommand, outputfilename)1372def evaluatePreprocessFilter(imageFilename, ppfilter, words):1373 """1374 Visualise how given words are detected from given image file when1375 using given preprocessing filter.1376 """1377 global _g_preprocess1378 evaluatePreprocessFilter.count += 11379 preprocessed_filename = '%s-pre%s.png' % (imageFilename, evaluatePreprocessFilter.count)1380 _runcmd("convert '%s' %s '%s' && tesseract %s eyenfinger.autoconfigure hocr" %1381 (imageFilename, ppfilter, preprocessed_filename,1382 preprocessed_filename))1383 detected_words = _hocr2words(file("eyenfinger.autoconfigure.html").read())1384 scored_words = []1385 for w in words:1386 try:1387 score, word = findWord(w, detected_words)1388 except BadMatch:1389 return1390 scored_words.append((score, word, w))1391 scored_words.sort()1392 avg_score = sum([s[0] for s in scored_words])/float(len(scored_words))1393 evaluatePreprocessFilter.scores.append( (scored_words[0][0] + avg_score, scored_words[0][0], avg_score, ppfilter) )1394 evaluatePreprocessFilter.scores.sort()1395 # set the best preprocess filter so far as a default1396 _g_preprocess = evaluatePreprocessFilter.scores[-1][-1]1397 drawWords(preprocessed_filename, preprocessed_filename, words, detected_words)1398 sys.stdout.write("%.2f %s %s %s\n" % (sum([s[0] for s in scored_words])/float(len(scored_words)), scored_words[0], preprocessed_filename, ppfilter))1399 sys.stdout.flush()1400evaluatePreprocessFilter.count = 01401evaluatePreprocessFilter.scores = []1402def autoconfigure(imageFilename, words):1403 """1404 Search for image preprocessing configuration that will maximise1405 the score of finding given words in the image.1406 Returns configuration as a string.1407 """1408 # check image width1409 iUseImageAsWindow(imageFilename)1410 image_width = _g_windowSizes[_g_lastWindow][0]1411 resize_filters = ['Mitchell', 'Catrom', 'Hermite', 'Gaussian']1412 levels = [(20, 20), (50, 50), (80, 80), (5, 5), (95, 95),1413 (30, 30), (40, 40), (60, 60), (70, 70), (60, 60),1414 (10, 30), (30, 50), (50, 70), (70, 90), (80, 100)]1415 zoom = [1, 2]1416 for f in resize_filters:1417 for z in zoom:1418 for blevel, wlevel in levels:1419 evaluatePreprocessFilter(1420 imageFilename,1421 "-sharpen 5 -level %s%%,%s%%,3.0 -sharpen 5" % (blevel, wlevel),1422 words)1423 evaluatePreprocessFilter(1424 imageFilename,1425 "-sharpen 5 -filter %s -resize %sx -sharpen 5 -level %s%%,%s%%,3.0 -sharpen 5" % (f, z * image_width, blevel, wlevel),1426 words)1427 evaluatePreprocessFilter(1428 imageFilename,1429 "-sharpen 5 -filter %s -resize %sx -level %s%%,%s%%,3.0 -sharpen 5" % (1430 f, z * image_width, blevel, wlevel),1431 words)1432 evaluatePreprocessFilter(1433 imageFilename,1434 "-sharpen 5 -filter %s -resize %sx -level %s%%,%s%%,3.0" % (1435 f, z * image_width, blevel, wlevel),1436 words)1437 evaluatePreprocessFilter(1438 imageFilename,1439 "-sharpen 5 -level %s%%,%s%%,3.0 -filter %s -resize %sx -sharpen 5" % (1440 blevel, wlevel, f, z * image_width),1441 words)1442 evaluatePreprocessFilter(1443 imageFilename,1444 "-sharpen 5 -level %s%%,%s%%,1.0 -filter %s -resize %sx" % (1445 blevel, wlevel, f, z * image_width),1446 words)1447 evaluatePreprocessFilter(1448 imageFilename,1449 "-sharpen 5 -level %s%%,%s%%,10.0 -filter %s -resize %sx" % (1450 blevel, wlevel, f, z * image_width),...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run fMBT automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful