Exemplo n.º 1
0
    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
Exemplo n.º 2
0
    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)
Exemplo n.º 3
0
    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)