From ef52dfff053b176f82142cf2cdf790ad3e9058e2 Mon Sep 17 00:00:00 2001 From: Onuralp SEZER Date: Sun, 15 Sep 2024 04:36:03 +0300 Subject: [PATCH 1/8] =?UTF-8?q?feat:=20=E2=9C=A8=20=20from=5Feasyocr=20det?= =?UTF-8?q?ection=20added?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onuralp SEZER --- supervision/config.py | 1 + supervision/detection/core.py | 38 ++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/supervision/config.py b/supervision/config.py index b18d2e20..357ff2d4 100644 --- a/supervision/config.py +++ b/supervision/config.py @@ -1,2 +1,3 @@ CLASS_NAME_DATA_FIELD = "class_name" ORIENTED_BOX_COORDINATES = "xyxyxyxy" +TEXT_DATA_FIELD = "text_data" diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 06995f90..54cae9a7 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -6,7 +6,11 @@ from typing import Any, Dict, Iterator, List, Optional, Tuple, Union import numpy as np -from supervision.config import CLASS_NAME_DATA_FIELD, ORIENTED_BOX_COORDINATES +from supervision.config import ( + CLASS_NAME_DATA_FIELD, + ORIENTED_BOX_COORDINATES, + TEXT_DATA_FIELD, +) from supervision.detection.lmm import ( LMM, from_florence_2, @@ -843,6 +847,38 @@ class Detections: raise ValueError(f"Unsupported LMM: {lmm}") + @classmethod + def from_easyocr(cls, easyocr_results: list) -> Detections: + """ + Create a Detections object from the + [EasyOCR](https://github.com/JaidedAI/EasyOCR) inference result. + + Args: + easyocr_results (List): The output Results instance from EasyOCR + + Returns: + Detections: A new Detections object. + + Example: + ```python + import supervision as sv + import easyocr + + reader = easyocr.Reader(['en']) + results = reader.readtext() + detections = sv.Detections.from_easyocr(results) + ``` + """ + bbox = np.array([result[0] for result in easyocr_results]) + xyxy = np.hstack((np.min(bbox, axis=1), np.max(bbox, axis=1))) + + return cls( + xyxy=xyxy, + confidence=np.array([result[2] for result in easyocr_results]), + class_id=np.arange(len(xyxy)), + data={TEXT_DATA_FIELD: np.array([result[1] for result in easyocr_results])}, + ) + @classmethod def empty(cls) -> Detections: """ From 6e07b174223cac702865adf30e1f2aeec36f13a2 Mon Sep 17 00:00:00 2001 From: Onuralp SEZER Date: Sun, 15 Sep 2024 05:26:43 +0300 Subject: [PATCH 2/8] =?UTF-8?q?feat:=20=E2=9C=A8=20=20from=5Feasyocr=20par?= =?UTF-8?q?agraph=20mode=20support=20added?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onuralp SEZER --- supervision/detection/core.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 54cae9a7..58d4c984 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -874,7 +874,12 @@ class Detections: return cls( xyxy=xyxy, - confidence=np.array([result[2] for result in easyocr_results]), + confidence=np.array( + [ + result[2] if len(result) > 2 and result[2] else 0 + for result in easyocr_results + ] + ), class_id=np.arange(len(xyxy)), data={TEXT_DATA_FIELD: np.array([result[1] for result in easyocr_results])}, ) From 1a870b9b1b87547dbd9c08615ba8c18bde28c111 Mon Sep 17 00:00:00 2001 From: Onuralp SEZER Date: Wed, 18 Sep 2024 22:44:07 +0300 Subject: [PATCH 3/8] =?UTF-8?q?fix:=20=F0=9F=90=9E=20empty=20image=20detec?= =?UTF-8?q?tion=20error=20corrected=20refactor:=20=E2=99=BB=EF=B8=8F=20=20?= =?UTF-8?q?update=20text=20data=20field=20to=20CLASS=5FNAME=5FDATA=5FFIELD?= =?UTF-8?q?=20in=20config=20and=20detection=20modules=20to=20reduce=20comp?= =?UTF-8?q?lexity=20of=20datafield=20names?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Onuralp SEZER --- supervision/config.py | 1 - supervision/detection/core.py | 10 ++++++++-- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/supervision/config.py b/supervision/config.py index 357ff2d4..b18d2e20 100644 --- a/supervision/config.py +++ b/supervision/config.py @@ -1,3 +1,2 @@ CLASS_NAME_DATA_FIELD = "class_name" ORIENTED_BOX_COORDINATES = "xyxyxyxy" -TEXT_DATA_FIELD = "text_data" diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 58d4c984..ed2ab28c 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -9,7 +9,6 @@ import numpy as np from supervision.config import ( CLASS_NAME_DATA_FIELD, ORIENTED_BOX_COORDINATES, - TEXT_DATA_FIELD, ) from supervision.detection.lmm import ( LMM, @@ -869,6 +868,9 @@ class Detections: detections = sv.Detections.from_easyocr(results) ``` """ + if len(easyocr_results) == 0: + return cls.empty() + bbox = np.array([result[0] for result in easyocr_results]) xyxy = np.hstack((np.min(bbox, axis=1), np.max(bbox, axis=1))) @@ -881,7 +883,11 @@ class Detections: ] ), class_id=np.arange(len(xyxy)), - data={TEXT_DATA_FIELD: np.array([result[1] for result in easyocr_results])}, + data={ + CLASS_NAME_DATA_FIELD: np.array( + [result[1] for result in easyocr_results] + ) + }, ) @classmethod From 47a7f929a209ed8628a7442fdfc9a276c193f119 Mon Sep 17 00:00:00 2001 From: LinasKo Date: Mon, 23 Sep 2024 13:45:42 +0300 Subject: [PATCH 4/8] from_easy_ocr: cast results to float, remove class_id --- supervision/detection/core.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) diff --git a/supervision/detection/core.py b/supervision/detection/core.py index ed2ab28c..959f1d94 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -873,20 +873,19 @@ class Detections: bbox = np.array([result[0] for result in easyocr_results]) xyxy = np.hstack((np.min(bbox, axis=1), np.max(bbox, axis=1))) + confidence = np.array( + [ + result[2] if len(result) > 2 and result[2] else 0 + for result in easyocr_results + ] + ) + ocr_text = np.array([result[1] for result in easyocr_results]) return cls( - xyxy=xyxy, - confidence=np.array( - [ - result[2] if len(result) > 2 and result[2] else 0 - for result in easyocr_results - ] - ), - class_id=np.arange(len(xyxy)), + xyxy=xyxy.astype(np.float32), + confidence=confidence.astype(np.float32), data={ - CLASS_NAME_DATA_FIELD: np.array( - [result[1] for result in easyocr_results] - ) + CLASS_NAME_DATA_FIELD: ocr_text, }, ) From 270b5f564fdddcc9f9771416efd8a9590221db29 Mon Sep 17 00:00:00 2001 From: LinasKo Date: Mon, 23 Sep 2024 13:53:29 +0300 Subject: [PATCH 5/8] Update annotator errors, suggesting fixes --- supervision/annotators/utils.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/supervision/annotators/utils.py b/supervision/annotators/utils.py index 100b7874..ae4f8cdc 100644 --- a/supervision/annotators/utils.py +++ b/supervision/annotators/utils.py @@ -51,14 +51,17 @@ def resolve_color_idx( if detections.class_id is None: raise ValueError( "Could not resolve color by class because " - "Detections do not have class_id" + "Detections do not have class_id. If using an annotator, " + "try setting color_lookup to sv.ColorLookup.INDEX or " + "sv.ColorLookup.TRACK." ) return detections.class_id[detection_idx] elif color_lookup == ColorLookup.TRACK: if detections.tracker_id is None: raise ValueError( "Could not resolve color by track because " - "Detections do not have tracker_id" + "Detections do not have tracker_id. Did you call " + "tracker.update_with_detections(...) before annotating?" ) return detections.tracker_id[detection_idx] From d01e76a9c7f1f9003af8b7f9fc4722bcd646499c Mon Sep 17 00:00:00 2001 From: LinasKo Date: Mon, 23 Sep 2024 14:14:08 +0300 Subject: [PATCH 6/8] easy_ocr: docstring explaining usage --- supervision/detection/core.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 052717dc..9ed679dc 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -857,7 +857,9 @@ class Detections: def from_easyocr(cls, easyocr_results: list) -> Detections: """ Create a Detections object from the - [EasyOCR](https://github.com/JaidedAI/EasyOCR) inference result. + [EasyOCR](https://github.com/JaidedAI/EasyOCR) result. + + Results are placed in the `data` field with the key `"class_name"`. Args: easyocr_results (List): The output Results instance from EasyOCR @@ -873,6 +875,7 @@ class Detections: reader = easyocr.Reader(['en']) results = reader.readtext() detections = sv.Detections.from_easyocr(results) + detected_text = detections["class_name"] ``` """ if len(easyocr_results) == 0: From f221019208293b077254ebcd5d8d7700bec1add5 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Mon, 23 Sep 2024 11:15:35 +0000 Subject: [PATCH 7/8] =?UTF-8?q?fix(pre=5Fcommit):=20=F0=9F=8E=A8=20auto=20?= =?UTF-8?q?format=20pre-commit=20hooks?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- supervision/detection/core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 9ed679dc..343050e9 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -858,7 +858,7 @@ class Detections: """ Create a Detections object from the [EasyOCR](https://github.com/JaidedAI/EasyOCR) result. - + Results are placed in the `data` field with the key `"class_name"`. Args: From 943a21412ead7eab2dd81302b3ad2142c0d9a396 Mon Sep 17 00:00:00 2001 From: LinasKo Date: Mon, 23 Sep 2024 14:22:39 +0300 Subject: [PATCH 8/8] fix regression: ncnn docs --- supervision/detection/core.py | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/supervision/detection/core.py b/supervision/detection/core.py index 343050e9..e1a2357e 100644 --- a/supervision/detection/core.py +++ b/supervision/detection/core.py @@ -906,10 +906,15 @@ class Detections: [ncnn](https://github.com/Tencent/ncnn) inference result. Supports object detection models. - Args: + Arguments: ncnn_results (dict): The output Results instance from ncnn. - import cv2 + Returns: + Detections: A new Detections object. + + Example: + ```python + import cv2 from ncnn.model_zoo import get_model import supervision as sv