Ver código fonte

fix results (#3367)

* remove useless codes

* fix JsonMixin to support indent and ensure_ascii
Tingquan Gao 9 meses atrás
pai
commit
cb29f1377b

+ 10 - 5
paddlex/inference/common/result/mixin.py

@@ -144,24 +144,29 @@ class JsonMixin:
             mime_type, _ = mimetypes.guess_type(file_path)
             return mime_type is not None and mime_type == "application/json"
 
-        json = self._to_json()
+        json_data = self._to_json()
         if not _is_json_file(save_path):
             fn = Path(self._get_input_fn())
             stem = fn.stem
             base_save_path = Path(save_path)
-            for key in json:
+            for key in json_data:
                 save_path = base_save_path / f"{stem}_{key}.json"
                 self._json_writer.write(
-                    save_path.as_posix(), json[key], *args, **kwargs
+                    save_path.as_posix(),
+                    json_data[key],
+                    indent=indent,
+                    ensure_ascii=ensure_ascii,
+                    *args,
+                    **kwargs,
                 )
         else:
-            if len(json) > 1:
+            if len(json_data) > 1:
                 logging.warning(
                     f"The result has multiple json files need to be saved. But the `save_path` has been specfied as `{save_path}`!"
                 )
             self._json_writer.write(
                 save_path,
-                json[list(json.keys())[0]],
+                json_data[list(json_data.keys())[0]],
                 indent=indent,
                 ensure_ascii=ensure_ascii,
                 *args,

+ 0 - 31
paddlex/inference/results/__init__.py

@@ -1,31 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from .base import BaseResult
-from .clas import TopkResult, MLClassResult
-from .text_det import TextDetResult
-from .text_rec import TextRecResult
-from .table_rec import TableRecResult, StructureTableResult, TableResult
-from .seal_rec import SealOCRResult
-from .ocr import OCRResult
-from .det import DetResult
-from .seg import SegResult
-from .formula_rec import FormulaRecResult, FormulaResult, FormulaVisualResult
-from .instance_seg import InstanceSegResult
-from .ts import TSFcResult, TSAdResult, TSClsResult
-from .warp import DocTrResult
-from .chat_ocr import *
-from .shitu import ShiTuResult
-from .face_rec import FaceRecResult
-from .attribute_rec import AttributeRecResult

+ 0 - 89
paddlex/inference/results/attribute_rec.py

@@ -1,89 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import cv2
-import numpy as np
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-
-from .base import CVResult
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-from ..utils.color_map import get_colormap, font_colormap
-
-
-def draw_attribute_result(img, boxes):
-    """
-    Args:
-        img (PIL.Image.Image): PIL image
-        boxes (list): a list of dictionaries representing detection box information.
-    Returns:
-        img (PIL.Image.Image): visualized image
-    """
-    font_size = int((0.024 * int(img.width) + 2) * 0.7)
-    font = ImageFont.truetype(PINGFANG_FONT_FILE_PATH, font_size, encoding="utf-8")
-
-    draw_thickness = int(max(img.size) * 0.005)
-    draw = ImageDraw.Draw(img)
-    label2color = {}
-    catid2fontcolor = {}
-    color_list = get_colormap(rgb=True)
-
-    for i, dt in enumerate(boxes):
-        text_lines, bbox, score = dt["label"], dt["coordinate"], dt["score"]
-        if i not in label2color:
-            color_index = i % len(color_list)
-            label2color[i] = color_list[color_index]
-            catid2fontcolor[i] = font_colormap(color_index)
-        color = tuple(label2color[i]) + (255,)
-        font_color = tuple(catid2fontcolor[i])
-
-        xmin, ymin, xmax, ymax = bbox
-        # draw box
-        draw.line(
-            [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin), (xmin, ymin)],
-            width=draw_thickness,
-            fill=color,
-        )
-        # draw label
-        current_y = ymin
-        for line in text_lines:
-            if tuple(map(int, PIL.__version__.split("."))) <= (10, 0, 0):
-                tw, th = draw.textsize(line, font=font)
-            else:
-                left, top, right, bottom = draw.textbbox((0, 0), line, font)
-                tw, th = right - left, bottom - top + 4
-
-            draw.text((5 + xmin + 1, current_y + 1), line, fill=(0, 0, 0), font=font)
-            draw.text((5 + xmin, current_y), line, fill=color, font=font)
-            current_y += th
-    return img
-
-
-class AttributeRecResult(CVResult):
-
-    def _to_img(self):
-        """apply"""
-        image = self._img_reader.read(self["input_path"])
-        boxes = [
-            {
-                "coordinate": box["coordinate"],
-                "label": box["labels"],
-                "score": box["det_score"],
-            }
-            for box in self["boxes"]
-            if box["det_score"] > 0.5
-        ]
-        image = draw_attribute_result(image, boxes)
-        return image

+ 0 - 43
paddlex/inference/results/base.py

@@ -1,43 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import inspect
-
-from ...utils.func_register import FuncRegister
-from ..utils.io import ImageReader, ImageWriter
-from .utils.mixin import JsonMixin, ImgMixin, StrMixin
-
-
-class BaseResult(dict, StrMixin, JsonMixin):
-    def __init__(self, data):
-        super().__init__(data)
-        self._show_funcs = []
-        StrMixin.__init__(self)
-        JsonMixin.__init__(self)
-
-    def save_all(self, save_path):
-        for func in self._show_funcs:
-            signature = inspect.signature(func)
-            if "save_path" in signature.parameters:
-                func(save_path=save_path)
-            else:
-                func()
-
-
-class CVResult(BaseResult, ImgMixin):
-    def __init__(self, data):
-        super().__init__(data)
-        ImgMixin.__init__(self, "pillow")
-        self._img_reader = ImageReader(backend="pillow")
-        self._img_writer = ImageWriter(backend="pillow")

+ 0 - 158
paddlex/inference/results/chat_ocr.py

@@ -1,158 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import copy
-from pathlib import Path
-from .base import BaseResult
-from .utils.mixin import Base64Mixin
-
-
-class LayoutParsingResult(BaseResult):
-    """LayoutParsingResult"""
-
-    pass
-
-
-class VisualInfoResult(BaseResult):
-    """VisualInfoResult"""
-
-    pass
-
-
-class VisualResult(BaseResult):
-    """VisualInfoResult"""
-
-    def __init__(self, data, page_id=None, src_input_name=None):
-        super().__init__(data)
-        self.page_id = page_id
-        if isinstance(src_input_name, list):
-            self.src_input_name = src_input_name[page_id]
-        else:
-            self.src_input_name = src_input_name
-
-    def _to_str(self, _, *args, **kwargs):
-        return super()._to_str(
-            {"layout_parsing_result": self["layout_parsing_result"]}, *args, **kwargs
-        )
-
-    def get_target_name(self, save_path):
-        if self.src_input_name.endswith(".pdf"):
-            save_path = (
-                Path(save_path)
-                / f"{Path(self.src_input_name).stem}_pdf"
-                / Path("page_{:04d}".format(self.page_id + 1))
-            )
-        else:
-            save_path = Path(save_path) / f"{Path(self.src_input_name).stem}"
-        return save_path
-
-    def save_to_json(self, save_path):
-        if not save_path.lower().endswith(("json")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        layout_save_path = f"{save_path}_layout.jpg"
-        ocr_save_path = f"{save_path}_ocr.jpg"
-        table_save_path = f"{save_path}_table"
-        table_result_num = len(self["table_result"])
-        for idx in range(table_result_num):
-            self["table_result"][idx]["input_path"] = "{}_{:04d}".format(
-                table_save_path, idx + 1
-            )
-
-        if not str(save_path).endswith(".json"):
-            save_path = "{}.json".format(save_path)
-        super().save_to_json(save_path)
-
-    def save_to_html(self, save_path):
-        if not save_path.lower().endswith(("html")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        table_save_path = f"{save_path}_table"
-        for idx, table_result in enumerate(self["table_result"]):
-            basename = (Path(table_result["input_path"]).name).split(".")[0]
-            table_result["input_path"] = Path(
-                str(table_result["input_path"]).replace(
-                    basename, "{}_{:04d}".format(table_save_path, idx + 1)
-                )
-            )
-            table_result.save_to_html(save_path)
-
-    def save_to_xlsx(self, save_path):
-        if not save_path.lower().endswith(("xlsx")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        table_save_path = f"{save_path}_table"
-        for idx, table_result in enumerate(self["table_result"]):
-            basename = (Path(table_result["input_path"]).name).split(".")[0]
-            table_result["input_path"] = Path(
-                str(table_result["input_path"]).replace(
-                    basename, "{}_{:04d}".format(table_save_path, idx + 1)
-                )
-            )
-            table_result.save_to_xlsx(save_path)
-
-    def save_to_img(self, save_path):
-        if not save_path.lower().endswith((".jpg", ".png")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-
-        oricls_save_path = f"{save_path}_oricls.jpg"
-        oricls_result = self["oricls_result"]
-        if oricls_result:
-            oricls_result.save_to_img(oricls_save_path)
-        uvdoc_save_path = f"{save_path}_uvdoc.jpg"
-        unwarp_result = self["unwarp_result"]
-        if unwarp_result:
-            unwarp_result.save_to_img(uvdoc_save_path)
-        curve_save_path = f"{save_path}_curve"
-        curve_results = self["curve_result"]
-        # TODO(): support list of result
-        if isinstance(curve_results, dict):
-            curve_results = [curve_results]
-        for idx, curve_result in enumerate(curve_results):
-            curve_result.save_to_img(f"{curve_save_path}_{idx}.jpg")
-        layout_save_path = f"{save_path}_layout.jpg"
-        layout_result = self["layout_result"]
-        if layout_result:
-            layout_result.save_to_img(layout_save_path)
-        ocr_save_path = f"{save_path}_ocr.jpg"
-        table_save_path = f"{save_path}_table"
-        ocr_result = self["ocr_result"]
-        if ocr_result:
-            ocr_result.save_to_img(ocr_save_path)
-        for idx, table_result in enumerate(self["table_result"]):
-            table_result.save_to_img(f"{table_save_path}_{idx}.jpg")
-
-
-class VectorResult(BaseResult, Base64Mixin):
-    """VisualInfoResult"""
-
-    def _to_base64(self):
-        return self["vector"]
-
-
-class RetrievalResult(BaseResult):
-    """VisualInfoResult"""
-
-    pass
-
-
-class ChatResult(BaseResult):
-    """VisualInfoResult"""
-
-    pass

+ 0 - 133
paddlex/inference/results/clas.py

@@ -1,133 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-import numpy as np
-import cv2
-
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-from ..utils.color_map import get_colormap
-from .base import CVResult
-
-
-class TopkResult(CVResult):
-
-    def _to_img(self):
-        """Draw label on image"""
-        labels = self.get("label_names", self["class_ids"])
-        label_str = f"{labels[0]} {self['scores'][0]:.2f}"
-
-        image = self._img_reader.read(self["input_path"])
-        image_size = image.size
-        draw = ImageDraw.Draw(image)
-        min_font_size = int(image_size[0] * 0.02)
-        max_font_size = int(image_size[0] * 0.05)
-        for font_size in range(max_font_size, min_font_size - 1, -1):
-            font = ImageFont.truetype(
-                PINGFANG_FONT_FILE_PATH, font_size, encoding="utf-8"
-            )
-            if tuple(map(int, PIL.__version__.split("."))) <= (10, 0, 0):
-                text_width_tmp, text_height_tmp = draw.textsize(label_str, font)
-            else:
-                left, top, right, bottom = draw.textbbox((0, 0), label_str, font)
-                text_width_tmp, text_height_tmp = right - left, bottom - top
-            if text_width_tmp <= image_size[0]:
-                break
-            else:
-                font = ImageFont.truetype(PINGFANG_FONT_FILE_PATH, min_font_size)
-        color_list = get_colormap(rgb=True)
-        color = tuple(color_list[0])
-        font_color = tuple(self._get_font_colormap(3))
-        if tuple(map(int, PIL.__version__.split("."))) <= (10, 0, 0):
-            text_width, text_height = draw.textsize(label_str, font)
-        else:
-            left, top, right, bottom = draw.textbbox((0, 0), label_str, font)
-            text_width, text_height = right - left, bottom - top
-
-        rect_left = 3
-        rect_top = 3
-        rect_right = rect_left + text_width + 3
-        rect_bottom = rect_top + text_height + 6
-
-        draw.rectangle([(rect_left, rect_top), (rect_right, rect_bottom)], fill=color)
-
-        text_x = rect_left + 3
-        text_y = rect_top
-        draw.text((text_x, text_y), label_str, fill=font_color, font=font)
-        return image
-
-    def _get_font_colormap(self, color_index):
-        """
-        Get font colormap
-        """
-        dark = np.array([0x14, 0x0E, 0x35])
-        light = np.array([0xFF, 0xFF, 0xFF])
-        light_indexs = [0, 3, 4, 8, 9, 13, 14, 18, 19]
-        if color_index in light_indexs:
-            return light.astype("int32")
-        else:
-            return dark.astype("int32")
-
-
-class MLClassResult(TopkResult):
-    def _to_img(self):
-        """Draw label on image"""
-        image = self._img_reader.read(self["input_path"])
-        label_names = self["label_names"]
-        scores = self["scores"]
-        image = image.convert("RGB")
-        image_width, image_height = image.size
-        font_size = int(image_width * 0.06)
-
-        font = ImageFont.truetype(PINGFANG_FONT_FILE_PATH, font_size)
-        text_lines = []
-        row_width = 0
-        row_height = 0
-        row_text = "\t"
-        for label_name, score in zip(label_names, scores):
-            text = f"{label_name}({score})\t"
-            if int(PIL.__version__.split(".")[0]) < 10:
-                text_width, row_height = font.getsize(text)
-            else:
-                text_width, row_height = font.getbbox(text)[2:]
-            if row_width + text_width <= image_width:
-                row_text += text
-                row_width += text_width
-            else:
-                text_lines.append(row_text)
-                row_text = "\t" + text
-                row_width = text_width
-        text_lines.append(row_text)
-        color_list = get_colormap(rgb=True)
-        color = tuple(color_list[0])
-        new_image_height = image_height + len(text_lines) * int(row_height * 1.2)
-        new_image = Image.new("RGB", (image_width, new_image_height), color)
-        new_image.paste(image, (0, 0))
-
-        draw = ImageDraw.Draw(new_image)
-        font_color = tuple(self._get_font_colormap(3))
-        for i, text in enumerate(text_lines):
-            if int(PIL.__version__.split(".")[0]) < 10:
-                text_width, _ = font.getsize(text)
-            else:
-                text_width, _ = font.getbbox(text)[2:]
-            draw.text(
-                (0, image_height + i * int(row_height * 1.2)),
-                text,
-                fill=font_color,
-                font=font,
-            )
-        return new_image

+ 0 - 100
paddlex/inference/results/det.py

@@ -1,100 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import cv2
-import numpy as np
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-from ..utils.color_map import get_colormap, font_colormap
-from .base import CVResult
-
-
-def draw_box(img, boxes):
-    """
-    Args:
-        img (PIL.Image.Image): PIL image
-        boxes (list): a list of dictionaries representing detection box information.
-    Returns:
-        img (PIL.Image.Image): visualized image
-    """
-    font_size = int(0.018 * int(img.width)) + 2
-    font = ImageFont.truetype(PINGFANG_FONT_FILE_PATH, font_size, encoding="utf-8")
-
-    draw_thickness = int(max(img.size) * 0.002)
-    draw = ImageDraw.Draw(img)
-    label2color = {}
-    catid2fontcolor = {}
-    color_list = get_colormap(rgb=True)
-
-    for i, dt in enumerate(boxes):
-        # clsid = dt["cls_id"]
-        label, bbox, score = dt["label"], dt["coordinate"], dt["score"]
-        if label not in label2color:
-            color_index = i % len(color_list)
-            label2color[label] = color_list[color_index]
-            catid2fontcolor[label] = font_colormap(color_index)
-        color = tuple(label2color[label])
-        font_color = tuple(catid2fontcolor[label])
-
-        if len(bbox) == 4:
-            # draw bbox of normal object detection
-            xmin, ymin, xmax, ymax = bbox
-            rectangle = [(xmin, ymin), (xmin, ymax), (xmax, ymax), (xmax, ymin), (xmin, ymin)]
-        elif len(bbox) == 8:
-            # draw bbox of rotated object detection
-            x1, y1, x2, y2, x3, y3, x4, y4 = bbox
-            rectangle = [(x1, y1), (x2, y2), (x3, y3), (x4, y4), (x1, y1)]
-            xmin = min(x1, x2, x3, x4)
-            ymin = min(y1, y2, y3, y4)
-        else:
-            raise ValueError(
-                f"Only support bbox format of [xmin,ymin,xmax,ymax] or [x1,y1,x2,y2,x3,y3,x4,y4], got bbox of shape {len(bbox)}."
-            )
-        
-        # draw bbox
-        draw.line(
-            rectangle,
-            width=draw_thickness,
-            fill=color,
-        )
-
-        # draw label
-        text = "{} {:.2f}".format(dt["label"], score)
-        if tuple(map(int, PIL.__version__.split("."))) <= (10, 0, 0):
-            tw, th = draw.textsize(text, font=font)
-        else:
-            left, top, right, bottom = draw.textbbox((0, 0), text, font)
-            tw, th = right - left, bottom - top + 4
-        if ymin < th:
-            draw.rectangle([(xmin, ymin), (xmin + tw + 4, ymin + th + 1)], fill=color)
-            draw.text((xmin + 2, ymin - 2), text, fill=font_color, font=font)
-        else:
-            draw.rectangle([(xmin, ymin - th), (xmin + tw + 4, ymin + 1)], fill=color)
-            draw.text((xmin + 2, ymin - th - 2), text, fill=font_color, font=font)
-
-    return img
-
-
-class DetResult(CVResult):
-    """Save Result Transform"""
-
-    def _to_img(self):
-        """apply"""
-        boxes = self["boxes"]
-        image = self._img_reader.read(self["input_path"])
-        image = draw_box(image, boxes)
-        return image

+ 0 - 34
paddlex/inference/results/face_rec.py

@@ -1,34 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import numpy as np
-from .base import CVResult
-from .det import draw_box
-
-
-class FaceRecResult(CVResult):
-
-    def _to_img(self):
-        """apply"""
-        image = self._img_reader.read(self["input_path"])
-        boxes = [
-            {
-                "coordinate": box["coordinate"],
-                "label": box["labels"][0] if box["labels"] is not None else "Unknown",
-                "score": box["rec_scores"][0] if box["rec_scores"] is not None else 0,
-            }
-            for box in self["boxes"]
-        ]
-        image = draw_box(image, boxes)
-        return image

+ 0 - 363
paddlex/inference/results/formula_rec.py

@@ -1,363 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import sys
-import cv2
-import math
-import random
-import tempfile
-import subprocess
-import numpy as np
-from pathlib import Path
-from PIL import Image, ImageDraw
-
-from .base import BaseResult, CVResult
-from ...utils import logging
-from .ocr import draw_box_txt_fine
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-
-
-class FormulaRecResult(CVResult):
-    def _to_str(self, *args, **kwargs):
-        return super()._to_str(*args, **kwargs).replace("\\\\", "\\")
-
-    def _to_img(
-        self,
-    ):
-        """Draw formula on image"""
-        try:
-            env_valid()
-        except subprocess.CalledProcessError as e:
-            logging.warning(
-                "Please refer to 2.3 Formula Recognition Pipeline Visualization in Formula Recognition Pipeline Tutorial to install the LaTeX rendering engine at first."
-            )
-            return None
-
-        image = self._img_reader.read(self["input_path"])
-        rec_formula = str(self["rec_text"])
-        image = np.array(image.convert("RGB"))
-        xywh = crop_white_area(image)
-        if xywh is not None:
-            x, y, w, h = xywh
-            image = image[y : y + h, x : x + w]
-        image = Image.fromarray(image)
-        image_width, image_height = image.size
-        box = [[0, 0], [image_width, 0], [image_width, image_height], [0, image_height]]
-        try:
-            img_formula = draw_formula_module(
-                image.size, box, rec_formula, is_debug=False
-            )
-            img_formula = Image.fromarray(img_formula)
-            render_width, render_height = img_formula.size
-            resize_height = render_height
-            resize_width = int(resize_height * image_width / image_height)
-            image = image.resize((resize_width, resize_height), Image.LANCZOS)
-
-            new_image_width = image.width + int(render_width) + 10
-            new_image = Image.new(
-                "RGB", (new_image_width, render_height), (255, 255, 255)
-            )
-            new_image.paste(image, (0, 0))
-            new_image.paste(img_formula, (image.width + 10, 0))
-            return new_image
-        except subprocess.CalledProcessError as e:
-            logging.warning("Syntax error detected in formula, rendering failed.")
-            return None
-
-
-class FormulaResult(CVResult):
-
-    def _to_str(self, *args, **kwargs):
-        return super()._to_str(*args, **kwargs).replace("\\\\", "\\")
-
-    def _to_img(
-        self,
-    ):
-        """draw formula result"""
-        try:
-            env_valid()
-        except subprocess.CalledProcessError as e:
-            logging.warning(
-                "Please refer to 2.3 Formula Recognition Pipeline Visualization in Formula Recognition Pipeline Tutorial to install the LaTeX rendering engine at first."
-            )
-            return None
-
-        boxes = self["dt_polys"]
-        formulas = self["rec_formula"]
-        image = self._img_reader.read(self["input_path"])
-        h, w = image.height, image.width
-        img_left = image.copy()
-        img_right = np.ones((h, w, 3), dtype=np.uint8) * 255
-        random.seed(0)
-        draw_left = ImageDraw.Draw(img_left)
-
-        if formulas is None or len(formulas) != len(boxes):
-            formulas = [None] * len(boxes)
-        for idx, (box, formula) in enumerate(zip(boxes, formulas)):
-            try:
-                color = (
-                    random.randint(0, 255),
-                    random.randint(0, 255),
-                    random.randint(0, 255),
-                )
-                box = np.array(box)
-                pts = [(x, y) for x, y in box.tolist()]
-                draw_left.polygon(pts, outline=color, width=8)
-                draw_left.polygon(box, fill=color)
-                img_right_text = draw_box_formula_fine(
-                    (w, h),
-                    box,
-                    formula,
-                    is_debug=False,
-                )
-                pts = np.array(box, np.int32).reshape((-1, 1, 2))
-                cv2.polylines(img_right_text, [pts], True, color, 1)
-                img_right = cv2.bitwise_and(img_right, img_right_text)
-            except subprocess.CalledProcessError as e:
-                logging.warning("Syntax error detected in formula, rendering failed.")
-                continue
-
-        img_left = Image.blend(image, img_left, 0.5)
-        img_show = Image.new("RGB", (int(w * 2), h), (255, 255, 255))
-        img_show.paste(img_left, (0, 0, w, h))
-        img_show.paste(Image.fromarray(img_right), (w, 0, w * 2, h))
-        return img_show
-
-
-class FormulaVisualResult(BaseResult):
-
-    def __init__(self, data, page_id=None, src_input_name=None):
-        super().__init__(data)
-        self.page_id = page_id
-        self.src_input_name = src_input_name
-
-    def _to_str(self, *args, **kwargs):
-        return super()._to_str(*args, **kwargs).replace("\\\\", "\\")
-
-    def get_target_name(self, save_path):
-        if self.src_input_name.endswith(".pdf"):
-            save_path = (
-                Path(save_path)
-                / f"{Path(self.src_input_name).stem}_pdf"
-                / Path("page_{:04d}".format(self.page_id + 1))
-            )
-        else:
-            save_path = Path(save_path) / f"{Path(self.src_input_name).stem}"
-        return save_path
-
-    def save_to_json(self, save_path):
-        if not save_path.lower().endswith(("json")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-
-        formula_save_path = f"{save_path}_formula.jpg"
-        if not str(save_path).endswith(".json"):
-            save_path = "{}.json".format(save_path)
-        super().save_to_json(save_path)
-
-    def save_to_img(self, save_path):
-        if not save_path.lower().endswith((".jpg", ".png")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        formula_save_path = f"{save_path}_formula.jpg"
-        formula_result = self["formula_result"]
-        if formula_result:
-            formula_result.save_to_img(formula_save_path)
-
-
-def get_align_equation(equation):
-    is_align = False
-    equation = str(equation) + "\n"
-    begin_dict = [
-        r"begin{align}",
-        r"begin{align*}",
-    ]
-    for begin_sym in begin_dict:
-        if begin_sym in equation:
-            is_align = True
-            break
-    if not is_align:
-        equation = (
-            r"\begin{equation}"
-            + "\n"
-            + equation.strip()
-            + r"\nonumber"
-            + "\n"
-            + r"\end{equation}"
-            + "\n"
-        )
-    return equation
-
-
-def generate_tex_file(tex_file_path, equation):
-    with open(tex_file_path, "w") as fp:
-        start_template = (
-            r"\documentclass{article}" + "\n"
-            r"\usepackage{cite}" + "\n"
-            r"\usepackage{amsmath,amssymb,amsfonts}" + "\n"
-            r"\usepackage{graphicx}" + "\n"
-            r"\usepackage{textcomp}" + "\n"
-            r"\DeclareMathSizes{14}{14}{9.8}{7}" + "\n"
-            r"\pagestyle{empty}" + "\n"
-            r"\begin{document}" + "\n"
-            r"\begin{large}" + "\n"
-        )
-        fp.write(start_template)
-        equation = get_align_equation(equation)
-        fp.write(equation)
-        end_template = r"\end{large}" + "\n" r"\end{document}" + "\n"
-        fp.write(end_template)
-
-
-def generate_pdf_file(tex_path, pdf_dir, is_debug=False):
-    if os.path.exists(tex_path):
-        command = "pdflatex -halt-on-error -output-directory={} {}".format(
-            pdf_dir, tex_path
-        )
-        if is_debug:
-            subprocess.check_call(command, shell=True)
-        else:
-            devNull = open(os.devnull, "w")
-            subprocess.check_call(
-                command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True
-            )
-
-
-def crop_white_area(image):
-    image = np.array(image).astype("uint8")
-    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
-    _, thresh = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV)
-    contours, _ = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
-    if len(contours) > 0:
-        x, y, w, h = cv2.boundingRect(np.concatenate(contours))
-        return [x, y, w, h]
-    else:
-        return None
-
-
-def pdf2img(pdf_path, img_path, is_padding=False):
-    import fitz
-
-    pdfDoc = fitz.open(pdf_path)
-    if pdfDoc.page_count != 1:
-        return None
-    for pg in range(pdfDoc.page_count):
-        page = pdfDoc[pg]
-        rotate = int(0)
-        zoom_x = 2
-        zoom_y = 2
-        mat = fitz.Matrix(zoom_x, zoom_y).prerotate(rotate)
-        pix = page.get_pixmap(matrix=mat, alpha=False)
-        if not os.path.exists(img_path):
-            os.makedirs(img_path)
-
-        pix._writeIMG(img_path, 7, 100)
-        img = cv2.imread(img_path)
-        xywh = crop_white_area(img)
-
-        if xywh is not None:
-            x, y, w, h = xywh
-            img = img[y : y + h, x : x + w]
-            if is_padding:
-                img = cv2.copyMakeBorder(
-                    img, 30, 30, 30, 30, cv2.BORDER_CONSTANT, value=(255, 255, 255)
-                )
-            return img
-    return None
-
-
-def draw_formula_module(img_size, box, formula, is_debug=False):
-    """draw box formula for module"""
-    box_width, box_height = img_size
-    with tempfile.TemporaryDirectory() as td:
-        tex_file_path = os.path.join(td, "temp.tex")
-        pdf_file_path = os.path.join(td, "temp.pdf")
-        img_file_path = os.path.join(td, "temp.jpg")
-        generate_tex_file(tex_file_path, formula)
-        if os.path.exists(tex_file_path):
-            generate_pdf_file(tex_file_path, td, is_debug)
-        formula_img = None
-        if os.path.exists(pdf_file_path):
-            formula_img = pdf2img(pdf_file_path, img_file_path, is_padding=False)
-        if formula_img is not None:
-            return formula_img
-        else:
-            img_right_text = draw_box_txt_fine(
-                img_size, box, "Rendering Failed", PINGFANG_FONT_FILE_PATH
-            )
-        return img_right_text
-
-
-def env_valid():
-    with tempfile.TemporaryDirectory() as td:
-        tex_file_path = os.path.join(td, "temp.tex")
-        pdf_file_path = os.path.join(td, "temp.pdf")
-        img_file_path = os.path.join(td, "temp.jpg")
-        formula = "a+b=c"
-        is_debug = False
-        generate_tex_file(tex_file_path, formula)
-        if os.path.exists(tex_file_path):
-            generate_pdf_file(tex_file_path, td, is_debug)
-        if os.path.exists(pdf_file_path):
-            formula_img = pdf2img(pdf_file_path, img_file_path, is_padding=False)
-
-
-def draw_box_formula_fine(img_size, box, formula, is_debug=False):
-    """draw box formula for pipeline"""
-    box_height = int(
-        math.sqrt((box[0][0] - box[3][0]) ** 2 + (box[0][1] - box[3][1]) ** 2)
-    )
-    box_width = int(
-        math.sqrt((box[0][0] - box[1][0]) ** 2 + (box[0][1] - box[1][1]) ** 2)
-    )
-    with tempfile.TemporaryDirectory() as td:
-        tex_file_path = os.path.join(td, "temp.tex")
-        pdf_file_path = os.path.join(td, "temp.pdf")
-        img_file_path = os.path.join(td, "temp.jpg")
-        generate_tex_file(tex_file_path, formula)
-        if os.path.exists(tex_file_path):
-            generate_pdf_file(tex_file_path, td, is_debug)
-        formula_img = None
-        if os.path.exists(pdf_file_path):
-            formula_img = pdf2img(pdf_file_path, img_file_path, is_padding=False)
-        if formula_img is not None:
-            formula_h, formula_w = formula_img.shape[:-1]
-            resize_height = box_height
-            resize_width = formula_w * resize_height / formula_h
-            formula_img = cv2.resize(
-                formula_img, (int(resize_width), int(resize_height))
-            )
-            formula_h, formula_w = formula_img.shape[:-1]
-            pts1 = np.float32(
-                [[0, 0], [box_width, 0], [box_width, box_height], [0, box_height]]
-            )
-            pts2 = np.array(box, dtype=np.float32)
-            M = cv2.getPerspectiveTransform(pts1, pts2)
-            formula_img = np.array(formula_img, dtype=np.uint8)
-            img_right_text = cv2.warpPerspective(
-                formula_img,
-                M,
-                img_size,
-                flags=cv2.INTER_NEAREST,
-                borderMode=cv2.BORDER_CONSTANT,
-                borderValue=(255, 255, 255),
-            )
-        else:
-            img_right_text = draw_box_txt_fine(
-                img_size, box, "Rendering Failed", PINGFANG_FONT_FILE_PATH
-            )
-        return img_right_text

+ 0 - 152
paddlex/inference/results/instance_seg.py

@@ -1,152 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import os
-import cv2
-import numpy as np
-import copy
-from PIL import Image
-
-from ..utils.color_map import get_colormap
-from .base import CVResult
-from .det import draw_box
-
-
-def draw_segm(im, masks, mask_info, alpha=0.7):
-    """
-    Draw segmentation on image
-    """
-    mask_color_id = 0
-    w_ratio = 0.4
-    color_list = get_colormap(rgb=True)
-    im = np.array(im).astype("float32")
-    clsid2color = {}
-    masks = np.array(masks)
-    masks = masks.astype(np.uint8)
-    for i in range(masks.shape[0]):
-        mask, score, clsid = masks[i], mask_info[i]["score"], mask_info[i]["class_id"]
-
-        if clsid not in clsid2color:
-            color_index = i % len(color_list)
-            clsid2color[clsid] = color_list[color_index]
-        color_mask = clsid2color[clsid]
-        for c in range(3):
-            color_mask[c] = color_mask[c] * (1 - w_ratio) + w_ratio * 255
-        idx = np.nonzero(mask)
-        color_mask = np.array(color_mask)
-        idx0 = np.minimum(idx[0], im.shape[0] - 1)
-        idx1 = np.minimum(idx[1], im.shape[1] - 1)
-        im[idx0, idx1, :] *= 1.0 - alpha
-        im[idx0, idx1, :] += alpha * color_mask
-        sum_x = np.sum(mask, axis=0)
-        x = np.where(sum_x > 0.5)[0]
-        sum_y = np.sum(mask, axis=1)
-        y = np.where(sum_y > 0.5)[0]
-        x0, x1, y0, y1 = x[0], x[-1], y[0], y[-1]
-        cv2.rectangle(
-            im, (x0, y0), (x1, y1), tuple(color_mask.astype("int32").tolist()), 1
-        )
-        bbox_text = "%s %.2f" % (mask_info[i]["label"], score)
-        t_size = cv2.getTextSize(bbox_text, 0, 0.3, thickness=1)[0]
-        cv2.rectangle(
-            im,
-            (x0, y0),
-            (x0 + t_size[0], y0 - t_size[1] - 3),
-            tuple(color_mask.astype("int32").tolist()),
-            -1,
-        )
-        cv2.putText(
-            im,
-            bbox_text,
-            (x0, y0 - 2),
-            cv2.FONT_HERSHEY_SIMPLEX,
-            0.3,
-            (0, 0, 0),
-            1,
-            lineType=cv2.LINE_AA,
-        )
-    return Image.fromarray(im.astype("uint8"))
-
-
-def restore_to_draw_masks(img_size, boxes, masks):
-    """
-    Restores extracted masks to the original shape and draws them on a blank image.
-
-    """
-
-    restored_masks = []
-
-    for i, (box, mask) in enumerate(zip(boxes, masks)):
-        restored_mask = np.zeros(img_size, dtype=np.uint8)
-        x_min, y_min, x_max, y_max = map(lambda x: int(round(x)), box["coordinate"])
-        restored_mask[y_min:y_max, x_min:x_max] = mask
-        restored_masks.append(restored_mask)
-
-    return np.array(restored_masks)
-
-
-def draw_mask(im, boxes, np_masks, img_size):
-    """
-    Args:
-        im (PIL.Image.Image): PIL image
-        boxes (list): a list of dictionaries representing detection box information.
-        np_masks (np.ndarray): shape:[N, im_h, im_w]
-    Returns:
-        im (PIL.Image.Image): visualized image
-    """
-    color_list = get_colormap(rgb=True)
-    w_ratio = 0.4
-    alpha = 0.7
-    im = np.array(im).astype("float32")
-    clsid2color = {}
-    np_masks = restore_to_draw_masks(img_size, boxes, np_masks)
-    im_h, im_w = im.shape[:2]
-    np_masks = np_masks[:, :im_h, :im_w]
-    for i in range(len(np_masks)):
-        clsid, score = int(boxes[i]["cls_id"]), boxes[i]["score"]
-        mask = np_masks[i]
-        if clsid not in clsid2color:
-            color_index = i % len(color_list)
-            clsid2color[clsid] = color_list[color_index]
-        color_mask = clsid2color[clsid]
-        for c in range(3):
-            color_mask[c] = color_mask[c] * (1 - w_ratio) + w_ratio * 255
-        idx = np.nonzero(mask)
-        color_mask = np.array(color_mask)
-        im[idx[0], idx[1], :] *= 1.0 - alpha
-        im[idx[0], idx[1], :] += alpha * color_mask
-    return Image.fromarray(im.astype("uint8"))
-
-
-class InstanceSegResult(CVResult):
-    """Save Result Transform"""
-
-    def _to_img(self):
-        """apply"""
-        image = self._img_reader.read(self["input_path"])
-        ori_img_size = list(image.size)[::-1]
-        boxes = self["boxes"]
-        masks = self["masks"]
-        if next((True for item in self["boxes"] if "coordinate" in item), False):
-            image = draw_mask(image, boxes, masks, ori_img_size)
-            image = draw_box(image, boxes)
-        else:
-            image = draw_segm(image, masks, boxes)
-
-        return image
-
-    def _to_str(self, _, *args, **kwargs):
-        data = copy.deepcopy(self)
-        data["masks"] = "..."
-        return super()._to_str(data, *args, **kwargs)

+ 0 - 157
paddlex/inference/results/ocr.py

@@ -1,157 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import math
-import random
-import numpy as np
-import cv2
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-from .base import CVResult
-
-
-class OCRResult(CVResult):
-
-    def get_minarea_rect(self, points):
-        bounding_box = cv2.minAreaRect(points)
-        points = sorted(list(cv2.boxPoints(bounding_box)), key=lambda x: x[0])
-
-        index_a, index_b, index_c, index_d = 0, 1, 2, 3
-        if points[1][1] > points[0][1]:
-            index_a = 0
-            index_d = 1
-        else:
-            index_a = 1
-            index_d = 0
-        if points[3][1] > points[2][1]:
-            index_b = 2
-            index_c = 3
-        else:
-            index_b = 3
-            index_c = 2
-
-        box = np.array(
-            [points[index_a], points[index_b], points[index_c], points[index_d]]
-        ).astype(np.int32)
-
-        return box
-
-    def _to_img(
-        self,
-    ):
-        """draw ocr result"""
-        # TODO(gaotingquan): mv to postprocess
-        drop_score = 0.5
-
-        boxes = self["dt_polys"]
-        txts = self["rec_text"]
-        scores = self["rec_score"]
-        image = self._img_reader.read(self["input_path"])
-        h, w = image.height, image.width
-        img_left = image.copy()
-        img_right = np.ones((h, w, 3), dtype=np.uint8) * 255
-        random.seed(0)
-        draw_left = ImageDraw.Draw(img_left)
-        if txts is None or len(txts) != len(boxes):
-            txts = [None] * len(boxes)
-        for idx, (box, txt) in enumerate(zip(boxes, txts)):
-            try:
-                if scores is not None and scores[idx] < drop_score:
-                    continue
-                color = (
-                    random.randint(0, 255),
-                    random.randint(0, 255),
-                    random.randint(0, 255),
-                )
-                box = np.array(box)
-                if len(box) > 4:
-                    pts = [(x, y) for x, y in box.tolist()]
-                    draw_left.polygon(pts, outline=color, width=8)
-                    box = self.get_minarea_rect(box)
-                    height = int(0.5 * (max(box[:, 1]) - min(box[:, 1])))
-                    box[:2, 1] = np.mean(box[:, 1])
-                    box[2:, 1] = np.mean(box[:, 1]) + min(20, height)
-                draw_left.polygon(box, fill=color)
-                img_right_text = draw_box_txt_fine(
-                    (w, h), box, txt, PINGFANG_FONT_FILE_PATH
-                )
-                pts = np.array(box, np.int32).reshape((-1, 1, 2))
-                cv2.polylines(img_right_text, [pts], True, color, 1)
-                img_right = cv2.bitwise_and(img_right, img_right_text)
-            except:
-                continue
-
-        img_left = Image.blend(image, img_left, 0.5)
-        img_show = Image.new("RGB", (w * 2, h), (255, 255, 255))
-        img_show.paste(img_left, (0, 0, w, h))
-        img_show.paste(Image.fromarray(img_right), (w, 0, w * 2, h))
-        return img_show
-
-
-def draw_box_txt_fine(img_size, box, txt, font_path):
-    """draw box text"""
-    box_height = int(
-        math.sqrt((box[0][0] - box[3][0]) ** 2 + (box[0][1] - box[3][1]) ** 2)
-    )
-    box_width = int(
-        math.sqrt((box[0][0] - box[1][0]) ** 2 + (box[0][1] - box[1][1]) ** 2)
-    )
-
-    if box_height > 2 * box_width and box_height > 30:
-        img_text = Image.new("RGB", (box_height, box_width), (255, 255, 255))
-        draw_text = ImageDraw.Draw(img_text)
-        if txt:
-            font = create_font(txt, (box_height, box_width), font_path)
-            draw_text.text([0, 0], txt, fill=(0, 0, 0), font=font)
-        img_text = img_text.transpose(Image.ROTATE_270)
-    else:
-        img_text = Image.new("RGB", (box_width, box_height), (255, 255, 255))
-        draw_text = ImageDraw.Draw(img_text)
-        if txt:
-            font = create_font(txt, (box_width, box_height), font_path)
-            draw_text.text([0, 0], txt, fill=(0, 0, 0), font=font)
-
-    pts1 = np.float32(
-        [[0, 0], [box_width, 0], [box_width, box_height], [0, box_height]]
-    )
-    pts2 = np.array(box, dtype=np.float32)
-    M = cv2.getPerspectiveTransform(pts1, pts2)
-
-    img_text = np.array(img_text, dtype=np.uint8)
-    img_right_text = cv2.warpPerspective(
-        img_text,
-        M,
-        img_size,
-        flags=cv2.INTER_NEAREST,
-        borderMode=cv2.BORDER_CONSTANT,
-        borderValue=(255, 255, 255),
-    )
-    return img_right_text
-
-
-def create_font(txt, sz, font_path):
-    """create font"""
-    font_size = int(sz[1] * 0.8)
-    font = ImageFont.truetype(font_path, font_size, encoding="utf-8")
-    if int(PIL.__version__.split(".")[0]) < 10:
-        length = font.getsize(txt)[0]
-    else:
-        length = font.getlength(txt)
-
-    if length > sz[0]:
-        font_size = int(font_size * sz[0] / length)
-        font = ImageFont.truetype(font_path, font_size, encoding="utf-8")
-    return font

+ 0 - 50
paddlex/inference/results/seal_rec.py

@@ -1,50 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from pathlib import Path
-from .base import BaseResult, CVResult
-
-
-class SealOCRResult(CVResult):
-    """SealOCRResult"""
-
-    def get_target_name(self, save_path):
-        input_path = self["src_file_name"]
-        if input_path.endswith(".pdf"):
-            save_path = (
-                Path(save_path)
-                / f"{Path(input_path).stem}_pdf"
-                / Path("page_{:04d}".format(self["page_id"] + 1))
-            )
-        else:
-            save_path = Path(save_path) / f"{Path(input_path).stem}"
-        return save_path
-
-    def save_to_img(self, save_path):
-        if not save_path.lower().endswith((".jpg", ".png")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        layout_save_path = f"{save_path}_layout.jpg"
-        layout_result = self["layout_result"]
-        layout_result.save_to_img(layout_save_path)
-        seal_result = self["ocr_result"]
-        seal_result.save_to_img(f"{save_path}_seal_ocr.jpg")
-
-    def save_to_json(self, save_path):
-        if not save_path.lower().endswith((".json")):
-            save_path = self.get_target_name(save_path)
-        else:
-            save_path = Path(save_path).stem
-        super().save_to_json(f"{save_path}_res.json")

+ 0 - 74
paddlex/inference/results/seg.py

@@ -1,74 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import numpy as np
-import PIL
-from PIL import Image
-import copy
-import json
-
-from ...utils import logging
-from .utils.mixin import ImgMixin
-from .base import CVResult
-
-
-class SegResult(CVResult):
-    """Save Result Transform"""
-
-    def __init__(self, data):
-        super().__init__(data)
-        self._img_writer.set_backend("pillow", format_="PNG")
-
-    def _to_img(self):
-        """apply"""
-        seg_map = self["pred"]
-        pc_map = self.get_pseudo_color_map(seg_map[0])
-        if pc_map.mode == "P":
-            pc_map = pc_map.convert("RGB")
-        return pc_map
-
-    def get_pseudo_color_map(self, pred):
-        """get_pseudo_color_map"""
-        if pred.min() < 0 or pred.max() > 255:
-            raise ValueError("`pred` cannot be cast to uint8.")
-        pred = pred.astype(np.uint8)
-        pred_mask = Image.fromarray(pred, mode="P")
-        color_map = self._get_color_map_list(256)
-        pred_mask.putpalette(color_map)
-        return pred_mask
-
-    @staticmethod
-    def _get_color_map_list(num_classes, custom_color=None):
-        """_get_color_map_list"""
-        num_classes += 1
-        color_map = num_classes * [0, 0, 0]
-        for i in range(0, num_classes):
-            j = 0
-            lab = i
-            while lab:
-                color_map[i * 3] |= ((lab >> 0) & 1) << (7 - j)
-                color_map[i * 3 + 1] |= ((lab >> 1) & 1) << (7 - j)
-                color_map[i * 3 + 2] |= ((lab >> 2) & 1) << (7 - j)
-                j += 1
-                lab >>= 3
-        color_map = color_map[3:]
-
-        if custom_color:
-            color_map[: len(custom_color)] = custom_color
-        return color_map
-
-    def _to_str(self, _, *args, **kwargs):
-        data = copy.deepcopy(self)
-        data["pred"] = "..."
-        return super()._to_str(data, *args, **kwargs)

+ 0 - 35
paddlex/inference/results/shitu.py

@@ -1,35 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import numpy as np
-from .base import CVResult
-from .det import draw_box
-
-
-class ShiTuResult(CVResult):
-
-    def _to_img(self):
-        """apply"""
-        image = self._img_reader.read(self["input_path"])
-        boxes = [
-            {
-                "coordinate": box["coordinate"],
-                "label": box["labels"][0],
-                "score": box["rec_scores"][0],
-            }
-            for box in self["boxes"]
-            if box["rec_scores"] is not None
-        ]
-        image = draw_box(image, boxes)
-        return image

+ 0 - 109
paddlex/inference/results/table_rec.py

@@ -1,109 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import cv2
-import numpy as np
-from pathlib import Path
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-
-from .utils.mixin import HtmlMixin, XlsxMixin
-from .base import BaseResult, CVResult
-
-
-class TableRecResult(CVResult):
-    """SaveTableResults"""
-
-    def __init__(self, data):
-        super().__init__(data)
-
-    def _to_img(self):
-        image = self._img_reader.read(self["input_path"])
-        bbox_res = self["bbox"]
-        if len(bbox_res) > 0 and len(bbox_res[0]) == 4:
-            vis_img = self.draw_rectangle(image, bbox_res)
-        else:
-            vis_img = self.draw_bbox(image, bbox_res)
-        return vis_img
-
-    def draw_rectangle(self, image, boxes):
-        """draw_rectangle"""
-        boxes = np.array(boxes)
-        img_show = image.copy()
-        for box in boxes.astype(int):
-            x1, y1, x2, y2 = box
-            cv2.rectangle(img_show, (x1, y1), (x2, y2), (255, 0, 0), 2)
-        return img_show
-
-    def draw_bbox(self, image, boxes):
-        """draw_bbox"""
-        for box in boxes:
-            box = np.reshape(np.array(box), [-1, 1, 2]).astype(np.int64)
-            image = cv2.polylines(np.array(image), [box], True, (255, 0, 0), 2)
-        return image
-
-
-class StructureTableResult(TableRecResult, HtmlMixin, XlsxMixin):
-    """StructureTableResult"""
-
-    def __init__(self, data):
-        super().__init__(data)
-        HtmlMixin.__init__(self)
-        XlsxMixin.__init__(self)
-
-    def _to_html(self):
-        return self["html"]
-
-
-class TableResult(CVResult, HtmlMixin, XlsxMixin):
-    """TableResult"""
-
-    def __init__(self, data):
-        super().__init__(data)
-        HtmlMixin.__init__(self)
-        XlsxMixin.__init__(self)
-
-    def save_to_html(self, save_path):
-        if not save_path.lower().endswith(("html")):
-            input_path = self["input_path"]
-            save_path = Path(save_path) / f"{Path(input_path).stem}"
-        else:
-            save_path = Path(save_path).stem
-        for table_result in self["table_result"]:
-            table_result.save_to_html(save_path)
-
-    def save_to_xlsx(self, save_path):
-        if not save_path.lower().endswith(("xlsx")):
-            input_path = self["input_path"]
-            save_path = Path(save_path) / f"{Path(input_path).stem}"
-        else:
-            save_path = Path(save_path).stem
-        for table_result in self["table_result"]:
-            table_result.save_to_xlsx(save_path)
-
-    def save_to_img(self, save_path):
-        if not save_path.lower().endswith((".jpg", ".png")):
-            input_path = self["input_path"]
-            save_path = Path(save_path) / f"{Path(input_path).stem}"
-        else:
-            save_path = Path(save_path).stem
-        layout_save_path = f"{save_path}_layout.jpg"
-        ocr_save_path = f"{save_path}_ocr.jpg"
-        table_save_path = f"{save_path}_table"
-        layout_result = self["layout_result"]
-        layout_result.save_to_img(layout_save_path)
-        ocr_result = self["ocr_result"]
-        ocr_result.save_to_img(ocr_save_path)
-        for idx, table_result in enumerate(self["table_result"]):
-            table_result.save_to_img(f"{table_save_path}_{idx}.jpg")

+ 0 - 33
paddlex/inference/results/text_det.py

@@ -1,33 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import numpy as np
-import cv2
-
-from .base import CVResult
-
-
-class TextDetResult(CVResult):
-    def __init__(self, data):
-        super().__init__(data)
-        self._img_reader.set_backend("opencv")
-
-    def _to_img(self):
-        """draw rectangle"""
-        boxes = self["dt_polys"]
-        image = self._img_reader.read(self["input_path"])
-        for box in boxes:
-            box = np.reshape(np.array(box).astype(int), [-1, 1, 2]).astype(np.int64)
-            cv2.polylines(image, [box], True, (0, 0, 255), 2)
-        return image

+ 0 - 66
paddlex/inference/results/text_rec.py

@@ -1,66 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import PIL
-from PIL import Image, ImageDraw, ImageFont
-import numpy as np
-import cv2
-
-from ...utils.fonts import PINGFANG_FONT_FILE_PATH
-from ...utils import logging
-from .base import CVResult
-
-
-class TextRecResult(CVResult):
-    def _to_img(self):
-        """Draw label on image"""
-        image = self._img_reader.read(self["input_path"])
-        rec_text = self["rec_text"]
-        rec_score = self["rec_score"]
-        image = image.convert("RGB")
-        image_width, image_height = image.size
-        text = f"{rec_text} ({rec_score})"
-        font = self.adjust_font_size(image_width, text, PINGFANG_FONT_FILE_PATH)
-        row_height = font.getbbox(text)[3]
-        new_image_height = image_height + int(row_height * 1.2)
-        new_image = Image.new("RGB", (image_width, new_image_height), (255, 255, 255))
-        new_image.paste(image, (0, 0))
-
-        draw = ImageDraw.Draw(new_image)
-        draw.text(
-            (0, image_height),
-            text,
-            fill=(0, 0, 0),
-            font=font,
-        )
-        return new_image
-
-    def adjust_font_size(self, image_width, text, font_path):
-        font_size = int(image_width * 0.06)
-        font = ImageFont.truetype(font_path, font_size)
-
-        if int(PIL.__version__.split(".")[0]) < 10:
-            text_width, _ = font.getsize(text)
-        else:
-            text_width, _ = font.getbbox(text)[2:]
-
-        while text_width > image_width:
-            font_size -= 1
-            font = ImageFont.truetype(font_path, font_size)
-            if int(PIL.__version__.split(".")[0]) < 10:
-                text_width, _ = font.getsize(text)
-            else:
-                text_width, _ = font.getbbox(text)[2:]
-
-        return font

+ 0 - 37
paddlex/inference/results/ts.py

@@ -1,37 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from .utils.mixin import JsonMixin, CSVMixin
-from .base import BaseResult
-
-
-class _BaseTSResult(BaseResult, CSVMixin):
-    def __init__(self, data):
-        super().__init__(data)
-        CSVMixin.__init__(self)
-
-
-class TSFcResult(_BaseTSResult):
-    def _to_csv(self):
-        return self["forecast"]
-
-
-class TSClsResult(_BaseTSResult):
-    def _to_csv(self):
-        return self["classification"]
-
-
-class TSAdResult(_BaseTSResult):
-    def _to_csv(self):
-        return self["anomaly"]

+ 0 - 13
paddlex/inference/results/utils/__init__.py

@@ -1,13 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.

+ 0 - 204
paddlex/inference/results/utils/mixin.py

@@ -1,204 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from abc import abstractmethod
-import json
-from pathlib import Path
-import numpy as np
-from PIL import Image
-import pandas as pd
-
-from ....utils import logging
-from ...utils.io import (
-    JsonWriter,
-    ImageReader,
-    ImageWriter,
-    CSVWriter,
-    HtmlWriter,
-    XlsxWriter,
-    TextWriter,
-)
-
-
-def _save_list_data(save_func, save_path, data, *args, **kwargs):
-    save_path = Path(save_path)
-    if data is None:
-        return
-    if isinstance(data, list):
-        for idx, single in enumerate(data):
-            save_func(
-                (
-                    save_path.parent / f"{save_path.stem}_{idx}{save_path.suffix}"
-                ).as_posix(),
-                single,
-                *args,
-                **kwargs,
-            )
-    save_func(save_path.as_posix(), data, *args, **kwargs)
-    logging.info(f"The result has been saved in {save_path}.")
-
-
-class StrMixin:
-    @property
-    def str(self):
-        return self._to_str()
-
-    def _to_str(self, data, json_format=False, indent=4, ensure_ascii=False):
-        if json_format:
-            return json.dumps(data.json, indent=indent, ensure_ascii=ensure_ascii)
-        else:
-            return str(data)
-
-    def print(self, json_format=False, indent=4, ensure_ascii=False):
-        str_ = self._to_str(
-            self, json_format=json_format, indent=indent, ensure_ascii=ensure_ascii
-        )
-        logging.info(str_)
-
-
-class JsonMixin:
-    def __init__(self):
-        self._json_writer = JsonWriter()
-        self._show_funcs.append(self.save_to_json)
-
-    def _to_json(self):
-        def _format_data(obj):
-            if isinstance(obj, np.float32):
-                return float(obj)
-            elif isinstance(obj, np.ndarray):
-                return [_format_data(item) for item in obj.tolist()]
-            elif isinstance(obj, pd.DataFrame):
-                return json.loads(obj.to_json(orient="records", force_ascii=False))
-            elif isinstance(obj, Path):
-                return obj.as_posix()
-            elif isinstance(obj, dict):
-                return type(obj)({k: _format_data(v) for k, v in obj.items()})
-            elif isinstance(obj, (list, tuple)):
-                return [_format_data(i) for i in obj]
-            else:
-                return obj
-
-        return _format_data(self)
-
-    @property
-    def json(self):
-        return self._to_json()
-
-    def save_to_json(self, save_path, indent=4, ensure_ascii=False, *args, **kwargs):
-        if not str(save_path).endswith(".json"):
-            save_path = Path(save_path) / f"{Path(self['input_path']).stem}.json"
-        _save_list_data(
-            self._json_writer.write,
-            save_path,
-            self.json,
-            indent=indent,
-            ensure_ascii=ensure_ascii,
-            *args,
-            **kwargs,
-        )
-
-
-class Base64Mixin:
-    def __init__(self, *args, **kwargs):
-        self._base64_writer = TextWriter(*args, **kwargs)
-        self._show_funcs.append(self.save_to_base64)
-
-    @abstractmethod
-    def _to_base64(self):
-        raise NotImplementedError
-
-    @property
-    def base64(self):
-        return self._to_base64()
-
-    def save_to_base64(self, save_path, *args, **kwargs):
-        if not str(save_path).lower().endswith((".b64")):
-            fp = Path(self["input_path"])
-            save_path = Path(save_path) / f"{fp.stem}{fp.suffix}"
-        _save_list_data(
-            self._base64_writer.write, save_path, self.base64, *args, **kwargs
-        )
-
-
-class ImgMixin:
-    def __init__(self, backend="pillow", *args, **kwargs):
-        self._img_writer = ImageWriter(backend=backend, *args, **kwargs)
-        self._show_funcs.append(self.save_to_img)
-
-    @abstractmethod
-    def _to_img(self):
-        raise NotImplementedError
-
-    @property
-    def img(self):
-        image = self._to_img()
-        # The img must be a PIL.Image obj
-        if isinstance(image, np.ndarray):
-            return Image.fromarray(image)
-        return image
-
-    def save_to_img(self, save_path, *args, **kwargs):
-        if not str(save_path).lower().endswith((".jpg", ".png")):
-            fp = Path(self["input_path"])
-            save_path = Path(save_path) / f"{fp.stem}{fp.suffix}"
-        _save_list_data(self._img_writer.write, save_path, self.img, *args, **kwargs)
-
-
-class CSVMixin:
-    def __init__(self, backend="pandas", *args, **kwargs):
-        self._csv_writer = CSVWriter(backend=backend, *args, **kwargs)
-        self._show_funcs.append(self.save_to_csv)
-
-    @abstractmethod
-    def _to_csv(self):
-        raise NotImplementedError
-
-    def save_to_csv(self, save_path, *args, **kwargs):
-        if not str(save_path).endswith(".csv"):
-            save_path = Path(save_path) / f"{Path(self['input_path']).stem}.csv"
-        _save_list_data(
-            self._csv_writer.write, save_path, self._to_csv(), *args, **kwargs
-        )
-
-
-class HtmlMixin:
-    def __init__(self, *args, **kwargs):
-        self._html_writer = HtmlWriter(*args, **kwargs)
-        self._show_funcs.append(self.save_to_html)
-
-    @property
-    def html(self):
-        return self._to_html()
-
-    def _to_html(self):
-        return self["html"]
-
-    def save_to_html(self, save_path, *args, **kwargs):
-        if not str(save_path).endswith(".html"):
-            save_path = Path(save_path) / f"{Path(self['input_path']).stem}.html"
-        _save_list_data(self._html_writer.write, save_path, self.html, *args, **kwargs)
-
-
-class XlsxMixin:
-    def __init__(self, *args, **kwargs):
-        self._xlsx_writer = XlsxWriter(*args, **kwargs)
-        self._show_funcs.append(self.save_to_xlsx)
-
-    def _to_xlsx(self):
-        return self["html"]
-
-    def save_to_xlsx(self, save_path, *args, **kwargs):
-        if not str(save_path).endswith(".xlsx"):
-            save_path = Path(save_path) / f"{Path(self['input_path']).stem}.xlsx"
-        _save_list_data(self._xlsx_writer.write, save_path, self.html, *args, **kwargs)

+ 0 - 31
paddlex/inference/results/warp.py

@@ -1,31 +0,0 @@
-# copyright (c) 2024 PaddlePaddle Authors. All Rights Reserve.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-#    http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import numpy as np
-import copy
-import json
-
-from ...utils import logging
-from .base import CVResult
-
-
-class DocTrResult(CVResult):
-
-    def _to_img(self):
-        return np.array(self["doctr_img"])
-
-    def _to_str(self, _, *args, **kwargs):
-        data = copy.deepcopy(self)
-        data.pop("doctr_img")
-        return super()._to_str(data, *args, **kwargs)