Last active
January 11, 2022 16:48
-
-
Save CasiaFan/7bc120f91207a39d7e3671dd22f6b582 to your computer and use it in GitHub Desktop.
Add local brightness adjustment in parallel for image augmentation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import cv2 | |
import numpy as np | |
import random | |
from scipy.stats import norm | |
def generate_parallel_light_mask(mask_size, | |
position=None, | |
direction=None, | |
max_brightness=255, | |
min_brightness=0, | |
mode="gaussian", | |
linear_decay_rate=None): | |
""" | |
Generate decayed light mask generated by light strip given its position, direction | |
Args: | |
mask_size: tuple of integers (w, h) defining generated mask size | |
position: tuple of integers (x, y) defining the center of light strip position, | |
which is the reference point during rotating | |
direction: integer from 0 to 360 to indicate the rotation degree of light strip | |
max_brightness: integer that max brightness in the mask | |
min_brightness: integer that min brightness in the mask | |
mode: the way that brightness decay from max to min: linear or gaussian | |
linear_decay_rate: only valid in linear_static mode. Suggested value is within [0.2, 2] | |
Return: | |
light_mask: ndarray in float type consisting value from 0 to strength | |
""" | |
if position is None: | |
pos_x = random.randint(0, mask_size[0]) | |
pos_y = random.randint(0, mask_size[1]) | |
else: | |
pos_x = position[0] | |
pos_y = position[1] | |
if direction is None: | |
direction = random.randint(0, 360) | |
print("Rotate degree: ", direction) | |
if linear_decay_rate is None: | |
if mode == "linear_static": | |
linear_decay_rate = random.uniform(0.2, 2) | |
if mode == "linear_dynamic": | |
linear_decay_rate = (max_brightness - min_brightness) / max(mask_size) | |
assert mode in ["linear_dynamic", "linear_static", "gaussian"], \ | |
"mode must be linear_dynamic, linear_static or gaussian" | |
padding = int(max(mask_size) * np.sqrt(2)) | |
# add padding to satisfy cropping after rotating | |
canvas_x = padding * 2 + mask_size[0] | |
canvas_y = padding * 2 + mask_size[1] | |
mask = np.zeros(shape=(canvas_y, canvas_x), dtype=np.float32) | |
# initial mask's up left corner and bottom right corner coordinate | |
init_mask_ul = (int(padding), int(padding)) | |
init_mask_br = (int(padding+mask_size[0]), int(padding+mask_size[1])) | |
init_light_pos = (padding + pos_x, padding + pos_y) | |
# fill in mask row by row with value decayed from center | |
for i in range(canvas_y): | |
if mode == "linear": | |
i_value = _decayed_value_in_linear(i, max_brightness, init_light_pos[1], linear_decay_rate) | |
elif mode == "gaussian": | |
i_value = _decayed_value_in_norm(i, max_brightness, min_brightness, init_light_pos[1], mask_size[1]) | |
else: | |
i_value = 0 | |
mask[i] = i_value | |
# rotate mask | |
rotate_M = cv2.getRotationMatrix2D(init_light_pos, direction, 1) | |
mask = cv2.warpAffine(mask, rotate_M, (canvas_x, canvas_y)) | |
# crop | |
mask = mask[init_mask_ul[1]:init_mask_br[1], init_mask_ul[0]:init_mask_br[0]] | |
mask = np.asarray(mask, dtype=np.uint8) | |
# add median blur | |
mask = cv2.medianBlur(mask, 9) | |
mask = 255 - mask | |
# cv2.circle(mask, init_light_pos, 1, (0, 0, 255)) | |
# cv2.imshow("crop", mask[init_mask_ul[1]:init_mask_br[1], init_mask_ul[0]:init_mask_br[0]]) | |
# cv2.imshow("all", mask) | |
# cv2.waitKey(0) | |
return mask |
Author
CasiaFan
commented
Jun 25, 2018
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment