def _set_player_info(self, player, position): """Set team & player name info for a matching result. Author: Appcell Args: None Returns: A dict of player info, with the form of: { "chara": "empty", # name of chara, or "empty" "player": "empty", # name of player, or "empty" "team": "empty", # name of team, or "empty" "pos": -1, # x-axis position of icon in killfeed row image } """ res = { 'chara': player['chara'], 'team': 'empty', 'player': 'empty', 'pos': player['pos'] } color_pos = OW.get_killfeed_team_color_pos(player['pos'], position)[self.game_type] color = self.image[color_pos[0], color_pos[1]] colors_ref = self.frame.get_team_colors() dist_left = ImageUtils.color_distance(color, colors_ref['left']) dist_right = ImageUtils.color_distance(color, colors_ref['right']) if dist_left < dist_right: res['team'] = self.frame.game.team_names['left'] else: res['team'] = self.frame.game.team_names['right'] chara = OW.get_chara_name(player['chara']) if res['team'] == self.frame.game.team_names['left']: res['player'] = next( (item.name for item in self.frame.players[0:6] if item.chara == chara), "empty") else: res['player'] = next( (item.name for item in self.frame.players[6:12] if item.chara == chara), "empty") return res
def _preprocess_ability_icon(self, icon): """Preprocess an ability icon cut from frame. Main idea here is to find color of icon first. Color of ability icon is same as of arrow icon on right side. Given color, remove all parts with different colors. Author: Appcell Args: None Returns: None """ ability_pos = OW.get_ability_icon_pos(self.player2['pos'])[self.game_type] color = self.image_with_gap[ability_pos[ 0] + ability_pos[1]/2, ability_pos[2] + ability_pos[3] + 6] filtered_icon = np.zeros((icon.shape[0], icon.shape[1])) # TODO: Labelling needed here!!! Especially when background looks # similar to foreground. # TODO: There must be a better way for this for i in range(icon.shape[0]): for j in range(icon.shape[1]): if ImageUtils.color_distance(icon[i, j, :], color) \ < OW.ABILITY_ICON_COLOR_FILTER_THRESHOLD[self.game_type]: filtered_icon[i, j] = 255 return filtered_icon.astype('uint8')
def get_headshot(self): """Tell if elimination comes with a headshot. Author: Appcell Args: None Returns: None """ ability_pos = OW.get_ability_icon_pos(self.player2['pos'])[self.game_type] color = self.image_with_gap[ability_pos[ 0] + ability_pos[1]/2, ability_pos[2] + ability_pos[3] + 6] # TODO: Write consts here into ow.py if ImageUtils.color_distance(color, np.array([255, 255, 255])) > 40: self.is_headshot = True
def get_chara(self): """Retrieves chara name for current player in current frame. Compare cropped avatar with reference avatars, pick the best match as the chara current player plays with. In OWL, currently observed player has a larger avatar. To differentiate between the two, comparison has to run twice and the better match gets chosen. Author: Appcell Args: None Returns: None """ all_avatars = self.frame.get_avatars(self.index) avatars_ref = all_avatars["normal"] avatars_small_ref = all_avatars["small"] team_color = avatars_ref['ana'][0, 0] # Crop avatar from frame avatar = ImageUtils.crop( self.image, OW.get_avatar_pos(self.index)[self.frame.game.game_type]) avatar_small = ImageUtils.crop( avatar, [4, avatar.shape[0] - 4, 0, avatar.shape[1]]) # If player is observed, not sure about this tho avatar_diff = ImageUtils.crop( self.image, OW.get_avatar_diff_pos(self.index)[self.frame.game.game_type]) max_diff = 0 for i in range(avatar_diff.shape[0]): for j in range(avatar_diff.shape[1]): if ImageUtils.color_distance(avatar_diff[i, j], team_color) > max_diff: max_diff = ImageUtils.color_distance( avatar_diff[i, j], team_color) if max_diff < 40 and self.is_ult_ready is False: self.is_observed = True score = 0 for (name, avatar_ref) in avatars_ref.iteritems(): s = cv2.matchTemplate(avatar, avatar_ref, cv2.TM_CCOEFF_NORMED) _, s, _, loc1 = cv2.minMaxLoc(s) temp_avatar = ImageUtils.crop( avatar, [loc1[1], avatar_ref.shape[0], loc1[0], avatar_ref.shape[1]]) s_ssim1 = measure.compare_ssim(temp_avatar, avatar_ref, multichannel=True) s_small = cv2.matchTemplate(avatar_small, avatars_small_ref[name], cv2.TM_CCOEFF_NORMED) _, s_small, _, loc2 = cv2.minMaxLoc(s_small) temp_avatar2 = ImageUtils.crop(avatar_small, [ loc2[1], avatars_small_ref[name].shape[0], loc2[0], avatars_small_ref[name].shape[1] ]) s_ssim2 = measure.compare_ssim(temp_avatar2, avatars_small_ref[name], multichannel=True) s_ssim = s_ssim1 if s > s_small else s_ssim2 s_final = s if s > s_small else s_small loc = loc1 if s > s_small else loc2 if s_final * 0.4 + s_ssim * 0.6 > score: score = s_final * 0.4 + s_ssim * 0.6 self.chara = name if self.chara is None: self.chara = "empty" self.is_dead = True return self.get_living_status(avatars_ref[self.chara])