{"record":{"id":"506e1daeeea18750","repo":"roboflow/supervision","slug":"easyocr-results-must-contain-four-corner-points-pe","errorCode":null,"errorMessage":"EasyOCR results must contain four corner points per detection.","messagePattern":"EasyOCR results must contain four corner points per detection\\.","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"src/supervision/detection/core.py","lineNumber":2181,"sourceCode":"\n            reader = easyocr.Reader(['en'])\n            results = reader.readtext(\"<SOURCE_IMAGE_PATH>\")\n            detections = sv.Detections.from_easyocr(results)\n            detected_text = detections[\"class_name\"]\n            ```\n        \"\"\"\n        if len(easyocr_results) == 0:\n            return cls.empty()\n\n        if isinstance(easyocr_results[0], str):\n            raise ValueError(\n                \"EasyOCR results produced with detail=0 do not include bounding \"\n                \"boxes. Call reader.readtext(..., detail=1) instead.\"\n            )\n\n        bbox = np.array([result[0] for result in easyocr_results], dtype=np.float32)\n        if bbox.ndim != 3 or bbox.shape[1:] != (4, 2):\n            raise ValueError(\n                \"EasyOCR results must contain four corner points per detection.\"\n            )\n        xyxy = np.hstack((np.min(bbox, axis=1), np.max(bbox, axis=1)))\n        confidence = np.array(\n            [\n                result[2] if len(result) > 2 and result[2] else 0\n                for result in easyocr_results\n            ]\n        )\n        ocr_text = np.array([result[1] for result in easyocr_results])\n\n        data: _DetectionDataType = {\n            CLASS_NAME_DATA_FIELD: ocr_text,\n            ORIENTED_BOX_COORDINATES: bbox,\n        }\n        return cls(\n            xyxy=xyxy.astype(np.float32),\n            confidence=confidence.astype(np.float32),","sourceCodeStart":2163,"sourceCodeEnd":2199,"githubUrl":"https://github.com/roboflow/supervision/blob/7f254d9784d4c37e0f03cd89ddee164c8db099c0/src/supervision/detection/core.py#L2163-L2199","documentation":"from_easyocr builds an (N, 4, 2) array of four corner points from result[0] of each item. If the collected bbox array does not have exactly shape (N, 4, 2), the per-detection geometry is not a quad and the method raises this ValueError.","triggerScenarios":"Passing easyocr_results whose first elements are not exactly 4 (x, y) pairs each — e.g. hand-built tuples with 2 or 8 points, lists of pixel coordinates with wrong nesting, or results from readtext with batched/altered formats (some paragraph or modified decoders), producing ragged input that np.array flattens incorrectly.","commonSituations":"Reformatting EasyOCR output into custom shapes before calling from_easyocr; mixing results from different OCR engines or frames; passing rotated-box centers/sizes instead of corner quads; ragged lists that numpy turns into an object array with wrong ndim.","solutions":["Pass EasyOCR's readtext(..., detail=1) output unmodified — it already yields 4-point quads.","Pre-validate shape before the call: np.array([r[0] for r in results]) must have .shape[1:] == (4, 2).","If you have xyxy boxes instead of quads, construct Detections directly (cls(xyxy=...)) rather than via from_easyocr."],"exampleFix":"# before\nresults = [(det[:2], det[2], det[3]) for det in custom_dets]  # 2-point 'bbox'\ndetections = sv.Detections.from_easyocr(results)\n\n# after\nquads = [np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]], dtype=np.float32) for x1,y1,x2,y2 in custom_xyxy]\nresults = [(q, 'text', 0.9) for q in quads]\ndetections = sv.Detections.from_easyocr(results)","handlingStrategy":"validation","validationCode":"import numpy as np\n\ndef valid_easyocr_quads(results: list) -> bool:\n    if not results:\n        return True\n    try:\n        arr = np.array([r[0] for r in results], dtype=np.float32)\n    except (ValueError, TypeError):\n        return False\n    return arr.ndim == 3 and arr.shape[1:] == (4, 2)\n\nassert valid_easyocr_quads(results)\ndetections = sv.Detections.from_easyocr(results)","typeGuard":"def is_quad_format(result_item: tuple) -> bool:\n    pts = result_item[0]\n    return (\n        isinstance(pts, (list, tuple)) and len(pts) == 4\n        and all(len(p) == 2 for p in pts)\n    )","tryCatchPattern":"try:\n    detections = sv.Detections.from_easyocr(results)\nexcept ValueError as e:\n    if 'four corner points' in str(e):\n        raise ValueError(f'malformed OCR geometry: {results[:2]!r}') from e\n    raise","preventionTips":["Don't reshape OCR output between readtext and from_easyocr","Validate shape (N, 4, 2) in a shared helper","For xyxy-only data build Detections directly"],"tags":["easyocr","ocr","shape","numpy","from-easyocr"],"backgroundTag":null,"analyzedSha":"7f254d9784d4c37e0f03cd89ddee164c8db099c0","analyzedAt":"2026-08-15T05:13:01.950Z","schemaVersion":2},"datasetVersion":"2026-08-15T22:17:37.221Z"}