def get_ball_stat(mask_ball): cnt_ball = zc.mask2cnt(mask_ball) area = cv2.contourArea(cnt_ball) center = cnt_ball.mean(axis=0)[0] center_homo = np.hstack((center, 1)).reshape(3, 1) center_rotated = np.dot(rotation_matrix, center_homo) return (area, center_rotated)
def find_pingpong(img, img_prev, mask_table, mask_ball_prev, rotation_matrix): def get_ball_stat(mask_ball): cnt_ball = zc.mask2cnt(mask_ball) area = cv2.contourArea(cnt_ball) center = cnt_ball.mean(axis = 0)[0] center_homo = np.hstack((center, 1)).reshape(3, 1) center_rotated = np.dot(rotation_matrix, center_homo) return (area, center_rotated) rtn_msg = {'status' : 'success'} mask_ball = zc.color_inrange(img, 'HSV', H_L = 165, H_U = 25, S_L = 60, V_L = 90, V_U = 240) mask_ball, _ = zc.get_small_blobs(mask_ball, max_area = 2300) mask_ball, _ = zc.get_big_blobs(mask_ball, min_area = 8) mask_ball, counter = zc.get_square_blobs(mask_ball, th_diff = 0.2, th_area = 0.2) if counter == 0: rtn_msg = {'status' : 'fail', 'message' : "No good color candidate"} return (rtn_msg, None) cnt_table = zc.mask2cnt(mask_table) loc_table_center = zc.get_contour_center(cnt_table)[::-1] mask_ball_ontable = np.bitwise_and(mask_ball, mask_table) mask_ball_ontable = zc.get_closest_blob(mask_ball_ontable, loc_table_center) if mask_ball_ontable is not None: # if any ball on the table, we don't have to rely on previous ball positions mask_ball = mask_ball_ontable return (rtn_msg, (mask_ball, get_ball_stat(mask_ball))) if mask_ball_prev is None: # mask_ball_ontable is already None rtn_msg = {'status' : 'fail', 'message' : "Cannot initialize a location of ball"} return (rtn_msg, None) cnt_ball_prev = zc.mask2cnt(mask_ball_prev) loc_ball_prev = zc.get_contour_center(cnt_ball_prev)[::-1] mask_ball = zc.get_closest_blob(mask_ball, loc_ball_prev) cnt_ball = zc.mask2cnt(mask_ball) loc_ball = zc.get_contour_center(cnt_ball)[::-1] ball_moved_dist = zc.euc_dist(loc_ball_prev, loc_ball) if ball_moved_dist > 110: rtn_msg = {'status' : 'fail', 'message' : "Lost track of ball: %d" % ball_moved_dist} return (rtn_msg, None) return (rtn_msg, (mask_ball, get_ball_stat(mask_ball)))
def find_pingpong(img, img_prev, mask_table, mask_ball_prev, rotation_matrix, display_list): def get_ball_stat(mask_ball): cnt_ball = zc.mask2cnt(mask_ball) area = cv2.contourArea(cnt_ball) center = cnt_ball.mean(axis=0)[0] center_homo = np.hstack((center, 1)).reshape(3, 1) center_rotated = np.dot(rotation_matrix, center_homo) return (area, center_rotated) rtn_msg = {'status': 'success'} mask_ball = zc.color_inrange(img, 'HSV', H_L=165, H_U=25, S_L=65, V_L=150, V_U=255) mask_screen = find_screen(img, display_list) mask_screen, _ = zc.find_largest_CC(mask_screen) mask_possible = np.bitwise_or(mask_screen, zc.expand(mask_table, 3)) mask_ball = np.bitwise_and(mask_ball, mask_possible) mask_ball, _ = zc.get_small_blobs(mask_ball, max_area=2300) mask_ball, _ = zc.get_big_blobs(mask_ball, min_area=8) mask_ball, counter = zc.get_square_blobs(mask_ball, th_diff=0.2, th_area=0.2) zc.check_and_display_mask('ball_raw', img, mask_ball, display_list, resize_max=config.DISPLAY_MAX_PIXEL, wait_time=config.DISPLAY_WAIT_TIME) if counter == 0: rtn_msg = {'status': 'fail', 'message': "No good color candidate"} return (rtn_msg, None) cnt_table = zc.mask2cnt(mask_table) loc_table_center = zc.get_contour_center(cnt_table)[::-1] mask_ball_ontable = np.bitwise_and(mask_ball, mask_table) mask_ball_ontable = zc.get_closest_blob(mask_ball_ontable, loc_table_center) if mask_ball_ontable is not None: # if any ball on the table, we don't have to rely on previous ball positions mask_ball = mask_ball_ontable zc.check_and_display_mask('ball', img, mask_ball, display_list, resize_max=config.DISPLAY_MAX_PIXEL, wait_time=config.DISPLAY_WAIT_TIME) return (rtn_msg, (mask_ball, get_ball_stat(mask_ball))) if mask_ball_prev is None: # mask_ball_ontable is already None rtn_msg = { 'status': 'fail', 'message': "Cannot initialize a location of ball" } return (rtn_msg, None) cnt_ball_prev = zc.mask2cnt(mask_ball_prev) loc_ball_prev = zc.get_contour_center(cnt_ball_prev)[::-1] mask_ball = zc.get_closest_blob(mask_ball, loc_ball_prev) zc.check_and_display_mask('ball', img, mask_ball, display_list, resize_max=config.DISPLAY_MAX_PIXEL, wait_time=config.DISPLAY_WAIT_TIME) cnt_ball = zc.mask2cnt(mask_ball) loc_ball = zc.get_contour_center(cnt_ball)[::-1] ball_moved_dist = zc.euc_dist(loc_ball_prev, loc_ball) if ball_moved_dist > 110: rtn_msg = { 'status': 'fail', 'message': "Lost track of ball: %d" % ball_moved_dist } return (rtn_msg, None) return (rtn_msg, (mask_ball, get_ball_stat(mask_ball)))