def pts_conversion_back_bbox(pts_array, bboxes_in, debug=True):
    '''
    convert pts in the cropped image to the pts in the original image 

    parameters:
        bboxes_in:      1 X 4 numpy array, TLBR or TLWH format
        pts_array:      2(3) x N numpy array, N should >= 1
    '''
    np_bboxes = safe_bbox(bboxes_in, debug=debug)
    if debug:
        assert is2dptsarray(pts_array) or is2dptsarray_occlusion(pts_array) or is2dptsarray_confidence(pts_array), 'the input points should have shape: 2 or 3 x num_pts vs %d x %s' % (pts_array.shape[0], pts_array.shape[1])
        assert isbbox(np_bboxes), 'the input bounding box is not correct'

    pts_out = pts_array.copy()
    pts_out[0, :] = pts_array[0, :] + np_bboxes[0, 0]
    pts_out[1, :] = pts_array[1, :] + np_bboxes[0, 1]

    return pts_out
예제 #2
0
def anno_writer(pts_array,
                pts_savepath,
                num_pts=68,
                anno_version=1,
                debug=True):
    '''
    write the point array to a .pts file
    parameter:
        pts_array:      2 or 3 x num_pts numpy array
        
    '''
    if debug:
        assert is_path_exists_or_creatable(
            pts_savepath), 'the save path is not correct'
        assert (
            is2dptsarray(pts_array) or is2dptsarray_occlusion(pts_array)
            or is2dptsarray_confidence(pts_array)
        ) and pts_array.shape[1] == num_pts, 'the input point is not correct'

    with open(pts_savepath, 'w') as file:
        file.write('version: %d\n' % anno_version)
        file.write('n_points: %d\n' % num_pts)
        file.write('{\n')

        # main content
        for pts_index in xrange(num_pts):
            if is2dptsarray(pts_array):
                file.write('%.3f %.3f %f\n' %
                           (pts_array[0, pts_index], pts_array[1, pts_index],
                            1.0))  # all visible
            else:
                file.write('%.3f %.3f %f\n' %
                           (pts_array[0, pts_index], pts_array[1, pts_index],
                            pts_array[2, pts_index]))

        file.write('}')
        file.close()
예제 #3
0
def visualize_pts_line(pts_array,
                       line_index_list,
                       method=2,
                       seed=0,
                       alpha=0.5,
                       vis_threshold=0.3,
                       pts_size=20,
                       line_size=10,
                       line_color_index=0,
                       fig=None,
                       ax=None,
                       save_path=None,
                       vis=False,
                       warning=True,
                       debug=True,
                       closefig=True):
    '''
    given a list of index, and a point array, to plot a set of points with line on it

    parameters:
        pts_array:          2(3) x num_pts
        line_index_list:    a list of index
        method:             1: all points are connected, if some points are missing in the middle, just ignore that point and connect the two nearby points
                            2: if some points are missing in the middle of a line, the line is decomposed to sub-lines
        vis_threshold:      confidence to draw the points

    '''
    if debug:
        assert is2dptsarray(pts_array) or is2dptsarray_occlusion(
            pts_array) or is2dptsarray_confidence(
                pts_array), 'input points are not correct'
        assert islist(line_index_list), 'the list of index is not correct'
        assert method in [1, 2], 'the plot method is not correct'

    num_pts = pts_array.shape[1]
    # expand the pts_array to 3 rows if the confidence row is not provided
    if pts_array.shape[0] == 2:
        pts_array = np.vstack((pts_array, np.ones((1, num_pts))))
    fig, ax = get_fig_ax_helper(fig=fig, ax=ax)
    np.random.seed(seed)
    color_option = 'hsv'

    if color_option == 'rgb': color_set_random = np.random.rand(3, num_pts)
    elif color_option == 'hsv':
        h_random = np.random.rand(num_pts, )
        color_set_random = np.zeros((3, num_pts), dtype='float32')
        for pts_index in range(num_pts):
            color_set_random[:, pts_index] = colorsys.hsv_to_rgb(
                h_random[pts_index], 1, 1)

    line_color = color_set[line_color_index]
    pts_line = pts_array[:, line_index_list]

    if method == 1:
        valid_pts_list = np.where(pts_line[2, :] > vis_threshold)[0].tolist()
        pts_line_tmp = pts_line[:, valid_pts_list]
        ax.plot(pts_line_tmp[0, :],
                pts_line_tmp[1, :],
                lw=line_size,
                color=line_color,
                alpha=alpha)  # plot all lines

        # plot all points
        for pts_index in valid_pts_list:
            pts_index_original = line_index_list[pts_index]
            # ax.plot(pts_array[0, pts_index_original], pts_array[1, pts_index_original], 'o', color=color_set_big[pts_index_original % len(color_set_big)], alpha=alpha)
            ax.plot(pts_array[0, pts_index_original],
                    pts_array[1, pts_index_original],
                    marker='o',
                    ms=pts_size,
                    lw=line_size,
                    color=color_set_random[:, pts_index],
                    alpha=alpha)
    else:
        not_valid_pts_list = np.where(
            pts_line[2, :] < vis_threshold)[0].tolist()
        if len(not_valid_pts_list) == 0:  # all valid
            ax.plot(pts_line[0, :],
                    pts_line[1, :],
                    lw=line_size,
                    color=line_color,
                    alpha=alpha)

            # plot points
            for pts_index in line_index_list:
                # ax.plot(pts_array[0, pts_index], pts_array[1, pts_index], 'o', color=color_set_big[pts_index % len(color_set_big)], alpha=alpha)
                ax.plot(pts_array[0, pts_index],
                        pts_array[1, pts_index],
                        marker='o',
                        ms=pts_size,
                        lw=line_size,
                        color=color_set_random[:, pts_index],
                        alpha=alpha)
        else:
            prev_index = 0
            for not_valid_index in not_valid_pts_list:
                plot_list = range(prev_index, not_valid_index)
                pts_line_tmp = pts_line[:, plot_list]
                ax.plot(pts_line_tmp[0, :],
                        pts_line_tmp[1, :],
                        lw=line_size,
                        color=line_color,
                        alpha=alpha)

                # plot points
                for pts_index in plot_list:
                    pts_index_original = line_index_list[pts_index]
                    ax.plot(pts_array[0, pts_index_original],
                            pts_array[1, pts_index_original],
                            marker='o',
                            ms=pts_size,
                            lw=line_size,
                            color=color_set_random[:, pts_index_original],
                            alpha=alpha)
                    # ax.plot(pts_array[0, pts_index_original], pts_array[1, pts_index_original], 'o', color=color_set_big[pts_index_original % len(color_set_big)], alpha=alpha)

                prev_index = not_valid_index + 1

            pts_line_tmp = pts_line[:, prev_index:]
            ax.plot(pts_line_tmp[0, :],
                    pts_line_tmp[1, :],
                    lw=line_size,
                    color=line_color,
                    alpha=alpha)  # plot last line

            # plot last points
            for pts_index in range(prev_index, pts_line.shape[1]):
                pts_index_original = line_index_list[pts_index]
                # ax.plot(pts_array[0, pts_index_original], pts_array[1, pts_index_original], 'o', color=color_set_big[pts_index_original % len(color_set_big)], alpha=alpha)
                ax.plot(pts_array[0, pts_index_original],
                        pts_array[1, pts_index_original],
                        marker='o',
                        ms=pts_size,
                        lw=line_size,
                        color=color_set_random[:, pts_index_original],
                        alpha=alpha)

    return save_vis_close_helper(fig=fig,
                                 ax=ax,
                                 vis=vis,
                                 save_path=save_path,
                                 warning=warning,
                                 debug=debug,
                                 closefig=closefig)
예제 #4
0
def visualize_pts_array(input_pts,
                        color_index=0,
                        pts_size=20,
                        label=False,
                        label_list=None,
                        label_size=20,
                        vis_threshold=0.3,
                        covariance=False,
                        plot_occl=False,
                        xlim=None,
                        ylim=None,
                        fig=None,
                        ax=None,
                        save_path=None,
                        vis=False,
                        warning=True,
                        debug=True,
                        closefig=True):
    '''
    plot keypoints with covariance ellipse

    parameters:
        pts_array:      2(3) x num_pts numpy array, the third channel could be confidence or occlusion
    '''
    # obtain the points
    try:
        pts_array = safe_2dptsarray(input_pts,
                                    homogeneous=True,
                                    warning=warning,
                                    debug=debug)
    except AssertionError:
        pts_array = safe_2dptsarray(input_pts,
                                    homogeneous=False,
                                    warning=warning,
                                    debug=debug)
    if debug:
        assert is2dptsarray(pts_array) or is2dptsarray_occlusion(
            pts_array) or is2dptsarray_confidence(
                pts_array), 'input points are not correct'
    num_pts = pts_array.shape[1]

    # obtain a label list if required but not provided
    if debug: assert islogical(label), 'label flag is not correct'
    if label and (label_list is None):
        label_list = [str(i) for i in xrange(num_pts)]
    if label_list is not None and debug:
        assert islistofstring(label_list), 'labels are not correct'

    # obtain the color index
    if islist(color_index):
        if debug:
            assert not (
                plot_occl or covariance
            ), 'the occlusion or covariance are not compatible with plotting different colors during scattering'
        color_tmp = [color_set_big[index_tmp] for index_tmp in color_index]
    else:
        color_tmp = color_set_big[color_index % len(color_set_big)]

    fig, ax = get_fig_ax_helper(fig=fig, ax=ax)
    std, conf = None, 0.95
    if is2dptsarray(pts_array):  # only 2d points without third rows
        if debug and islist(color_tmp):
            assert len(
                color_tmp
            ) == num_pts, 'number of points to plot is not equal to number of colors provided'
        ax.scatter(pts_array[0, :],
                   pts_array[1, :],
                   color=color_tmp,
                   s=pts_size)
        pts_visible_index = range(pts_array.shape[1])
        pts_ignore_index = []
        pts_invisible_index = []
    else:
        # automatically justify if the third row is confidence or occlusion flag
        num_float_elements = np.where(
            np.logical_and(
                pts_array[2, :] != -1,
                np.logical_and(pts_array[2, :] != 0,
                               pts_array[2, :] != 1)))[0].tolist()
        if len(num_float_elements) > 0: type_3row = 'conf'
        else: type_3row = 'occu'

        if type_3row == 'occu':
            pts_visible_index = np.where(pts_array[
                2, :] == 1)[0].tolist()  # plot visible points in red color
            pts_ignore_index = np.where(pts_array[2, :] == -1)[0].tolist(
            )  # do not plot points with annotation, usually visible, but not annotated
            pts_invisible_index = np.where(pts_array[
                2, :] == 0)[0].tolist()  # plot invisible points in blue color
        else:
            pts_visible_index = np.where(
                pts_array[2, :] > vis_threshold)[0].tolist()
            pts_invisible_index = np.where(
                pts_array[2, :] <= vis_threshold)[0].tolist()
            pts_ignore_index = []

        if debug and islist(color_tmp):
            assert len(color_tmp) == len(
                pts_visible_index
            ), 'number of points to plot is not equal to number of colors provided'
        ax.scatter(pts_array[0, pts_visible_index],
                   pts_array[1, pts_visible_index],
                   color=color_tmp,
                   s=pts_size)
        if plot_occl:
            ax.scatter(pts_array[0, pts_invisible_index],
                       pts_array[1, pts_invisible_index],
                       color=color_set_big[(color_index + 1) %
                                           len(color_set_big)],
                       s=pts_size)
        if covariance:
            visualize_pts_covariance(pts_array[0:2, :],
                                     std=std,
                                     conf=conf,
                                     fig=fig,
                                     ax=ax,
                                     debug=debug,
                                     color=color_tmp)

    if plot_occl: not_plot_index = pts_ignore_index
    else: not_plot_index = pts_ignore_index + pts_invisible_index
    if label_list is not None:
        for pts_index in xrange(num_pts):
            label_tmp = label_list[pts_index]
            if pts_index in not_plot_index: continue
            else:
                # note that the annotation is based on the coordinate instead of the order of plotting the points, so the orider in pts_index does not matter
                if islist(color_index):
                    plt.annotate(
                        label_tmp,
                        xy=(pts_array[0, pts_index], pts_array[1, pts_index]),
                        xytext=(-1, 1),
                        color=color_set_big[(color_index[pts_index] + 5) %
                                            len(color_set_big)],
                        textcoords='offset points',
                        ha='right',
                        va='bottom',
                        fontsize=label_size)
                else:
                    plt.annotate(label_tmp,
                                 xy=(pts_array[0, pts_index],
                                     pts_array[1, pts_index]),
                                 xytext=(-1, 1),
                                 color=color_set_big[(color_index + 5) %
                                                     len(color_set_big)],
                                 textcoords='offset points',
                                 ha='right',
                                 va='bottom',
                                 fontsize=label_size)

    # set axis
    if xlim is not None:
        if debug:
            assert islist(xlim) and len(xlim) == 2, 'the x lim is not correct'
        plt.xlim(xlim[0], xlim[1])
    if ylim is not None:
        if debug:
            assert islist(ylim) and len(ylim) == 2, 'the y lim is not correct'
        plt.ylim(ylim[0], ylim[1])

    return save_vis_close_helper(fig=fig,
                                 ax=ax,
                                 vis=vis,
                                 save_path=save_path,
                                 warning=warning,
                                 debug=debug,
                                 closefig=closefig,
                                 transparent=False)
예제 #5
0
def triangulate_two_views(input_pts1,
                          input_pts2,
                          projection1,
                          projection2,
                          scaling_factor=1,
                          warning=True,
                          debug=True):
    '''
	triangulation from two views
	'''
    #       projection1 - 3 x 4 Camera Matrix 1
    #       pts_array1 - 3 x N set of points
    #       projection2 - 3 x 4 Camera Matrix 2
    #       pts_array2 - 3 x N set of points
    try:
        pts_array1 = safe_2dptsarray(input_pts1,
                                     homogeneous=True,
                                     warning=warning,
                                     debug=debug)
    except AssertionError:
        pts_array1 = safe_2dptsarray(input_pts1,
                                     homogeneous=False,
                                     warning=warning,
                                     debug=debug)
    if debug:
        assert is2dptsarray(pts_array1) or is2dptsarray_occlusion(
            pts_array1) or is2dptsarray_confidence(
                pts_array1), 'first input points are not correct'
    try:
        pts_array2 = safe_2dptsarray(input_pts2,
                                     homogeneous=True,
                                     warning=warning,
                                     debug=debug)
    except AssertionError:
        pts_array2 = safe_2dptsarray(input_pts2,
                                     homogeneous=False,
                                     warning=warning,
                                     debug=debug)
    if debug:
        assert is2dptsarray(pts_array2) or is2dptsarray_occlusion(
            pts_array2) or is2dptsarray_confidence(
                pts_array2), 'second input points are not correct'

    pts_array1 = pts_array1.astype('float32')
    pts_array2 = pts_array2.astype('float32')

    # initialization
    num_pts = pts_array1.shape[1]
    pts_array1[0:2, :] = pts_array1[0:2, :] / float(scaling_factor)
    pts_array2[0:2, :] = pts_array2[0:2, :] / float(scaling_factor)

    # least square
    p1T1 = projection1[0, :]  # 1 x 4
    p1T2 = projection1[1, :]
    p1T3 = projection1[2, :]
    p2T1 = projection2[0, :]
    p2T2 = projection2[1, :]
    p2T3 = projection2[2, :]
    # condition_matrix = np.array([[1e-3, 0, 0, 0],			# 4 x 4
    # 							 [0, 1e-3, 0, 0],
    # 							 [0, 0, 1e-3, 0],
    # 							 [0, 0, 0, 1e-6]])
    condition_matrix = np.array([
        [1, 0, 0, 0],  # 4 x 4
        [0, 1, 0, 0],
        [0, 0, 1, 0],
        [0, 0, 0, 1]
    ])
    pts_3d = np.zeros((num_pts, 4), 'float32')  # N x 4
    pts_3d.fill(-1)
    p1_proj = pts_array1.copy().transpose()  # N x 3
    p2_proj = pts_array2.copy().transpose()
    for i in range(num_pts):
        if pts_array1[2, i] == -1 or pts_array2[2, i] == -1: continue
        U = np.zeros((6, 4), dtype='float32')  # 6 x 4

        U[0, :] = np.multiply(pts_array1[1, i], p1T3) - p1T2  # y * p1T3 - p1T2
        U[1, :] = p1T1 - np.multiply(pts_array1[0, i], p1T3)  # p1T1 - x * p1T3
        U[2, :] = np.multiply(pts_array1[0, i], p1T2) - np.multiply(
            pts_array1[1, i], p1T1)  # x * p1T2 - y * p1T1
        U[3, :] = np.multiply(pts_array2[1, i], p2T3) - p2T2  # y * p2T3 - p2T2
        U[4, :] = p2T1 - np.multiply(pts_array2[0, i], p2T3)  # p2T1 - x * p2T3
        U[5, :] = np.multiply(pts_array2[0, i], p2T2) - np.multiply(
            pts_array2[1, i], p2T1)  # x * p2T2 - y * p2T1

        conditioned_U = np.matmul(U, condition_matrix)
        # print(conditioned_U)

        _, _, V = np.linalg.svd(conditioned_U)
        conditioned_pts_3d = V[
            -1, :]  # 4 x 1, V is the transpose version of V in matlab
        pts_3d[i, :] = np.matmul(condition_matrix,
                                 conditioned_pts_3d.reshape(
                                     (4, 1))).transpose()
        pts_3d[i, :] = np.divide(pts_3d[i, :], pts_3d[i, 3])  # N x 4
        # print(pts_3d)

        # compute reprojection error
        p1_proj[i, :] = (np.matmul(projection1,
                                   pts_3d[i, :].transpose().reshape(
                                       (4, 1)))).transpose()  # 1 x 3
        p2_proj[i, :] = (np.matmul(projection2,
                                   pts_3d[i, :].transpose().reshape(
                                       (4, 1)))).transpose()
        p1_proj[i, :] = np.divide(p1_proj[i, :], p1_proj[i, -1])
        p2_proj[i, :] = np.divide(p2_proj[i, :], p2_proj[i, -1])
        # error = error + np.norm(p1_proj[i, 0:2] - pts_array1[0:2, i]) + np.norm(p2_proj[i, 0:2] - pts_array2[0:2, i])

    error_tmp, error_list = pts_euclidean(p1_proj[:, 0:2].transpose(),
                                          pts_array1[0:2, :],
                                          warning=warning,
                                          debug=debug)
    error = error_tmp * num_pts
    print(error_list)
    error_tmp, error_list = pts_euclidean(p2_proj[:, 0:2].transpose(),
                                          pts_array2[0:2, :],
                                          warning=warning,
                                          debug=debug)
    error += error_tmp * num_pts
    print(error_list)

    pts_3d = pts_3d[:, 0:3].transpose()  # 3 x N
    return pts_3d, p1_proj.transpose(), p2_proj.transpose()