def image_normalize(input_image, warning=True, debug=True): ''' normalize an image to an uint8 with range of [0, 255] note that: the input might not be an image because the value range might be arbitrary parameters: input_image: pil image or image-like array, color or gray, float or uint outputs: np_image: numpy uint8 image, normalized to [0, 255] ''' np_image, isnan = safe_image_like(input_image, warning=warning, debug=debug) if isuintnparray(np_image): np_image = np_image.astype('float32') / 255. else: assert isfloatnparray(np_image), 'the input image-like array should be either an uint8 or float32 array' min_val = np.min(np_image) max_val = np.max(np_image) if isnan: np_image.fill(0) elif min_val == max_val: # all same if warning: print('the input image has the same value over all the pixels') np_image.fill(0) else: # normal case np_image -= min_val np_image = ((np_image / (max_val - min_val)) * 255.).astype('uint8') if debug: assert np.min(np_image) == 0 and np.max(np_image) == 255, 'the value range is not right [%f, %f]' % (np.min(np_image), np.max(np_image)) return np_image.astype('uint8')
def preprocess_batch_deep_image(input_image, pixel_mean=None, pixel_std=None, rgb2bgr=True, warning=True, debug=True): ''' this function preprocesses batch of images to a deep image, 1: from rgb to bgr 2: normalize the batch image based on mean and std 3: convert (N)HWC to NCHW parameters: input_image: NHWC numpy color image, where C is 3, uint8 or float32 pixel_mean: a float32 numpy array mean over 3 channels with shape of (3, ) or (1, ) pixel_std: a float32 numpy array std over 3 channels with shape of (3, ) or (1, ) rgb2bgr: true if the input image is rgb format, such that the output is bgr image outputs: np_image: NCHW float32 color numpy image, bgr format ''' np_image, isnan = safe_batch_image(input_image, warning=warning, debug=debug) if debug: assert np_image.shape[-1] == 3, 'the input image should be a color image' if isuintnparray(np_image): np_image = np_image.astype('float32') / 255. else: assert isfloatnparray(np_image), 'the input image-like array should be either an uint8 or float32 array' if rgb2bgr: np_image = np_image[:, :, :, [2, 1, 0]] # from rgb to bgr, currently NHWC # normalize the numpy image data if pixel_mean is not None: pixel_mean = safe_npdata(pixel_mean, warning=warning, debug=debug) if debug: assert pixel_mean.shape == (3, ) or pixel_mean.shape == (1, ), 'pixel mean is not correct' assert (pixel_mean <= 1.0).all() and (pixel_mean >= 0.0).all(), 'mean value should be in range [0, 1].' if pixel_mean.shape == (3, ): pixel_mean_reshape = np.reshape(pixel_mean, (1, 1, 1, 3)) elif pixel_mean.shape == (1, ): pixel_mean_reshape = np.reshape(np.repeat(pixel_mean, 3), (1, 1, 1, 3)) else: assert False, 'pixel mean is not correct' np_image -= pixel_mean_reshape if pixel_std is not None: pixel_std = safe_npdata(pixel_std, warning=warning, debug=debug) if debug: assert pixel_std.shape == (3, ) or pixel_std.shape == (1, ), 'pixel std is not correct' assert (pixel_std <= 1.0).all() and (pixel_std >= 0.0).all(), 'std value should be in range [0, 1].' if pixel_std.shape == (3, ): pixel_std_reshape = np.reshape(pixel_std, (1, 1, 1, 3)) elif pixel_std.shape == (1, ): pixel_std_reshape = np.reshape(np.repeat(pixel_std, 3), (1, 1, 1, 3)) else: assert False, 'pixel std is not correct' np_image /= pixel_std_reshape np_image = np.transpose(np_image, (0, 3, 1, 2)) # NHWC to NCHW return np_image
def image_mean(input_image, warning=True, debug=True): ''' this function computes the mean image over batch of images parameters: input_image: NHWC numpy image, uint8 or float32 outputs: mean_image: HWC numpy image, uint8 ''' np_image, isnan = safe_batch_image(input_image, warning=warning, debug=debug) if isuintnparray(np_image): np_image = np_image.astype('float32') / 255. else: assert isfloatnparray(np_image), 'the input image-like array should be either an uint8 or float32 array' mean_image = (np.mean(np_image, axis=0) * 255.).astype('uint8') return mean_image
def unpreprocess_batch_deep_image(input_image, pixel_mean=None, pixel_std=None, bgr2rgb=True, warning=True, debug=True): ''' this function unpreprocesses batch of deep images, which uses chw format instead of hwc format in general 1: un-normalize the batch image based on mean and std 2: convert NCHW to NHWC 3. from bgr to rgb parameters: input_image: NCHW / CHW float32 numpy array, where C is 3 pixel_mean: a float32 numpy array mean over 3 channels with shape of (3, ) or (1, ) pixel_std: a float32 numpy array std over 3 channels with shape of (3, ) or (1, ) bgr2rgb: true if the input image is bgr format, such that the output is rgb image outputs: np_image: NHWC uint8 color numpy image, rgb format ''' np_image, isnan = safe_batch_deep_image(input_image, warning=warning, debug=debug) if debug: assert isfloatnparray(np_image), 'the input image-like array should be either an uint8 or float32 array' if pixel_std is not None: pixel_std = safe_npdata(pixel_std, warning=warning, debug=debug) if debug: assert pixel_std.shape == (3, ) or pixel_std.shape == (1, ), 'pixel std is not correct' assert (pixel_std <= 1.0).all() and (pixel_std >= 0.0).all(), 'std value should be in range [0, 1].' if pixel_std.shape == (3, ): pixel_std_reshape = np.reshape(pixel_std, (1, 3, 1, 1)) elif pixel_std.shape == (1, ): pixel_std_reshape = np.reshape(np.repeat(pixel_std, 3), (1, 3, 1, 1)) else: assert False, 'pixel std is not correct' np_image *= pixel_std_reshape if pixel_mean is not None: pixel_mean = safe_npdata(pixel_mean, warning=warning, debug=debug) if debug: assert pixel_mean.shape == (3, ) or pixel_mean.shape == (1, ), 'pixel mean is not correct' assert (pixel_mean <= 1.0).all() and (pixel_mean >= 0.0).all(), 'mean value should be in range [0, 1].' if pixel_mean.shape == (3, ): pixel_mean_reshape = np.reshape(pixel_mean, (1, 3, 1, 1)) elif pixel_mean.shape == (1, ): pixel_mean_reshape = np.reshape(np.repeat(pixel_mean, 3), (1, 3, 1, 1)) else: assert False, 'pixel mean is not correct' np_image += pixel_mean_reshape np_image = np.transpose(np_image, (0, 2, 3, 1)) # permute to [batch, height, weight, channel] if bgr2rgb: np_image = np_image[:, :, :, [2, 1, 0]] # from bgr to rgb for color image np_image = (np.clip(np_image, 0.0, 1.0) * 255.).astype('uint8') return np_image