def pts_euclidean(input_pts1, input_pts2, warning=True, debug=True): ''' calculate the euclidean distance between two sets of points parameters: input_pts1: 2 x N or (2, ) numpy array, a list of 2 elements, a listoflist of 2 elements: (x, y) input_pts2: same as above outputs: ave_euclidean: averaged euclidean distance eculidean_list: a list of the euclidean distance for all data points ''' pts1 = safe_2dptsarray(input_pts1, warning=warning, debug=debug) pts2 = safe_2dptsarray(input_pts2, warning=warning, debug=debug) if debug: assert pts1.shape == pts2.shape, 'the shape of two points is not equal' assert is2dptsarray(pts1) and is2dptsarray(pts2), 'the input points are not correct' # calculate the distance eculidean_list = np.zeros((pts1.shape[1], ), dtype='float32') num_pts = pts1.shape[1] ave_euclidean = 0 for pts_index in xrange(num_pts): pts1_tmp = pts1[:, pts_index] pts2_tmp = pts2[:, pts_index] n = float(pts_index + 1) distance_tmp = math.sqrt((pts1_tmp[0] - pts2_tmp[0])**2 + (pts1_tmp[1] - pts2_tmp[1])**2) # TODO check the start ave_euclidean = (n - 1) / n * ave_euclidean + distance_tmp / n eculidean_list[pts_index] = distance_tmp return ave_euclidean, eculidean_list.tolist()
def pts2bbox(pts, debug=True, vis=False): ''' convert a set of 2d points to a bounding box parameter: pts: 2 x N numpy array, N should >= 2 return: bbox: 1 x 4 numpy array, TLBR format ''' if debug: assert is2dptsarray(pts) or is2dptsarray_occlusion( pts ), 'the input points should have shape: 2 or 3 x num_pts vs %d x %s' % ( pts.shape[0], pts.shape[1]) assert pts.shape[ 1] >= 2, 'number of points should be larger or equal than 2' bbox = np.zeros((1, 4), dtype='float32') bbox[0, 0] = np.min(pts[0, :]) # x coordinate of left top point bbox[0, 1] = np.min(pts[1, :]) # y coordinate of left top point bbox[0, 2] = np.max(pts[0, :]) # x coordinate of bottom right point bbox[0, 3] = np.max(pts[1, :]) # y coordinate of bottom right point # if vis: # fig = plt.figure() # pts = imagecoor2cartesian(pts) # plt.scatter(pts[0, :], pts[1, :], color='r') # plt.scatter(bbox[0, 0], -bbox[0, 1], color='b') # -1 is to convert the coordinate from image to cartesian # plt.scatter(bbox[0, 2], -bbox[0, 3], color='b') # plt.show() # plt.close(fig) return bbox
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()
def safe_2dptsarray(input_pts, homogeneous=False, warning=True, debug=True): ''' make sure to copy the pts array without modifying it and make the dimension to 2(3 if homogenous) x N parameters: input_pts: a list of 2(3 if homogenous) elements, a listoflist of 2 elements: e.g., [[1,2], [5,6]], a numpy array with shape or (2, N) or (2, ) homogeneous: the input points are in the homogenous coordinate outputs: np_pts: 2 (3 if homogenous) X N numpy array ''' if homogeneous: dimension = 3 else: dimension = 2 if islist(input_pts): if islistoflist(input_pts): if debug: assert all( len(list_tmp) == dimension for list_tmp in input_pts ), 'all sub-lists should have length of %d' % dimension np_pts = np.array(input_pts).transpose() else: if debug: assert len( input_pts ) == dimension, 'the input pts list does not have a good shape' np_pts = np.array(input_pts).reshape((dimension, 1)) elif isnparray(input_pts): input_pts = input_pts.copy() if input_pts.shape == (dimension, ): np_pts = input_pts.reshape((dimension, 1)) else: np_pts = input_pts else: assert False, 'only list and numpy array for pts are supported' if debug: if homogeneous: assert is2dptsarray_homogeneous( np_pts), 'the input pts array does not have a good shape' else: assert is2dptsarray( np_pts), 'the input pts array does not have a good shape' return np_pts
def pts_rotate2D(pts_array, rotation_angle, im_height, im_width, warning=True, debug=True): ''' rotate the point array in 2D plane counter-clockwise parameters: pts_array: 2 x num_pts rotation_angle: e.g. 90 return pts_array: 2 x num_pts ''' if debug: assert is2dptsarray(pts_array), 'the input point array does not have a good shape' rotation_angle = safe_angle(rotation_angle, warning=warning, debug=True) # ensure to be in [-180, 180] if rotation_angle > 0: cols2rotated, rows2rotated = im_width, im_width else: cols2rotated, rows2rotated = im_height, im_height rotation_matrix = cv2.getRotationMatrix2D((cols2rotated/2, rows2rotated/2), rotation_angle, 1) # 2 x 3 num_pts = pts_array.shape[1] pts_rotate = np.ones((3, num_pts), dtype='float32') # 3 x num_pts pts_rotate[0:2, :] = pts_array return np.dot(rotation_matrix, pts_rotate) # 2 x num_pts
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