Переглянути джерело

feat(image): 添加旗舰AI抠图精细模式支持

- 在api.py中新增"旗舰AI抠图-精细"模式映射为cutOutMode "4"
- 在base_deal.py中添加对应的模式字符串处理逻辑
- 为cutout_mode "4"实现精细化抠图处理流程
- 新增ultra_segment_fast方法提供快速旗舰抠图功能
- 在message_handler.py中补充新抠图模式的处理分支
- 实现基于CV的图像处理和mask优化功能
rambo 1 місяць тому
батько
коміт
596361386e

+ 2 - 0
python/api.py

@@ -500,6 +500,8 @@ async def _build_config_data(params, goods_art_no_arrays):
             cutOutMode = "2"
         case "旗舰AI抠图":
             cutOutMode = "3"
+        case "旗舰AI抠图-精细":
+            cutOutMode = "4"
         case _:
             cutOutMode = "1"
 

+ 8 - 0
python/service/base_deal.py

@@ -582,6 +582,8 @@ class BaseDealImage(object):
                 cutout_mode_str = "精细化抠图"
             case "3":
                 cutout_mode_str = "旗舰AI抠图"
+            case "旗舰AI抠图-精细":
+                cutout_mode_str = "4"
         logger.info(f"当前抠图模式:{cutout_mode_str}")
         """
         处理所有的抠图
@@ -663,6 +665,12 @@ class BaseDealImage(object):
                                     )
                                 if cutout_mode == "3":
                                     remove_pic_ins = RemoveUltraBackground()
+                                    im = remove_pic_ins.ultra_segment_fast(
+                                        file_path=original_image_path,
+                                        out_file_path=original_move_bg_image_path,
+                                    )
+                                if cutout_mode == "4":
+                                    remove_pic_ins = RemoveUltraBackground()
                                     im = remove_pic_ins.run_ultra_segment(
                                         file_path=original_image_path,
                                         out_file_path=original_move_bg_image_path,

+ 75 - 0
python/service/remove_bg_ali.py

@@ -623,6 +623,81 @@ class RemoveUltraBackground:
 
         return _img
 
+    @func_set_timeout(40)
+    def ultra_segment_fast(self, file_path, out_file_path=None):
+        '''
+        旗舰抠图快速版
+        '''
+        original_pic = Picture(file_path)
+        original_pic.im = self.segment.get_image_orientation(original_pic.im)
+        original_pic.x, original_pic.y = original_pic.im.size
+        if original_pic.im.mode != "RGB":
+            print("抠图图片不能是PNG")
+            return None
+
+        new_pic = copy.copy(original_pic)
+        after_need_resize = False
+        if new_pic.x > new_pic.y:
+            if new_pic.x > 2000:
+                after_need_resize = True
+                new_pic.resize(2000)
+        else:
+            if new_pic.y > 2000:
+                after_need_resize = True
+                new_pic.resize_by_heigh(heigh=2000)
+        print("使用旗舰版抠图")
+        try:
+            api_url = f"{settings.DOMAIN}{self.api_url}"
+            image_url = self.segment.get_bo_bg_goods_ultra_background(im=new_pic.im, api_url=api_url)
+        except BaseException as e:
+            print("旗舰版抠图异常:", e)
+            # 处理失败,需要删除过程图片
+            return None
+        if image_url is None:
+            return None
+        # 字节流转PIL对象
+        print("image_url", image_url)
+        response = requests.get(image_url)
+        pic = response.content
+        _img_im = Image.open(BytesIO(pic))  # 阿里返回的抠图结果 已转PIL对象
+        # 原图更大,则需要执行CV处理
+        if after_need_resize:
+            # 将抠图结果转成mask
+            # _img_im = Image.open(_path)
+            # 将抠图结果放大到原始图大小
+            _img_im = _img_im.resize(original_pic.im.size)
+            new_big_mask = Image.new('RGB', _img_im.size, (0, 0, 0))
+            white = Image.new('RGB', _img_im.size, (255, 255, 255))
+            new_big_mask.paste(white, mask=_img_im.split()[3])
+
+            # ---------制作选区缩小的mask
+            # mask = cv2.imread(mask_path)
+            # mask = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)
+            mask = cv2.cvtColor(np.asarray(new_big_mask), cv2.COLOR_BGR2GRAY)  # 将PIL 格式转换为 CV对象
+            mask[mask != 255] = 0
+            # 黑白反转
+            # mask = 255 - mask
+            # 选区缩小10
+            kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10))
+            erode_im = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
+
+            # -------再进行抠图处理
+            mask = Image.fromarray(cv2.cvtColor(erode_im, cv2.COLOR_GRAY2RGBA))  # CV 对象转 PIL
+            transparent_im = Image.new('RGBA', original_pic.im.size, (0, 0, 0, 0))
+            # original_pic.im.show()
+            # mask.show()
+            transparent_im.paste(original_pic.im, (0, 0), mask.convert('L'))
+            # transparent_im.show()
+            # 上述抠图结果进行拼接
+            _img_im.paste(transparent_im, (0, 0), transparent_im)
+        # 原图更大,则需要执行CV处理
+        if out_file_path:
+            self.saver.save_image(
+                image=_img_im, file_path=out_file_path,
+                quality=100, dpi=(350, 350), _format="PNG"
+            )
+        return _img_im
+
     def run_ultra_segment(self, file_path, out_file_path):
         # 直接调用抠图
         time.sleep(0.01)

+ 2 - 0
python/sockets/message_handler.py

@@ -756,6 +756,8 @@ async def handlerSend(
                     cutOutMode = "2"
                 case "旗舰AI抠图":
                     cutOutMode = "3"
+                case "旗舰AI抠图-精细":
+                    cutOutMode = "4"
                 case _:
                     cutOutMode = "1"
             config_data = {