improve the OCR pipeline processing and outputs formatting
This commit is contained in:
@@ -33,7 +33,10 @@ class FigureDetector:
|
||||
try:
|
||||
import layoutparser as lp
|
||||
|
||||
self._predictor = lp.Detectron2LayoutModel(
|
||||
model_class = getattr(lp, "Detectron2LayoutModel", None) or getattr(lp, "AutoLayoutModel", None)
|
||||
if model_class is None:
|
||||
raise RuntimeError("layoutparser has no compatible layout model backend; install Detectron2")
|
||||
self._predictor = model_class(
|
||||
config_path=settings.detectors.figures.model,
|
||||
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"},
|
||||
extra_config=[
|
||||
@@ -67,7 +70,10 @@ class FigureDetector:
|
||||
block.block.x_2,
|
||||
block.block.y_2,
|
||||
)
|
||||
crop = image[int(y1) : int(y2), int(x1) : int(x2)]
|
||||
height, width = image.shape[:2]
|
||||
x1_i, x2_i = max(0, int(x1)), min(width, int(x2))
|
||||
y1_i, y2_i = max(0, int(y1)), min(height, int(y2))
|
||||
crop = image[y1_i:y2_i, x1_i:x2_i]
|
||||
figures.append(
|
||||
DetectedFigure(
|
||||
bbox=[float(x1), float(y1), float(x2), float(y2)],
|
||||
@@ -98,7 +104,10 @@ class CaptionExtractor:
|
||||
try:
|
||||
import layoutparser as lp
|
||||
|
||||
self._predictor = lp.Detectron2LayoutModel(
|
||||
model_class = getattr(lp, "Detectron2LayoutModel", None) or getattr(lp, "AutoLayoutModel", None)
|
||||
if model_class is None:
|
||||
raise RuntimeError("layoutparser has no compatible layout model backend; install Detectron2")
|
||||
self._predictor = model_class(
|
||||
config_path=settings.detectors.captions.model,
|
||||
label_map={0: "Text", 1: "Title", 2: "List", 3: "Table", 4: "Figure"},
|
||||
extra_config=[
|
||||
@@ -156,11 +165,14 @@ class CaptionExtractor:
|
||||
return figures
|
||||
|
||||
|
||||
def detect_figures(image: np.ndarray) -> list[DetectedFigure]:
|
||||
detector = FigureDetector()
|
||||
figures = detector.detect(image)
|
||||
_figure_detector = FigureDetector()
|
||||
_caption_extractor = CaptionExtractor()
|
||||
|
||||
captioner = CaptionExtractor()
|
||||
|
||||
def detect_figures(image: np.ndarray) -> list[DetectedFigure]:
|
||||
figures = _figure_detector.detect(image)
|
||||
|
||||
captioner = _caption_extractor
|
||||
figures = captioner.extract_captions(image, figures)
|
||||
|
||||
return figures
|
||||
|
||||
@@ -59,6 +59,7 @@ class TableDetector:
|
||||
try:
|
||||
import torch
|
||||
|
||||
original_height, original_width = image.shape[:2]
|
||||
pil_image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)
|
||||
pil_image = cv2.resize(pil_image, (800, 800))
|
||||
|
||||
@@ -77,8 +78,12 @@ class TableDetector:
|
||||
for score, _label, box in zip(
|
||||
results["scores"], results["labels"], results["boxes"], strict=True
|
||||
):
|
||||
box = [float(x) for x in box]
|
||||
resized_box = [float(x) for x in box]
|
||||
scale_x, scale_y = original_width / 800, original_height / 800
|
||||
box = [resized_box[0] * scale_x, resized_box[1] * scale_y, resized_box[2] * scale_x, resized_box[3] * scale_y]
|
||||
x1, y1, x2, y2 = map(int, box)
|
||||
x1, x2 = max(0, x1), min(original_width, x2)
|
||||
y1, y2 = max(0, y1), min(original_height, y2)
|
||||
crop = image[y1:y2, x1:x2]
|
||||
tables.append(
|
||||
DetectedTable(
|
||||
@@ -122,6 +127,7 @@ class TableStructureRecognizer:
|
||||
self._initialized = True
|
||||
|
||||
def recognize(self, table_crop: np.ndarray) -> tuple[list[dict[str, Any]] | None, str | None]:
|
||||
self._init()
|
||||
if self._model is None or self._processor is None:
|
||||
return None, None
|
||||
|
||||
@@ -150,8 +156,9 @@ class TableStructureRecognizer:
|
||||
}
|
||||
)
|
||||
|
||||
markdown = self._structure_to_markdown(structure, table_crop.shape)
|
||||
return structure, markdown
|
||||
# Structure models locate rows/cells but do not provide cell text. Do not
|
||||
# emit labels as fabricated table content; OCR must be associated separately.
|
||||
return structure, None
|
||||
except Exception as e:
|
||||
logger.warning("table_structure_recognition_failed", error=str(e))
|
||||
return None, None
|
||||
@@ -185,17 +192,19 @@ class TableStructureRecognizer:
|
||||
return None
|
||||
|
||||
|
||||
_table_detector = TableDetector()
|
||||
_table_structure_recognizer = TableStructureRecognizer()
|
||||
|
||||
|
||||
def detect_tables(image: np.ndarray) -> list[DetectedTable]:
|
||||
detector = TableDetector()
|
||||
tables = detector.detect(image)
|
||||
tables = _table_detector.detect(image)
|
||||
|
||||
if not tables:
|
||||
return tables
|
||||
|
||||
recognizer = TableStructureRecognizer()
|
||||
for table in tables:
|
||||
if table.image_crop is not None:
|
||||
structure, markdown = recognizer.recognize(table.image_crop)
|
||||
structure, markdown = _table_structure_recognizer.recognize(table.image_crop)
|
||||
table.structure = structure
|
||||
table.markdown = markdown
|
||||
|
||||
|
||||
Reference in New Issue
Block a user