Преглед на файлове

```
refactor(image): 优化图像阴影处理算法

- 修改 get_mask_and_config_v4_online 函数参数列表,移除 opacity 和 brightness 参数
- 调整图像缩放尺寸从 1800 到 1200,新增 600 尺寸处理
- 更改 API 接口从 /segment_shadow/shadow_service 到 /segment_shadow/platform_shadow
- 替换 get_ultra_shadow 调用为 get_platform_shadow 方法
- 重构蒙版生成逻辑,添加透明图转蒙版和蒙版交集运算
- 更新调试输出信息的日志标记数字
- 修改返回值从 return_mask 改为 bg_mask 以符合新逻辑
- 在 remove_bg_ali.py 中新增 get_platform_shadow 方法实现
```

rambo преди 1 месец
родител
ревизия
8e7c5b5661
променени са 2 файла, в които са добавени 77 реда и са изтрити 43 реда
  1. 49 43
      python/service/grenerate_main_image_test.py
  2. 28 0
      python/service/remove_bg_ali.py

+ 49 - 43
python/service/grenerate_main_image_test.py

@@ -145,9 +145,8 @@ class GeneratePic(object):
         return return_mask, config
 
     @time_it
-    def get_mask_and_config_v4_online(self, ori_im_jpg: Image, ori_im_png: Image, im_jpg: Image, im_png: Image,
-                                      image_mask_opacity, image_mask_grenerate_main_pic_brightness):
-        print("42------当前计算函数:get_mask_and_config_v4_online")
+    def get_mask_and_config_v4_online(self, ori_im_jpg: Image, ori_im_png: Image, im_jpg: Image, im_png: Image):
+        print("179------当前计算函数:get_mask_and_config_v4_online")
         """
         步骤:
         1、尺寸进行对应缩小
@@ -156,33 +155,45 @@ class GeneratePic(object):
         4、输出自动色阶参数、以及放大的尺寸蒙版
         """
         # ===================尺寸进行对应缩小(提升处理速度)
-        ori_im_jpg = to_resize(ori_im_jpg, width=1800)
-        ori_im_png = to_resize(ori_im_png, width=1800)
-        # todo 上传云端返回mask
-        utrlImage = Segment()
-        try:
-            api_url = f"{settings.DOMAIN}/api/ai_image/segment_shadow/shadow_service"
-            matte_image_url = utrlImage.get_ultra_shadow(ori_im_jpg, ori_im_png, opacity=image_mask_opacity,
-                                                         bright_target=image_mask_grenerate_main_pic_brightness,
-                                                         api_url=api_url)
-            response = requests.get(matte_image_url)
+        ori_im_jpg = to_resize(ori_im_jpg, width=1200)
+        ori_im_png = to_resize(ori_im_png, width=1200)
+
+        im_jpg = to_resize(im_jpg, width=600)
+        im_png = to_resize(im_png, width=600)
+        segment = Segment()
+        api_url = f"{settings.DOMAIN}/api/ai_image/segment_shadow/platform_shadow"
+        bg_mask_image_url = segment.get_platform_shadow(ori_im_jpg, api_url=api_url)
+        if bg_mask_image_url:
+            response = requests.get(bg_mask_image_url)
             pic = response.content
-            return_mask = Image.open(BytesIO(pic))  # 阿里返回的抠图结果 已转PIL对象
-        except Exception as e:
-            print("get_mask_and_config_v4_online 异常", e)
-            return None, None
-        # todo 上传云端
-        # ori_im_jpg ori_im_png
-        # return_mask
+            bg_mask = Image.open(BytesIO(pic))  # 阿里返回的抠图结果 已转PIL对象
+            bg_mask = bg_mask.convert("L")
+            bg_mask = ImageChops.invert(bg_mask)
+            _, new_box = get_mini_crop_img(img=ori_im_png)
+            bg_mask = bg_mask.crop(new_box)  # 切图
+            bg_mask = bg_mask.resize(im_png.size)
+            # bg_mask = expand_or_shrink_mask(pil_image=bg_mask, expansion_radius=6, blur_radius=0)
+        else:
+            bg_mask = Image.new("RGB", im_png.size, (255, 255, 255))
+            bg_mask = bg_mask.convert("L")
 
-        # ====================生成新的图片
-        print("get_mask_and_config_v4_online  生成新的图片", matte_image_url)
+        # 透明图转mask 将原图扩边一些,并填充白色
+        shoe_png_mask = transparent_to_mask_pil(im_png, is_invert=False)
+        shoe_png_mask = expand_or_shrink_mask(pil_image=shoe_png_mask, expansion_radius=40, blur_radius=0)
+        shoe_png_mask = ImageChops.invert(shoe_png_mask)
+        # 两个mask 取交集
+        if bg_mask is not False:
+            # new_mask 背景+鞋子+鞋子阴影的mask
+            new_mask = mask_intersection(shoe_png_mask, bg_mask)
+        else:
+            new_mask = shoe_png_mask
 
-        # mask 复原尺寸报错一致
-        return_mask = return_mask.resize(im_png.size)
+        # 黑色表示鞋子+背景
+        # new_mask.show()
 
+        # ====================生成图片(一张图减去背景、减去阴影、减去鞋子,即只有底盘的图片,其他区域为白色)
         bg = Image.new(mode="RGB", size=im_png.size, color=(255, 255, 255))
-        bg.paste(im=im_jpg, mask=return_mask)  # 只粘贴有阴影的地方
+        bg.paste(im=im_jpg, mask=new_mask)  # 只粘贴有阴影的地方
         # bg.show()
 
         # ==================自动色阶处理======================
@@ -191,12 +202,12 @@ class GeneratePic(object):
         # 背景阴影
         im_shadow = cv2.cvtColor(_im, cv2.COLOR_BGR2GRAY)
 
-        # print("copy.copy(im_shadow)")
         _im_shadow = copy.copy(im_shadow)
+
         Midtones = 0.8
         Highlight = 235
         k = copy.copy(settings.COLOR_GRADATION_CYCLES)
-        print("get_mask_and_config_v4_online 开始循环识别")
+        print("开始循环识别")
         xunhuan = 0
         while k:
             xunhuan += 1
@@ -213,16 +224,14 @@ class GeneratePic(object):
                                        OutShadow=0,
                                        OutHighlight=255, Dim=3)
 
-            brightness_value = get_png_brightness(img_gray=_im_shadow, mask=return_mask)
+            brightness_value = get_png_brightness(img_gray=_im_shadow, mask=new_mask)
 
-            print(
-                "get_mask_and_config_v4_online----循环识别:{},Midtones:{},Highlight:{},brightness_value:{},阀值:{}".format(
-                    xunhuan,
-                    Midtones,
-                    Highlight,
-                    brightness_value,
-                    settings.GRENERATE_MAIN_PIC_BRIGHTNESS
-                ))
+            print("128----循环识别:{},Midtones:{},Highlight:{},brightness_value:{},阀值:{}".format(xunhuan,
+                                                                                                   Midtones,
+                                                                                                   Highlight,
+                                                                                                   brightness_value,
+                                                                                                   settings.GRENERATE_MAIN_PIC_BRIGHTNESS
+                                                                                                   ))
 
             if brightness_value >= settings.GRENERATE_MAIN_PIC_BRIGHTNESS:
                 break
@@ -230,21 +239,20 @@ class GeneratePic(object):
         im_shadow = cv2_to_pil(_im_shadow)
         # ========================================================
         # 计算阴影的亮度,用于确保阴影不要太黑
-
         # 1、图片预处理,只保留阴影
         only_shadow_img = im_shadow.copy()
         only_shadow_img.paste(Image.new(mode="RGBA", size=only_shadow_img.size, color=(255, 255, 255, 255)),
                               mask=im_png)
         # only_shadow_img.show()
         average_brightness = calculated_shadow_brightness(only_shadow_img)
-        print("get_mask_and_config_v4_online average_brightness:", average_brightness)
+        print("average_brightness:", average_brightness)
 
         config = {
             "Midtones": Midtones,
             "Highlight": Highlight,
             "average_brightness": average_brightness,
         }
-        return return_mask, config
+        return bg_mask, config
 
     @time_it
     def get_mask_and_config(self, im_jpg: Image, im_png: Image, curve_mask: bool):
@@ -720,11 +728,9 @@ class GeneratePic(object):
             shadow_mask, config = self.get_mask_and_config_v3(im_jpg=im_shadow, im_png=cut_image, curve_mask=curve_mask,
                                                               grenerate_main_pic_brightness=image_mask_grenerate_main_pic_brightness)
         elif image_mask_mode == 2:
-            shadow_mask, config = self.get_mask_and_config_v4_online(ori_im_jpg=orign_im, ori_im_png=cut_image_basic,
+            shadow_mask, config = self.get_mask_and_config_v4_online(ori_im_jpg=orign_im,
                                                                      im_jpg=im_shadow,
-                                                                     im_png=cut_image,
-                                                                     image_mask_opacity=image_mask_opacity,
-                                                                     image_mask_grenerate_main_pic_brightness=image_mask_grenerate_main_pic_brightness)
+                                                                     im_png=cut_image)
         else:
             shadow_mask, config = self.get_mask_and_config_v3(im_jpg=im_shadow, im_png=cut_image, curve_mask=curve_mask,
                                                               grenerate_main_pic_brightness=image_mask_grenerate_main_pic_brightness)

+ 28 - 0
python/service/remove_bg_ali.py

@@ -165,6 +165,34 @@ class Segment(object):
             return None
         return cutout_image
 
+    def get_platform_shadow(self, original_image, api_url=None):
+        image_original_url = uploadImage(original_image)
+        if not settings.USER_TOKEN:
+            print("错误:USER_TOKEN 未配置或为空")
+            return None
+        print("阴影图处理,图片上传成功", image_original_url)
+        post_headers = {"Authorization": "Bearer " + settings.USER_TOKEN}
+        data = {
+            "oraginal_image": image_original_url,
+        }
+        print("阴影处理参数:", data)
+        response = requests.post(
+            api_url, json=data, headers=post_headers
+        )
+        print(f"响应状态码: {response.status_code}")
+        print(f"响应内容: {response.text[:500]}")  # 只打印前500字符
+        resultData = response.json()
+        print("旗舰版阴影处理请求", resultData)
+        # 安全地获取返回值
+        data = resultData.get("data")
+        if data is None:
+            return None
+        oss_url = data.get("oss_url")
+        if oss_url is None:
+            print("旗舰版 阴影处理 返回的 matte_image为空")
+            return None
+        return oss_url
+
     def get_ultra_shadow(self, original_image, cutout_image, opacity, bright_target, api_url=None):
         image_original_url = uploadImage(original_image)
         image_cutcou_url = uploadImage(cutout_image)