def _match_auto(self, screen, search_img, threshold): """Maybe not a good idea """ # 1. try template first ret = ac.find_template(screen, search_img) if ret and ret['confidence'] > threshold: return FindPoint(ret['result'], ret['confidence'], consts.IMAGE_MATCH_METHOD_TMPL, matched=True) # 2. try sift ret = ac.find_sift(screen, search_img, min_match_count=10) if ret is None: return None matches, total = ret['confidence'] if 1.0*matches/total > 0.5: # FIXME(ssx): sift just write here return FindPoint(ret['result'], ret['confidence'], consts.IMAGE_MATCH_METHOD_SIFT, matched=True) return None
def match(self, pattern, screen=None, rect=None, offset=None, threshold=None, method=None): """Check if image position in screen Args: - pattern: Image file name or opencv image object - screen (PIL.Image): optional, if not None, screenshot method will be called - threshold (float): it depends on the image match method - method (string): choices on <template | sift> Returns: None or FindPoint, For example: FindPoint(pos=(20, 30), method='tmpl', confidence=0.801, matched=True) Only when confidence > self.image_match_threshold, matched will be True Raises: TypeError: when image_match_method is invalid """ pattern = self.pattern_open(pattern) search_img = pattern.image pattern_scale = self._cal_scale(pattern) if pattern_scale != 1.0: search_img = cv2.resize(search_img, (0, 0), fx=pattern_scale, fy=pattern_scale, interpolation=cv2.INTER_CUBIC) screen = screen or self.region_screenshot() threshold = threshold or pattern.threshold or self.image_match_threshold # handle offset if percent, ex (0.2, 0.8) dx, dy = offset or pattern.offset or (0, 0) dx = pattern.image.shape[1] * dx # opencv object width dy = pattern.image.shape[0] * dy # opencv object height dx, dy = int(dx*pattern_scale), int(dy*pattern_scale) # image match screen = imutils.from_pillow(screen) # convert to opencv image if rect and isinstance(rect, tuple) and len(rect) == 4: (x0, y0, x1, y1) = [int(v*pattern_scale) for v in rect] (dx, dy) = dx+x0, dy+y0 screen = imutils.crop(screen, x0, y0, x1, y1) #cv2.imwrite('cc.png', screen) match_method = method or self.image_match_method ret = None confidence = None matched = False position = None if match_method == consts.IMAGE_MATCH_METHOD_TMPL: #IMG_METHOD_TMPL ret = ac.find_template(screen, search_img) if ret is None: return None confidence = ret['confidence'] if confidence > threshold: matched = True (x, y) = ret['result'] position = (x+dx, y+dy) # fix by offset elif match_method == consts.IMAGE_MATCH_METHOD_SIFT: ret = ac.find_sift(screen, search_img, min_match_count=10) if ret is None: return None confidence = ret['confidence'] matches, total = confidence if 1.0*matches/total > 0.5: # FIXME(ssx): sift just write here matched = True (x, y) = ret['result'] position = (x+dx, y+dy) # fix by offset elif match_method == consts.IMAGE_MATCH_METHOD_AUTO: fp = self._match_auto(screen, search_img, threshold) if fp is None: return None (x, y) = fp.pos position = (x+dx, y+dy) return FindPoint(position, fp.confidence, fp.method, fp.matched) else: raise TypeError("Invalid image match method: %s" %(match_method,)) (x, y) = ret['result'] position = (x+dx, y+dy) # fix by offset if self.bounds: x, y = position position = (x+self.bounds.left, y+self.bounds.top) return FindPoint(position, confidence, match_method, matched=matched)
def match(self, pattern, screen=None, rect=None, offset=None, threshold=None, method=None): pattern = self.pattern_open(pattern) search_img = pattern.image pattern_scale = self._cal_scale(pattern) if pattern_scale != 1.0: search_img = cv2.resize(search_img, (0, 0), fx=pattern_scale, fy=pattern_scale, interpolation=cv2.INTER_CUBIC) screen = screen or self.region_screenshot() threshold = threshold or pattern.threshold or self.image_match_threshold # handle offset if percent, ex (0.2, 0.8) dx, dy = offset or pattern.offset or (0, 0) dx = pattern.image.shape[1] * dx # opencv object width dy = pattern.image.shape[0] * dy # opencv object height dx, dy = int(dx * pattern_scale), int(dy * pattern_scale) # image match screen = imutils.from_pillow(screen) # convert to opencv image if rect and isinstance(rect, tuple) and len(rect) == 4: (x0, y0, x1, y1) = [v * pattern_scale for v in rect] (dx, dy) = dx + x0, dy + y0 screen = imutils.crop(screen, x0, y0, x1, y1) # cv2.imwrite('cc.png', screen) match_method = method or self.image_match_method ret = None confidence = None matched = False if match_method == consts.IMAGE_MATCH_METHOD_TMPL: # IMG_METHOD_TMPL ret = ac.find_template(screen, search_img) if ret is None: return None confidence = ret['confidence'] if confidence > threshold: matched = True (x, y) = ret['result'] position = (x + dx, y + dy) # fix by offset else: ret_all = ac.find_all_template(screen, search_img, maxcnt=10) if not ret_all: return None for ret in ret_all: confidence = ret['confidence'] if confidence > threshold: (x, y) = ret['rectangle'][0] color_screen = screen[y, x, 2] color_img = search_img[0, 0, 2] if -10 < int(color_img) - int(color_screen) < 10: matched = True break (x, y) = ret['result'] position = (x + dx, y + dy) # fix by offset if self.bounds: x, y = position position = (x + self.bounds.left, y + self.bounds.top) return FindPoint(position, confidence, match_method, matched=matched)