Example #1
0
 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)))
Example #3
0
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)))