|
@@ -215,7 +215,7 @@ def _call_paddleocr_api(
|
|
|
use_chart_recognition: bool = False,
|
|
use_chart_recognition: bool = False,
|
|
|
use_layout_detection: bool = False
|
|
use_layout_detection: bool = False
|
|
|
) -> tuple[bool, Optional[str]]:
|
|
) -> tuple[bool, Optional[str]]:
|
|
|
- """使用 Python API 调用 PaddleOCR VL
|
|
|
|
|
|
|
+ """通过独立脚本调用 PaddleOCR VL(避免显存共享问题)
|
|
|
|
|
|
|
|
Args:
|
|
Args:
|
|
|
image_path: 输入图片路径
|
|
image_path: 输入图片路径
|
|
@@ -226,61 +226,72 @@ def _call_paddleocr_api(
|
|
|
Returns:
|
|
Returns:
|
|
|
(是否成功, markdown 文件路径)
|
|
(是否成功, markdown 文件路径)
|
|
|
"""
|
|
"""
|
|
|
- import signal
|
|
|
|
|
-
|
|
|
|
|
- class TimeoutError(Exception):
|
|
|
|
|
- pass
|
|
|
|
|
-
|
|
|
|
|
- def timeout_handler(signum, frame):
|
|
|
|
|
- raise TimeoutError("PaddleOCR predict 超时")
|
|
|
|
|
-
|
|
|
|
|
try:
|
|
try:
|
|
|
if not os.path.exists(image_path):
|
|
if not os.path.exists(image_path):
|
|
|
- logger.error(f"[PaddleOCR API] 图片文件不存在: {image_path}")
|
|
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 图片文件不存在: {image_path}")
|
|
|
return False, None
|
|
return False, None
|
|
|
|
|
|
|
|
os.makedirs(save_path, exist_ok=True)
|
|
os.makedirs(save_path, exist_ok=True)
|
|
|
|
|
|
|
|
- # 获取 pipeline
|
|
|
|
|
- pipeline = _get_paddleocr_pipeline(use_chart_recognition, use_layout_detection)
|
|
|
|
|
|
|
+ # 获取 wrapper 脚本路径
|
|
|
|
|
+ current_dir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
|
|
|
|
+ wrapper_script = os.path.join(current_dir, "paddleocr_wrapper.py")
|
|
|
|
|
|
|
|
- logger.info(f"[PaddleOCR API] 开始处理: {image_path}")
|
|
|
|
|
- logger.info(f"[PaddleOCR API] Pipeline 类型: {type(pipeline)}")
|
|
|
|
|
|
|
+ if not os.path.exists(wrapper_script):
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 脚本不存在: {wrapper_script}")
|
|
|
|
|
+ return False, None
|
|
|
|
|
|
|
|
- # 执行识别(设置 60 秒超时)
|
|
|
|
|
- logger.info(f"[PaddleOCR API] 调用 predict 方法...")
|
|
|
|
|
- signal.signal(signal.SIGALRM, timeout_handler)
|
|
|
|
|
- signal.alarm(60) # 60 秒超时
|
|
|
|
|
|
|
+ # 获取 Python 解释器路径(使用 PaddleOCR 虚拟环境)
|
|
|
|
|
+ python_executable = "/mnt/win_d/paddle/.venv_paddleocr/bin/python"
|
|
|
|
|
+ if not os.path.exists(python_executable):
|
|
|
|
|
+ python_executable = sys.executable
|
|
|
|
|
+
|
|
|
|
|
+ # 构建命令
|
|
|
|
|
+ mode = 'doc_parser' if (use_chart_recognition or use_layout_detection) else 'ocr'
|
|
|
|
|
+ cmd = [python_executable, wrapper_script, '-i', image_path, '-o', save_path, '--mode', mode]
|
|
|
|
|
+
|
|
|
|
|
+ if use_chart_recognition:
|
|
|
|
|
+ cmd.append('--use-chart')
|
|
|
|
|
+ if use_layout_detection:
|
|
|
|
|
+ cmd.append('--use-layout')
|
|
|
|
|
+
|
|
|
|
|
+ # 获取设备
|
|
|
|
|
+ device = _get_paddle_ocr_device()
|
|
|
|
|
+ cmd.extend(['--device', device])
|
|
|
|
|
+
|
|
|
|
|
+ logger.info(f"[PaddleOCR Wrapper] 执行命令: {' '.join(cmd)}")
|
|
|
|
|
+
|
|
|
|
|
+ # 执行命令
|
|
|
|
|
+ result = subprocess.run(
|
|
|
|
|
+ cmd,
|
|
|
|
|
+ capture_output=True,
|
|
|
|
|
+ text=True,
|
|
|
|
|
+ timeout=120, # 2分钟超时
|
|
|
|
|
+ check=False,
|
|
|
|
|
+ )
|
|
|
|
|
|
|
|
- try:
|
|
|
|
|
- result = pipeline.predict(input=image_path)
|
|
|
|
|
- signal.alarm(0) # 取消超时
|
|
|
|
|
- logger.info(f"[PaddleOCR API] predict 返回,结果类型: {type(result)}")
|
|
|
|
|
- except TimeoutError:
|
|
|
|
|
- signal.alarm(0)
|
|
|
|
|
- logger.error(f"[PaddleOCR API] predict 超时(60秒),可能显存不足或模型加载失败")
|
|
|
|
|
|
|
+ if result.returncode != 0:
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 执行失败,返回码: {result.returncode}")
|
|
|
|
|
+ if result.stderr:
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 错误输出: {result.stderr}")
|
|
|
return False, None
|
|
return False, None
|
|
|
|
|
|
|
|
- # 保存结果
|
|
|
|
|
- image_basename = os.path.splitext(os.path.basename(image_path))[0]
|
|
|
|
|
|
|
+ # 从 stdout 解析 markdown 文件路径
|
|
|
|
|
+ output = result.stdout.strip()
|
|
|
|
|
+ if output.startswith("SUCCESS: "):
|
|
|
|
|
+ markdown_file = output.replace("SUCCESS: ", "")
|
|
|
|
|
+ if os.path.exists(markdown_file):
|
|
|
|
|
+ logger.info(f"[PaddleOCR Wrapper] 成功,markdown 文件: {markdown_file}")
|
|
|
|
|
+ return True, markdown_file
|
|
|
|
|
|
|
|
- logger.info(f"[PaddleOCR API] 开始处理结果...")
|
|
|
|
|
- for item in result:
|
|
|
|
|
- if hasattr(item, 'save'):
|
|
|
|
|
- item_save_path = os.path.join(save_path, image_basename)
|
|
|
|
|
- item.save(item_save_path)
|
|
|
|
|
- logger.info(f"[PaddleOCR API] 结果已保存到: {item_save_path}")
|
|
|
|
|
-
|
|
|
|
|
- # 查找生成的 markdown 文件
|
|
|
|
|
- markdown_file = os.path.join(item_save_path, f"{image_basename}.md")
|
|
|
|
|
- if os.path.exists(markdown_file):
|
|
|
|
|
- return True, markdown_file
|
|
|
|
|
-
|
|
|
|
|
- logger.warning(f"[PaddleOCR API] 未找到 markdown 输出文件")
|
|
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 未找到 markdown 输出文件")
|
|
|
return False, None
|
|
return False, None
|
|
|
|
|
|
|
|
|
|
+ except subprocess.TimeoutExpired:
|
|
|
|
|
+ logger.error("[PaddleOCR Wrapper] 执行超时(120秒)")
|
|
|
|
|
+ return False, None
|
|
|
except Exception as e:
|
|
except Exception as e:
|
|
|
- logger.error(f"[PaddleOCR API] 处理失败: {e}")
|
|
|
|
|
|
|
+ logger.error(f"[PaddleOCR Wrapper] 处理失败: {e}")
|
|
|
import traceback
|
|
import traceback
|
|
|
logger.error(traceback.format_exc())
|
|
logger.error(traceback.format_exc())
|
|
|
return False, None
|
|
return False, None
|