def rotate(img, rotation_degree: int = 180, scaling_factor: float = 1.0, order: str = 'rgb'): """ Rotate image by specified degrees anti-clockwise Params: img: (numpy.array, PIL.image, cv2.image) rotation_degree: rotation angle (in degrees) scaling_factor: 1.0 to maintain the original scale of the image. 0.5 to halve the size of the image, to double the size of the image, use 2.0. order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) # get the dimensions of the image (height, width) = img.shape[:2] # calculate the center of the image center = (width / 2, height / 2) # rotate the image by 180 degrees img_matrix = cv.getRotationMatrix2D(center, rotation_degree, scaling_factor) rotated_image = cv.warpAffine(img, img_matrix, (width, height)) return helpers.format_output_order_input_BGR(rotated_image, order)
def resize(img, interpolation_method: str = 'shrink', resize_width: int = None, resize_height: int = None, resize_percentage: float = None, order: str = 'rgb'): """ Resize (scale or shrink) image to specified dimensions Params: img: (numpy.array, PIL.image, cv2.image) interpolation_method: (s, z) s/shrink or z/zoom; default to shrink resize_percentage: (0, 100) floating value. to resize image by the specified percentage resize_width, resize_height: (in pixels) if unspecified, defaults to 50% of original img width & height. If either only width or height is specified, the other dimension is scale to keep the aspect ratio intact. Note: these will be ignored if resize_percentage is specified order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) interpolation_method = 's' # set the size of image along with interploation methods # cv2.INTER_AREA is used for shrinking, whereas cv2.INTER_LINEAR # is used for zooming if interpolation_method in ['shrink', 's']: interpolation = cv.INTER_AREA elif interpolation_method in ['zoom', 'z']: interpolation = cv.INTER_LINEAR # get number of pixel horizontally and vertically (height, width) = img.shape[:2] # set width and height pixels of transformed image if resize_percentage is not None: ratio = resize_percentage / 100 dim = (int(width * ratio), int(height * ratio)) elif resize_width is None and resize_height is not None: ratio = resize_height / img.shape[0] dim = (int(img.shape[1] * ratio), resize_height) elif resize_height is None and resize_width is not None: ratio = resize_width / img.shape[1] dim = (resize_width, int(img.shape[0] * ratio)) elif resize_height is not None and resize_width is not None: dim = (resize_width, resize_height) else: dim = (int(width / 2), int(height / 2)) res_img = cv.resize(img, dim, interpolation=interpolation) return helpers.format_output_order_input_BGR(res_img, order)
def img2grayscale(img, to_binary: bool = False, to_zero: bool = False, inverted: bool = False, trunc: bool = False, is_gray: bool = True, order: str = 'rgb'): """ BGR/RGB to Grayscale conversion Params: img: (numpy.array, PIL.image, cv2.image) thresholding_options: binary, zero, trunc, inverted binary, inverted zero order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) # convert image to grey scale if is_gray: gs_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # if thresholding/inverting if inverted: if trunc: _, gs_img = cv.threshold(gs_img, 127, 255, cv.THRESH_TRUNC) gs_img = cv.bitwise_not(gs_img) elif to_binary: _, gs_img = cv.threshold(gs_img, 120, 255, cv.THRESH_BINARY_INV) elif to_zero: _, gs_img = cv.threshold(gs_img, 120, 255, cv.THRESH_TOZERO_INV) else: gs_img = cv.bitwise_not(gs_img) else: if trunc: _, gs_img = cv.threshold(gs_img, 127, 255, cv.THRESH_TRUNC) elif to_binary: _, gs_img = cv.threshold(gs_img, 120, 255, cv.THRESH_BINARY) elif to_zero: _, gs_img = cv.threshold(gs_img, 120, 255, cv.THRESH_TOZERO) else: gs_img = img if inverted: gs_img = cv.bitwise_not(gs_img) return helpers.format_output_order_input_BGR(gs_img, order)
def blur(img, kernel_size: int, order: str): """ Averaging blur by convolving the image with a normalized box filter of kernel_size Params: img: (numpy.array, PIL.image, cv2.image) kernel_size(k): (k X k) normalized box filter for blurring """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) k = kernel_size blur_img = cv.blur(img, (k, k)) return helpers.format_output_order_input_BGR(blur_img, order)
def luminosity(img, intensity_shift: int, order: str = 'rgb'): """ Increase/decrease the brightness of the image Params: img: (numpy.array, PIL.image, cv2.image) intensity_shift: decrease or increase the brightness level order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) # get the HSV from BGR hsv = cv.cvtColor(img, cv.COLOR_BGR2HSV) hue, sat, brightness_value = cv.split(hsv) # brighten the pixels (intensity_shift > 0) if intensity_shift > 0: # prevent overflow of value limit = 255 - intensity_shift brightness_value[brightness_value > limit] = 255 # increase the brightness value brightness_value[brightness_value <= limit] += intensity_shift # darken the pixels (intensity_shift < 0) else: # prevent overflow of value limit = -(intensity_shift) brightness_value[brightness_value < limit] = 0 # decrease the brightness value brightness_value[brightness_value >= limit] -= limit # re-construct hsv final_hsv = cv.merge((hue, sat, brightness_value)) # convert hsv to BGR and return numpy.array in the order specified img = cv.cvtColor(final_hsv, cv.COLOR_HSV2BGR) return helpers.format_output_order_input_BGR(img, order)
def skew_affine(img, input_points: np.float32, output_points: np.float32, order: str = 'rgb'): """ skew image by applying affine transformation Params: img: (numpy.array, PIL.image, cv2.image) input_points: three points on input image, ex: np.float32([[50,50],[200,50],[50,200]]) output_points: three points on output location correspoinding to input_points' to be transformed, np.float32([[10,100],[200,50],[100,250]]) order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) rows, cols, _ch = img.shape img_matrix = cv.getAffineTransform(input_points, output_points) affine_skew_img = cv.warpAffine(img, img_matrix, (cols, rows)) return helpers.format_output_order_input_BGR(affine_skew_img, order)
def mirror(img, flip_code: int, order: str): """ Mirror the image Params: img: (numpy.array, PIL.image, cv2.image) flip_code: = 0 for flipping the image around the y-axis (vertical flipping); > 0 for flipping around the x-axis (horizontal flipping); < 0 for flipping around both axes order: (RGB, BGR) input order of the colors BGR/RGB. Deafult order: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) if flip_code in [0, 1, -1]: mirrored_image = cv.flip(img, flip_code) return helpers.format_output_order_input_BGR(mirrored_image, order) else: raise ValueError("flip code must be 0, 1 or -1")
def crop(img, start_x: int, end_x: int, start_y: int, end_y: int, is_percentage: bool = False, order: str = 'rgb'): """ Crop the image to specified pixel coordinates Params: img: (numpy.array, PIL.image, cv2.image) start_x: starting pixel coordinate along the x-axis/width of the image end_x: ending pixel coordinate along the x-axis/width of the image start_y: starting pixle coordinate along the y-axis/height of the image end_y: ending pixle coordinate along the y-axis/height of the image is_percentage: if True, the coordinates will be considered as percentages. Default: False order: (RGB, BGR) input order of the colors BGR/RGB. Default: RGB Note: The output will be a numpy.array of the same order Returns: numpy.array of the order specified """ # img object passed is converted to a BGR array # and all the operations are performed. The image will be converted # back to specified order and returned as numpy.array img = helpers.image2BGR(img, order) err_msg = '' # get the dimensions of the image (height, width) = img.shape[:2] # compute coordinates if params values are percentages if is_percentage: if start_x < 0 or start_x > 100: err_msg += 'start x: {} out of range 0 - 100. \n'.format(start_x) if end_x < 0 or end_x > 100: err_msg += 'end x: {} out of range 0 - 100. \n'.format(end_x) if start_y < 0 or start_y > 100: err_msg += 'start y: {} out of range 0 - 100. \n'.format(start_y) if end_y < 0 or end_y > 100: err_msg += 'end x: {} out of range 0 - 100. \n'.format(end_y) if start_x > end_x: err_msg += 'start x: {} must be less than end x: {}. \n'.format( start_x, end_x) if start_y > end_y: err_msg += 'start y: {} must be less than end y: {}. \n'.format( start_y, end_y) start_x, end_x, start_y, end_y = width * (start_x / 100), width * ( end_x / 100), height * (start_y / 100), height * (end_y / 100) else: if start_x > end_x: err_msg += 'start x: {} must be less than end x: {}. \n'.format( start_x, end_x) if start_y > end_y: err_msg += 'start y: {} must be less than end y: {}. \n'.format( start_y, end_y) if start_x < 0 or start_x > width: err_msg += 'start x: {} is out of range 0 - {}. \n'.format( start_x, width) if end_x < 0 or end_x > width: err_msg += 'end x: {} is out of range 0 - {}. \n'.format( end_x, width) if start_y < 0 or start_y > height: err_msg += 'start y: {} is out of range 0 - {}. \n'.format( start_y, height) if end_y < 0 or end_y > width: err_msg += 'end y: {} is out of range 0 - {}. \n'.format( end_y, height) if not err_msg == '': raise ValueError(err_msg) cropped_image = img[int(start_y):int(end_y), int(start_x):int(end_x)] return helpers.format_output_order_input_BGR(cropped_image, order)