Ejemplo n.º 1
0
def nparray_chw2hwc(input_nparray, warning=True, debug=True):
	'''
	this function transpose the channels of an numpy array  from CHW to HWC

	parameters:
	    input_nparray:  a numpy CHW array

	outputs:
	    np_array:       a numpy HWC array
	'''
	if debug: isnparray(input_nparray), 'the input array is not a numpy'
	np_array = input_nparray.copy()
	if debug: assert np_array.ndim == 3, 'the input numpy array does not have a good dimension: {}'.format(np_image.shape)

	return np.transpose(np_array, (1, 2, 0)) 
Ejemplo n.º 2
0
def hist_equalization(input_data, num_bins=256, warning=True, debug=True):
    '''
	convert a N-d numpy data (or list) with random distribution to a 1-d data with equalized histogram
	e.g., for the samples from a gaussian distribution, the data points are dense in the middle, the cdf increases fast
	in the middle so that the discrete cdf is sparse in the middle, the equalized data points are interpolated from cdf such
	that the density can be the same for the middle and the rest

	parameters:
		input_data:		a list or a numpy data, could be any shape, not necessarily a 1-d data, can be integer data (uint8 image) or float data (float32 image)
		num_bins:		bigger, the histogram of equalized data points is more flat

	outputs:
		data_equalized:	equalized data with the same shape as input, it is float with [0, 1]
	'''
    np_data = safe_npdata(input_data, warning=warning, debug=debug)
    if debug: assert isnparray(np_data), 'the input data is not a numpy data'

    ori_shape = np_data.shape
    np_data = np_data.flatten()
    hist, xs = np.histogram(
        np_data, num_bins,
        density=True)  # return distribution and X's coordinates
    cdf = hist.cumsum()
    cdf = cdf / cdf[-1]  # sparse in the middle
    data_equalized = np.interp(np_data, xs[:-1], cdf)

    return data_equalized.reshape((ori_shape))
Ejemplo n.º 3
0
def identity(data, data_range=None, debug=True):
    if debug:
        print(
            'debug mode is on during identity function. Please turn off after debuging'
        )
        assert isnparray(data), 'data is not correct'
    return data
Ejemplo n.º 4
0
def safe_image_like(input_image, warning=True, debug=True):
    '''
	return an image-like numpy no matter what format the input is, the numpy has the image shape, but value may not be in [0, 1] for float image
	make sure the output numpy image is a copy of the input image

	note:
		an image-like numpy array is an array with image-like shape, but might contain arbitrary value

	parameters:
		input_image:		pil image or image-like array, color or gray, float or uint

	outputs:
		np_image:			numpy image, with the same color and datatype as the input
		isnan:				return True if any nan value exists
	'''
    if ispilimage(input_image): np_image = np.array(input_image)
    elif isnparray(input_image):
        np_image = input_image.copy()
        assert isimage_dimension(
            np_image), 'the input is not an image-like numpy array'
    else:
        assert False, 'only pil and numpy image-like data are supported'

    isnan = isnannparray(np_image)
    if warning and isnan: print('nan exists in the image data')

    return np_image, isnan
Ejemplo n.º 5
0
def safe_angle(input_angle, radian=False, warning=True, debug=True):
    '''
	make ensure the rotation is in [-180, 180] in degree

	parameters:
		input_angle:	an angle which is supposed to be in degree
		radian:			if True, the unit is replaced to radian instead of degree

	outputs:
		angle:			an angle in degree within (-180, 180]
	'''
    angle = copy.copy(input_angle)
    if debug:
        assert isscalar(angle), 'the input angle should be a scalar'

    if isnparray(angle): angle = angle[0]  # single numpy scalar value
    if radian:
        while angle > np.pi:
            angle -= np.pi
        while angle <= -np.pi:
            angle += np.pi
    else:
        while angle > 180:
            angle -= 360
        while angle <= -180:
            angle += 360

    return angle
Ejemplo n.º 6
0
def generate_list_from_data(save_path, src_data, debug=True):
    '''
    generate a file which contains a 1-d numpy array data

    parameter:
        src_data:   a list of 1 element data, or a 1-d numpy array data
    '''
    save_path = safe_path(save_path)

    if debug:
        if isnparray(src_data):
            assert src_data.ndim == 1, 'source data is incorrect'
        elif islist(src_data):
            assert all(np.array(data_tmp).size == 1
                       for data_tmp in src_data), 'source data is in correct'
        assert isfolder(save_path) or isfile(
            save_path), 'save path is not correct'

    if isfolder(save_path): save_path = os.path.join(save_path, 'datalist.txt')
    if debug:
        assert is_path_exists_or_creatable(
            save_path), 'the file cannot be created'
    with open(save_path, 'w') as file:
        for item in src_data:
            file.write('%f\n' % item)
    file.close()
Ejemplo n.º 7
0
def bbox_rotatedtight2rotatedloose(bbox_in, angle_in_degree, debug=True):
    '''
    transfer the rotated bbox with tight version to loose version, both contains only two points (top left and bottom right)
    only a single box is feeded into
    '''
    if debug:
        assert isnparray(bbox_in) and bbox_in.size == 4, 'box is not correct'

    pts_tl = np.array([bbox_in[0], bbox_in[1]])
    pts_br = np.array([bbox_in[2], bbox_in[3]])
    line1 = get_2Dline_from_pts_slope(imagecoor2cartesian(pts_tl),
                                      angle_in_degree + 90.00)
    line2 = get_2Dline_from_pts_slope(imagecoor2cartesian(pts_br),
                                      angle_in_degree)
    pts_bl = cartesian2imagecoor(get_2dpts_from_lines(line1, line2))
    pts_tr = cartesian2imagecoor(
        get_2dpts_from_lines(
            get_2Dline_from_pts_slope(imagecoor2cartesian(pts_tl),
                                      angle_in_degree),
            get_2Dline_from_pts_slope(imagecoor2cartesian(pts_br),
                                      angle_in_degree + 90.00)))
    # assert_almost_equal(np.dot(pts_bl - pts_br, pts_bl - pts_tl), 0, err_msg='The intersection points are wrong')
    # assert_almost_equal(np.dot(pts_tr - pts_br, pts_tr - pts_tl), 0, err_msg='The intersection points are wrong')

    pts_tl_final = np.zeros((2), dtype=np.float32)
    pts_br_final = np.zeros((2), dtype=np.float32)
    pts_tl_final[0] = min({pts_tl[0], pts_br[0], pts_bl[0], pts_tr[0]})
    pts_tl_final[1] = min({pts_tl[1], pts_br[1], pts_bl[1], pts_tr[1]})
    pts_br_final[0] = max({pts_tl[0], pts_br[0], pts_bl[0], pts_tr[0]})
    pts_br_final[1] = max({pts_tl[1], pts_br[1], pts_bl[1], pts_tr[1]})

    # print(pts_tl_final)
    # print(pts_br_final)
    test = np.hstack((pts_tl_final, pts_br_final))
    return test
Ejemplo n.º 8
0
def cartesian2imagecoor(pts, debug=True):
    '''
    change the coordinate system from normal cartesian system back to image coordinate system, basically reverse the y coordinate
    
    parameter: 
        pts:    a single point (list, tuple, numpy array) or a 2 x N numpy array representing a set of points

    return:
        pts:    a tuple if only single point comes in or a 2 x N numpy array
    '''
    if debug:
        assert is2dpts(pts) or (isnparray(pts) and pts.shape[0] == 2 and pts.shape[1] > 0), 'point is not correct'
    
    if is2dpts(pts):
        if isnparray(pts): pts = np.reshape(pts, (2, ))
        return (pts[0], -pts[1])
    else:
        pts[1, :] = -pts[1, :]
        return pts
Ejemplo n.º 9
0
def image_chw2hwc(input_image, warning=True, debug=True):
    '''
	this function transpose the channels of an image from CHW to HWC

	parameters:
		input_image:	a numpy CHW image

	outputs:
		np_image:		a numpy HWC image
	'''

    if debug: isnparray(input_image), 'the input image is not a numpy'
    np_image = input_image.copy()
    if debug:
        assert np_image.ndim == 3 and np_image.shape[
            0] == 3, 'the input numpy image does not have a good dimension: {}'.format(
                np_image.shape)

    return np.transpose(np_image, (1, 2, 0))
Ejemplo n.º 10
0
def save_2dmatrix_to_file(data, save_path, formatting='%.1f', debug=True):
    save_path = safe_path(save_path)
    if debug:
        assert isnparray(data) and len(
            data.shape) == 2, 'input data is not 2d numpy array'
        assert is_path_exists_or_creatable(
            save_path), 'save path is not correct'
        mkdir_if_missing(save_path)
        # assert isnparray(data) and len(data.shape) <= 2, 'the data is not correct'

    np.savetxt(save_path, data, delimiter=' ', fmt=formatting)
Ejemplo n.º 11
0
def pol2cart_2d_degree(pts, debug=True):
    '''
    input point: (rho, phi)

    phi is in degree
    '''
    if debug:
        assert istuple(pts) or islist(pts) or isnparray(pts), 'input point is not correct'
        assert np.array(pts).size == 2, 'input point is not 2d points'

    rho = pts[0]
    phi = math.radians(pts[1])
    x = rho * np.cos(phi)
    y = rho * np.sin(phi)
    return (x, y)
Ejemplo n.º 12
0
def safe_npdata(input_data, warning=True, debug=True):
    '''
	copy a list of data or a numpy data to the buffer for use

	parameters:
		input_data:		a list, a scalar or numpy data

	outputs:
		np_data:		a copy of numpy data
	'''
    if islist(input_data): np_data = np.array(input_data)
    elif isscalar(input_data): np_data = np.array(input_data).reshape((1, ))
    elif isnparray(input_data): np_data = input_data.copy()
    else: assert False, 'only list of data, scalar or numpy data are supported'

    return np_data
Ejemplo n.º 13
0
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
Ejemplo n.º 14
0
def data_unnormalize(data, data_range, debug=True):
    '''
	this function unnormalizes 1-d label to normal scale based on range of data
	'''
    np_data = safe_npdata(input_data, warning=warning,
                          debug=debug).astype('float32')
    if debug:
        assert isnparray(np_data), 'the input data is not a numpy data'
        assert isrange(data_range), 'data range is not correct'

    max_value = data_range[1]
    min_value = data_range[0]
    unnormalized = np_data * (max_value - min_value) + min_value

    # if debug:
    # normalized = normalize_data(data=unnormalized, data_range=data_range, debug=False)
    # assert_almost_equal(data, normalized, decimal=6, err_msg='data is not correct: %f vs %f' % (data, normalized))
    return unnormalized
Ejemplo n.º 15
0
def apply_rotation_tight(bbox_in, angle_in_degree, im_shape, debug=True):
    '''
    return 4 points clockwise
    '''
    if debug:
        assert isnparray(bbox_in) and bbox_in.size == 4, 'box is not correct'

    bbox_in = np.reshape(bbox_in, (4, ))
    bbox_tight = bbox_rotation_inv(
        bbox_in, angle_in_degree, im_shape, debug=debug
    )  # get top left and bottom right coordinate of the rotated bbox in the image coordinate
    # print('bbox after inverse the rotation')
    # print(bbox_tight)
    pts_total = np.zeros((4, 2), dtype=np.int)
    pts_tl = np.array([bbox_tight[0], bbox_tight[1]])
    pts_br = np.array([bbox_tight[2], bbox_tight[3]])
    line1 = get_2dline_from_pts_slope(imagecoor2cartesian(pts_tl, debug=debug),
                                      angle_in_degree + 90.00,
                                      debug=debug)
    line2 = get_2dline_from_pts_slope(imagecoor2cartesian(pts_br, debug=debug),
                                      angle_in_degree,
                                      debug=debug)
    pts_bl = cartesian2imagecoor(get_2dpts_from_lines(line1,
                                                      line2,
                                                      debug=debug),
                                 debug=debug)
    pts_tr = cartesian2imagecoor(get_2dpts_from_lines(
        get_2dline_from_pts_slope(imagecoor2cartesian(pts_tl, debug=debug),
                                  angle_in_degree,
                                  debug=debug),
        get_2dline_from_pts_slope(imagecoor2cartesian(pts_br, debug=debug),
                                  angle_in_degree + 90.00,
                                  debug=debug),
        debug=debug),
                                 debug=debug)

    # print np.reshape(pts_tl, (1, 2)).shape
    # print pts_total[0, :].shape

    pts_total[0, :] = np.reshape(pts_tl, (1, 2))
    pts_total[1, :] = np.reshape(pts_tr, (1, 2))
    pts_total[2, :] = np.reshape(pts_br, (1, 2))
    pts_total[3, :] = np.reshape(pts_bl, (1, 2))
    return pts_total
Ejemplo n.º 16
0
def cart2pol_2d_degree(pts, debug=True):
    '''
    input a 2d point and convert to polar coordinate

    return for degree: [0, 360)
    '''
    if debug:
        assert istuple(pts) or islist(pts) or isnparray(pts), 'input point is not correct'
        assert np.array(pts).size == 2, 'input point is not 2d points'

    x = pts[0]
    y = pts[1]
    rho = np.sqrt(x**2 + y**2)
    phi = math.degrees(np.arctan2(y, x))
    while phi < 0:
        phi += 360
    while phi >= 360.:
        phi -= 360
        
    return (rho, phi)
Ejemplo n.º 17
0
def safe_center_bbox(input_bbox, warning=True, debug=True):
    '''
	make sure to copy the center bbox without modifying it and make the dimension to N x 4 or N x 2

	parameters:
		input_bbox: 	a list of 4 (2) elements, a listoflist of 4 (2) elements: e.g., [[1,2,3,4], [5,6,7,8]],
						a numpy array with shape or (N, 4) or (4, ) or (N, 2) or (2, )

	outputs:
		np_bboxes:		N X 4 (2) numpy array
	'''
    if islist(input_bbox):
        if islistoflist(input_bbox):
            if debug:
                assert all(
                    len(list_tmp) == 4 or len(list_tmp) == 2 for list_tmp in
                    input_bbox), 'all sub-lists should have length of 4'
            np_bboxes = np.array(input_bbox)
        else:
            if debug:
                assert len(input_bbox) == 4 or len(
                    input_bbox
                ) == 2, 'the center bboxes list does not have a good shape'
            if len(input_bbox) == 4:
                np_bboxes = np.array(input_bbox).reshape((1, 4))
            else:
                np_bboxes = np.array(input_bbox).reshape((1, 2))
    elif isnparray(input_bbox):
        input_bbox = input_bbox.copy()
        if input_bbox.shape == (4, ): np_bboxes = input_bbox.reshape((1, 4))
        elif input_bbox.shape == (2, ): np_bboxes = input_bbox.reshape((1, 2))
        else:
            if debug:
                assert iscenterbbox(
                    input_bbox
                ), 'the input center bbox numpy array does not have a good shape'
            np_bboxes = input_bbox
    else:
        assert False, 'only list and numpy array for bbox are supported'

    return np_bboxes
Ejemplo n.º 18
0
def data_normalize(input_data,
                   method='max',
                   data_range=None,
                   sum=1,
                   warning=True,
                   debug=True):
    '''
	this function normalizes N-d data in different ways: 1) normalize the data from a range to [0, 1]; 2) normalize the data which sums to a value

	parameters:
		input_data:			a list or a numpy N-d data to normalize
		method:				max:	normalize the data from a range to [0, 1], when the range is not given, the max and min are obtained from the data
							sum:	normalize the data such that all elements are summed to a value, the default value is 1
		data_range:			None or 2-element tuple, list or array
		sum:				a scalar

	outputs:
		normalized_data:	a float32 numpy array with same shape as the input data
	'''
    np_data = safe_npdata(input_data, warning=warning,
                          debug=debug).astype('float32')
    if debug:
        assert isnparray(np_data), 'the input data is not a numpy data'
        assert method in ['max',
                          'sum'], 'the method for normalization is not correct'

    if method == 'max':
        if data_range is None:
            max_value, min_value = np.max(np_data), np.min(np_data)
        else:
            if debug: assert isrange(data_range), 'data range is not correct'
            max_value, min_value = data_range[1], data_range[0]
    elif method == 'sum':
        if debug: assert isscalar(sum), 'the sum is not correct'
        max_value, min_value = np.sum(np_data) / sum, 0

    normalized_data = (np_data - min_value) / (max_value - min_value
                                               )  # normalization

    return normalized_data
Ejemplo n.º 19
0
def safe_batch_image(input_image, warning=True, debug=True):
    '''
	return a numpy image no matter what format the input is
	make sure the output numpy image is a copy of the input image

	parameters:
		input_image:		a numpy image, NHWC, float or uint

	outputs:
		np_image:			NHWC numpy image, with the same datatype as the input
		isnan:				return True if any nan value exists
	'''
    if debug:
        assert isnparray(
            input_image), 'the input image should be a numpy array'
    np_image = input_image.copy()

    if np_image.ndim == 2:
        np_image = np.expand_dims(np_image,
                                  axis=0)  # compatible with grayscale image
    if np_image.ndim == 3:  # expand HWC to NHWC batch images with batch of 1
        if debug:
            assert isnpimage(np_image), 'the image should be a numpy image'
        np_image = np.expand_dims(np_image, axis=0)
    elif np_image.ndim == 4:
        if debug:
            assert np_image.shape[-1] == 3 or np_image.shape[
                -1] == 1, 'the image shape is not good'
            for image_index in range(np_image.shape[0]):
                assert isnpimage(
                    np_image[image_index]
                ), 'each individual image should be a numpy image'
    else:
        assert False, 'only color images are supported'

    isnan = isnannparray(np_image)
    if warning and isnan: print('nan exists in the image data')

    return np_image, isnan
Ejemplo n.º 20
0
def safe_batch_deep_image(input_image, warning=True, debug=True):
    '''
	return a batch image-like deep numpy no matter what format the input is,
	the shape of input should be N3HW or 3HW,
	make sure the output numpy image is a copy of the input image

	note:
		an image-like numpy array is an array with image-like shape, but might contain arbitrary value

	parameters:
		input_image:		image-like numpy array, N3HW or 3HW, float or uint

	outputs:
		np_image:			N3HW numpy image, with the same datatype as the input
		isnan:				return True if any nan value exists
	'''
    if debug:
        assert isnparray(
            input_image), 'the input image should be a numpy array'
    np_image = input_image.copy()

    # if np_image.ndim == 2:		# expand HW gradscale image to CHW image with one channel
    # np_image = np.expand_dims(np_image, axis=0)
    if np_image.ndim == 3:  # expand CHW to NCHW batch images with batch of 1
        if debug:
            assert np_image.shape[0] == 3, 'the image should be a color image'
        np_image = np.expand_dims(np_image, axis=0)
    elif np_image.ndim == 4:
        if debug:
            assert np_image.shape[1] == 3, 'the image should be a color image'
    else:
        assert False, 'only color images are supported'

    isnan = isnannparray(np_image)
    if warning and isnan: print('nan exists in the image data')

    return np_image, isnan
Ejemplo n.º 21
0
def bbox_rotation_inv(bbox_in, angle_in_degree, image_shape, debug=True):
    '''
    bbox_in is two coordinate
    angle is clockwise
    '''
    if debug:
        assert isnparray(bbox_in) and bbox_in.size == 4, 'box is not correct'

    im_width = image_shape[1]
    im_height = image_shape[0]
    coor_in_tl = np.array([(bbox_in[0] - im_width / 2) / im_width * 2,
                           (bbox_in[1] - im_height / 2) / im_height * 2,
                           1])  # normalization
    coor_in_br = np.array([(bbox_in[2] - im_width / 2) / im_width * 2,
                           (bbox_in[3] - im_height / 2) / im_height * 2,
                           1])  # normalization
    # print(coor_in_tl)
    # print(coor_in_br)
    affine = np.array(
        [[math.cos(rad(angle_in_degree)),
          math.sin(rad(angle_in_degree)), 0],
         [-math.sin(rad(angle_in_degree)),
          math.cos(rad(angle_in_degree)), 0]])
    coor_out_tl = np.dot(coor_in_tl, affine.transpose())
    coor_out_br = np.dot(coor_in_br, affine.transpose())
    # print(coor_out_tl)
    # print(coor_out_br)
    bbox_recover = [
        coor_out_tl[0] * im_width / 2 + im_width / 2,
        coor_out_tl[1] * im_height / 2 + im_height / 2,
        coor_out_br[0] * im_width / 2 + im_width / 2,
        coor_out_br[1] * im_height / 2 + im_height / 2
    ]
    bbox_recover = np.array(bbox_recover, dtype=float)

    return bbox_recover