Skip to content

Commit

Permalink
More progress on hue/sat. Feathering still needs work
Browse files Browse the repository at this point in the history
  • Loading branch information
chrisfreilich committed May 2, 2024
1 parent 6961c4f commit 32fed47
Showing 1 changed file with 30 additions and 7 deletions.
37 changes: 30 additions & 7 deletions colors.py
Original file line number Diff line number Diff line change
Expand Up @@ -445,8 +445,7 @@ def do_hue_sat(self, image, hue_low, hue_low_feather, hue_high, hue_high_feather

# Convert image to HSV and build mask
image_hsv = rgb_to_hsv(image)
mask = create_mask(image_hsv[..., 0], hue_low, hue_high, hue_low_feather, hue_high_feather)

mask = create_mask(image_hsv[..., 0], image_hsv[..., 1], hue_low, hue_high, hue_low_feather, hue_high_feather)
# Adjust hue
image_hsv[..., 0] = adjust_hue(image_hsv[..., 0], hue_offset)

Expand Down Expand Up @@ -552,7 +551,7 @@ def hsv_to_rgb(hsv: torch.Tensor) -> torch.Tensor:

return rgb_tensor

def create_mask(hue, hue_low, hue_high, hue_low_feather, hue_high_feather):
def create_mask(hue, saturation, hue_low, hue_high, hue_low_feather, hue_high_feather):
# Normalize the values to the range [0, 1]
hue_low_norm = hue_low / 360.0
hue_high_norm = hue_high / 360.0
Expand All @@ -561,17 +560,26 @@ def create_mask(hue, hue_low, hue_high, hue_low_feather, hue_high_feather):

# Calculate the mask
if hue_low_norm < hue_high_norm:
mask_low = smoothstep(hue_low_norm - hue_low_feather_norm, hue_low_norm, hue)
mask_high = smoothstep(hue_high_norm, hue_high_norm + hue_high_feather_norm, hue)
mask_low = linearstep(hue_low_norm - hue_low_feather_norm, hue_low_norm, hue)
mask_high = linearstep(hue_high_norm, hue_high_norm + hue_high_feather_norm, hue)
mask_middle = torch.where((hue >= hue_low_norm) & (hue <= hue_high_norm), torch.tensor(1.0), torch.tensor(0.0))
else:
mask_low = smoothstep(hue_low_norm, hue_low_norm + hue_low_feather_norm, hue)
mask_high = smoothstep(hue_high_norm - hue_high_feather_norm, hue_high_norm, hue)
mask_low = linearstep(hue_low_norm, hue_low_norm + hue_low_feather_norm, hue)
mask_high = linearstep(hue_high_norm - hue_high_feather_norm, hue_high_norm, hue)
mask_middle = torch.where((hue >= hue_low_norm) | (hue <= hue_high_norm), torch.tensor(1.0), torch.tensor(0.0))

# Calculate the final mask by taking the maximum value among the three masks
mask = torch.max(torch.max(mask_low, mask_middle), mask_high)

# Only select pixels with a saturation greater than 0
mask = torch.where(saturation > 0, mask, torch.tensor(0.0))

# Save the tensors as grayscale PNG images
save_image(mask_low.unsqueeze(0), 'C:/Users/chris/Desktop/mask_low.png')
save_image(mask_high.unsqueeze(0), 'C:/Users/chris/Desktop/mask_high.png')
save_image(mask_middle.unsqueeze(0), 'C:/Users/chris/Desktop/mask_middle.png')
save_image(mask.unsqueeze(0), 'C:/Users/chris/Desktop/mask.png')

return mask

def save_hsv_components(image_hsv):
Expand All @@ -594,6 +602,13 @@ def count_out_of_range_values(tensor):
print(f"The total number of unique values not in the range [0, 1] is {len(out_of_range_values)}")
print(out_of_range_values)

def linearstep(edge0, edge1, x):
# Return 0 for values outside the range [edge0, edge1]
x = torch.where((x < edge0) | (x > edge1), torch.tensor(0.0), x)
# Scale x to 0..1 range
x = (x - edge0) / (edge1 - edge0)
return x

def smoothstep(edge0, edge1, x):
# Scale, bias and saturate x to 0..1 range
x = (x - edge0) / (edge1 - edge0)
Expand All @@ -602,6 +617,14 @@ def smoothstep(edge0, edge1, x):
# Evaluate polynomial
return x * x * (3 - 2 * x)

def smootherstep(edge0, edge1, x):
# Scale, and clamp x to 0..1 range
x = torch.clamp((x - edge0) / (edge1 - edge0), 0.0, 1.0)
# Return 0 for values outside the range [0, 1]
x = torch.where((x < 0) | (x > 1), torch.tensor(0.0), x)
# Evaluate quintic polynomial
return x * x * x * (x * (x * 6 - 15) + 10)

def adjust_saturation(saturation, sat_offset):
# Calculate the change in saturation
if sat_offset < 0:
Expand Down

0 comments on commit 32fed47

Please sign in to comment.