fix(v5): preserve grayscale gradient masks

This commit is contained in:
2026-07-09 20:09:22 +08:00
parent 38faff0ed0
commit 47d6af6abc
2 changed files with 37 additions and 1 deletions

View File

@@ -327,6 +327,7 @@ def gradient_abs_sum(image, params):
Use it to emphasize prominent edges before combining them with a sharpened image.
"""
grayscale_input = image.ndim == 2
operator = params.get("operator", "sobel")
gray = to_gray(image).astype(np.float32)
if operator == "roberts":
@@ -337,7 +338,8 @@ def gradient_abs_sum(image, params):
gy = np.array([[-1, 0, 1], [-2, 0, 2], [-1, 0, 1]], dtype=np.float32)
fx = cv2.filter2D(gray, cv2.CV_32F, gx, borderType=cv2.BORDER_REFLECT)
fy = cv2.filter2D(gray, cv2.CV_32F, gy, borderType=cv2.BORDER_REFLECT)
return gray_to_rgb(normalize_to_uint8(np.abs(fx) + np.abs(fy)))
gradient = normalize_to_uint8(np.abs(fx) + np.abs(fy))
return gradient if grayscale_input else gray_to_rgb(gradient)
def rgb_channel(image, params):

View File

@@ -385,6 +385,40 @@ class ApiTests(TestCase):
self.assertEqual(noisy.data["channels"], 1)
self.assertEqual(noisy.data["color_mode"], "L")
def test_gradient_mask_from_grayscale_can_combine_with_grayscale_state(self):
upload = self.client.post("/api/images/", {"image": png_upload()}, format="multipart")
s0_id = upload.data["states"][0]["state_id"]
gray = self.client.post(
f"/api/states/{s0_id}/operations/",
{"operation": "rgb_to_gray", "params": {"red_weight": 0.299, "green_weight": 0.587, "blue_weight": 0.114}},
format="json",
)
gradient = self.client.post(
f"/api/states/{gray.data['state_id']}/operations/",
{"operation": "gradient_abs_sum", "params": {"operator": "sobel"}},
format="json",
)
self.assertEqual(gradient.status_code, 201)
self.assertEqual(gradient.data["channels"], 1)
self.assertEqual(gradient.data["color_mode"], "L")
added = self.client.post(
"/api/states/combine/",
{"operation": "add", "state_ids": [gray.data["state_id"], gradient.data["state_id"]]},
format="json",
)
subtracted = self.client.post(
"/api/states/combine/",
{"operation": "subtract", "state_ids": [gray.data["state_id"], gradient.data["state_id"]]},
format="json",
)
self.assertEqual(added.status_code, 201)
self.assertEqual(added.data["channels"], 1)
self.assertEqual(subtracted.status_code, 201)
self.assertEqual(subtracted.data["channels"], 1)
@patch("processing.services.run_batch_job.delay")
def test_batch_returns_job_id(self, delay):
first = self.client.post("/api/images/", {"image": png_upload(name="a.png")}, format="multipart")