예제 #1
0
def grab_proc(url, rate, camera_id):
    '''
    抓图处理进程
    :param url:
    :param rate:
    :param camera_id:
    :param logger:
    :return:
    '''
    logger = Log('grab-proc' + str(os.getpid()), 'logs/')
    logger.info('初始化seaweedfs')
    master = WeedClient(config.get('weed', 'host'),
                        config.getint('weed', 'port'))
    logger.info('初始化Kafka')
    kafka = Kafka(bootstrap_servers=config.get('kafka', 'boot_servers'))
    topic = config.get('camera', 'topic')
    face_tool = Face(config.get('api', 'face_server'))
    detect_count = 0  # 用于detect频次计数
    frame_internal = track_internal * rate
    trackable = False

    # 启动抓图线程
    q = queue.Queue(maxsize=100)
    t = GrabJob(q, camera_id, url, rate,
                Log('grab-proc' + str(os.getpid()) + '-thread', 'logs/'),
                config)
    t.start()

    while True:
        try:
            img = q.get(timeout=20)
            if detect_count % frame_internal == 0:
                detect_count = 0
                b64 = mat_to_base64(img)
                t1 = time.time()
                detect_result = face_tool.detect(b64)
                logger.info('detect cost time: ',
                            round((time.time() - t1) * 1000), 'ms')
                if detect_result['error_message'] != '601':
                    logger.warning('verifier detector error, error_message:',
                                   detect_result['error_message'])
                    continue
                tracker = cv2.MultiTracker_create()
                latest_imgs = []
                timestamp = round(time.time())
                for face_num in range(detect_result['detect_nums']):
                    tmp = detect_result['detect'][face_num]
                    bbox = (tmp['left'], tmp['top'], tmp['width'],
                            tmp['height'])
                    tracker.add(cv2.TrackerKCF_create(), img, bbox)
                    face_b64 = face_tool.crop(bbox[0], bbox[1], bbox[2],
                                              bbox[3], b64, True)
                    latest_img = {
                        'image_base64': face_b64,
                        'bbox': bbox,
                        'landmark':
                        detect_result['detect'][face_num]['landmark'],
                        'time': timestamp
                    }
                    # 增加人脸质量过滤
                    if tmp['sideFace'] == 0 and tmp[
                            'quality'] == 1 and tmp['score'] > 0.95:
                        latest_imgs.append(latest_img)
                if len(latest_imgs) > 0:
                    trackable = True
                else:
                    trackable = False

            elif trackable:
                # 开始追踪
                ok, bboxs = tracker.update(img)
                if ok and detect_count < frame_internal - 1:
                    if detect_count % 10 == 0:
                        logger.info('tracking..., detect_count = %d' %
                                    detect_count)
                    detect_count += 1
                    continue
                else:
                    # 取detect到的人脸
                    logger.info('tracking over! detect_count = %d' %
                                detect_count)
                    for latest in latest_imgs:
                        logger.info([camera_id], 'track person success!')
                        face_b64 = latest['image_base64']

                        # save img to seaweed fs
                        logger.info([camera_id],
                                    'save grabbed detect_result to seaweed fs')
                        assign = master.assign()
                        logger.info([camera_id], 'assign result:', assign)

                        ret = master.upload(assign['url'], assign['fid'],
                                            base64_to_bytes(face_b64),
                                            assign['fid'] + '.jpg')
                        logger.info([camera_id], 'upload result:', ret)

                        # send to Kafka
                        url = 'http' + ':' + '//' + assign[
                            'url'] + '/' + assign['fid']
                        logger.info('[', camera_id, ']', 'img url:', url)
                        msg = json.dumps({
                            'url': url,
                            'time': latest['time'],
                            'camera_id': camera_id,
                            'landmark': latest['landmark']
                        })
                        logger.info([camera_id], 'send to kafka: ', msg)
                        kafka.send(topic, msg)
                    # 再次进入detect
                    detect_count = 0
                    trackable = False
                    logger.info('restart detection')
            else:
                if detect_count % 10 == 0:
                    logger.info('detect 0 detect_result, do not track',
                                'detect count= ', detect_count)
                detect_count += 1
                continue
        except queue.Empty:
            logger.error('grab queue empty error, exit')
            break
        detect_count += 1
    logger.info('抓图进程终止')
예제 #2
0
class AutoHelper(object):
    def __init__(self, config_name='sample_config', *args):
        try:
            # Get the current abspath
            self.path = getcwd()

            # Instantiate util.Log module
            self.log = Log()

            # Import config file
            self.config = importlib.import_module(config_name,
                                                  package='AutoHelper')
            self.log.info(f'Import config success: {config_name}.py.')
            if not self.__verify_config():
                self.log.warning(
                    'Config file is not compliant. Missing args will be blank.'
                )

            # Instantiate util.ADB_client to interact with emulator
            self.adb = ADBClient(self.config.ADB_root, self.config.ADB_host)

            # Instantiate util.Ocr to interact with Baidu-api
            self.ocr = Ocr(self.config.APP_ID, self.config.API_KEY,
                           self.config.SECRET_KEY)

            # Initialize
            with open('ingame.json', mode='r') as file:
                self.ingame = json.load(file)
            self.initialize()

        except ImportError as e:
            self.log.critical(f'Import config error:', e)
        except ADBError as e:
            self.log.critical(f'ADB Error:', e)
        except OCRError as e:
            self.log.critical(f'Connecting to Baidu-api error:', e)
        except Exception as e:
            self.log.warning('Unknown Error:', e)

    # Initializers
    def initialize(self):
        """
        Initialize in-game info (Includes window size, click positions etc.)
        And save into ingame.json
        :return: None
        """
        def homepage():
            self.log.info(
                "Please go to home page, when finished, input anything below:")
            self.log.input()
            self.log.info("Start recognizing...")
            with self.adb.screen_shot(screenshot_path):
                pic_content = self.ocr.scan(screenshot_path)
            if pic_content['flag']['is_homepage'] == 'TRUE':
                self.ingame['location']['homepage_strength'] = pic_content[
                    'location']['strength']
                self.log.info('Done')
            else:
                raise AutoHelperError('Incorrect page')

        def mission_page():
            self.log.info(
                "Please go to mission page (anyone with '开始行动' button), "
                "when finished, input anything below:")
            self.log.input()
            self.log.info("Start recognizing...")
            with self.adb.screen_shot(screenshot_path):
                pic_content = self.ocr.scan(screenshot_path)
            if pic_content['flag']['is_mission_page'] == 'TRUE':
                self.ingame['location']['mission_page_strength'] = pic_content[
                    'location']['strength']
                self.ingame['location']['start_mission'] = pic_content[
                    'location']['start_mission']
                self.log.info('Done')
            else:
                raise AutoHelperError('Incorrect page')

        def preparation():
            self.log.info(
                'The program will automatically go to preparation page(without actually start the mission)\n'
                "Please don't disturbance the program")
            self.adb.click(
                self.confuse(self.ingame['location']['start_mission']))
            with self.adb.screen_shot(screenshot_path):
                pic_content = self.ocr.scan(screenshot_path)
            if pic_content['flag']['is_preparation_page'] == 'TRUE':
                self.ingame['location']['prepare_start'] = pic_content[
                    'location']['prepare_start']
                self.log.info('Done')
            else:
                raise AutoHelperError('Incorrect page')

        try:
            # Detect if it's first time
            if self.ingame['FIRST_TIME'] == "TRUE":
                self.log.info(
                    'First time using AA-Helper, Initializing, please follow the instruction.'
                )  # TODO
                # Detect window size
                self.ingame['window_size'] = self.adb.get_window_size()

                # Set screenshot save path
                screenshot_path = path.join(self.path, 'pictures',
                                            'Screenshot.png')

                # Detect homepage
                self.retry(homepage)

                # Detect mission page
                self.retry(mission_page)

                # Detect start button in preparation page
                self.retry(preparation)

                # Change the first-time status into false
                # self.ingame['FIRST_TIME'] = "FALSE" TODO: Uncomment

                # Writing into file
                with open('ingame.json', mode='w') as file:
                    file.write(json.dumps(self.ingame))
        except FileNotFoundError as e:
            self.log.warning('Cannot found ingame.json, creating...', e)
            with open('ingame.json', mode='w'
                      ) as file:  # Create the file and set FIRST_TIME to TRUE
                self.ingame = dict()
                self.ingame['FIRST_TIME'] = "TRUE"
                file.write(json.dumps(self.ingame))
        except JSONDecodeError as e:
            self.log.warning('JSON decoder error:', e)
        except Exception as e:
            self.log.warning('Unknown error during initializing:', e)

    def retry(self, func, max_time=3):
        try:
            return func()
        except Exception as e:
            self.log.warning('Unknown error:', e)
            if max_time > 0:
                self.log.info(
                    f"Error while running '{func.__name__}', retrying ({max_time} time(s) left)."
                )
                return self.retry(func, max_time - 1)
            else:
                raise

    def __verify_config(self):  # TODO
        """
        To verify if the config file is compliant format.
        :return:(bool)
        """
        return True

    # Battle functions
    def battle(self):  # TODO
        """
        A overall battle module
        :return: None
        """
        try:
            self.__start_battle()
        except Exception as e:
            self.log.warning("Unknown Error:", e)

    def __start_battle(self, times=0):  # TODO
        """
        Simply click on '开始战斗' for times
        :param times: Times of clicking '开始战斗' button
        :return: None
        """
        try:
            self.adb.click(
                self.confuse(self.ingame['location']['start_mission']))
        except Exception as e:
            self.log.warning('Unknown error:', e)

    def confuse(self, loca):
        try:
            return loca['left'] + uniform(-0.49, 0.49) * loca['width'], \
                   loca['top'] + uniform(-0.49, 0.49) * loca['height'],
        except Exception as e:
            self.log.warning("Unknown error:", e)