<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def click_image(self, pattern, timeout=20.0, action='click', safe=False, desc=None, delay=None, **match_kwargs):
 """Simulate click according image position Args: - pattern (str or Pattern):
 filename or an opencv image object. - timeout (float):
 if image not found during this time, ImageNotFoundError will raise. - action (str):
 click or long_click - safe (bool):
 if safe is True, Exception will not raise and return None instead. - method (str):
 image match method, choice of <template|sift> - delay (float):
 wait for a moment then perform click Returns: None Raises: ImageNotFoundError: An error occured when img not found in current screen. """

        pattern = self.pattern_open(pattern)
        log.info('click image:%s %s', desc or '', pattern)
        start_time = time.time()
        found = False
        point = None
        while time.time() - start_time < timeout:
            point = self.match(pattern, **match_kwargs)
            if point is None:
                sys.stdout.write('.')
                sys.stdout.flush()
                continue

            log.debug('confidence: %s', point.confidence)
            if not point.matched:
                log.info('Ignore confidence: %s', point.confidence)
                continue
            
            # wait for program ready
            if delay and delay > 0:
                self.delay(delay)

            func = getattr(self, action)
            func(*point.pos)

            found = True
            break
        sys.stdout.write('\n')

        if not found:
            if safe:
                log.info("Image(%s) not found, safe=True, skip", pattern)
                return None
            raise errors.ImageNotFoundError('Not found image %s' % pattern, point)

        # FIXME(ssx): maybe this function is too complex
        return point