「我们以为难点是NLP简化,结果光是提取文字就已经是场噩梦。」——MediSimplify团队

这是六位工程师在MongoDB技术社区分享的真实经历。他们做了一款把医疗报告转成患者易懂语言的产品,却发现OCR(光学字符识别)这一步比想象中复杂十倍。

打开网易新闻 查看精彩图片

医疗报告的格式混乱到离谱:干净的PDF、手机拍的模糊照片、传真件扫描再邮件转发——什么都有。更麻烦的是,你以为的"PDF"可能是可选中文字的电子文档,也可能是300 DPI的扫描图片,打开之前完全不知道。

为什么OCR成了隐形杀手

团队最初低估了文档解析的复杂度。图片格式(JPG/PNG)必定要走OCR流程,这没问题。但PDF是个黑箱——里面可能有嵌入文字,也可能只是扫描图像的容器。

他们总结出一条铁律:永远先走便宜的路。提取PDF内嵌文字是瞬间完成的,质量完美。OCR又慢又容易出错,只有迫不得已才调用。

另一个现实障碍:Tesseract(开源OCR引擎)不一定装在每台服务器上。如果直接调用pytesseract.image_to_string(),没配置环境的用户只会看到晦涩的Python异常,完全不知道发生了什么。

ocr.py的设计哲学:一个入口,兜底所有混乱

团队没有让OCR逻辑散落在各处,而是建了专门的ocr.py服务层。所有文件上传端点都走这一个入口。它的职责极其单一:收原始字节,返回干净文字。

核心策略分三层:

第一层,PDF内嵌文字提取。用PyPDF2或pdfplumber直接读,能走通就立即返回,不碰OCR。

第二层,图像OCR。只有确认PDF里没有可选文字,或者上传的就是图片时,才启动Tesseract。关键细节:渲染页面时必须指定合适DPI,否则识别质量暴跌。

第三层,输出清洗。原始OCR结果满是噪声——双空格、断行错乱、乱码字符。这些噪音会直接搞崩下游的简化模型,必须过滤。

Tesseract路径的智能探测

团队写了一段防御性极强的路径解析逻辑。Tesseract可能装在系统任意位置:系统二进制目录、虚拟环境、运维自定义路径。硬编码路径只会让自己崩溃。

他们的解法是先查配置,再回退到系统搜索:

代码逻辑是:先读settings.tesseract_cmd配置,如果配置了且文件存在,直接用;如果配置的是命令名而非完整路径,用shutil.which解析;最后回退到系统默认搜索tesseract命令。

同一套代码,开发者的Mac、Docker容器、云虚拟机都能跑,零修改。

如果Tesseract实在找不到,他们不抛底层FileNotFoundError,而是立即抛出自定义异常,信息对人可读——在任何事情开始之前就拦住用户。

从像素到处方:工程决策的复利

回头看,这个OCR服务层的价值被严重低估了。它没做什么炫技的事,只是老老实实处理了医疗文档的现实混乱:格式不可预测、环境不可假设、输出不可信任。

但正是这些边界情况的覆盖,让NLP简化模型能收到相对干净的输入。上游省下的每一行防御代码,都是下游模型少犯的一次错。

医疗AI的落地,往往卡在这些"不性感"的基础设施环节。团队把ocr.py开源出来,或许能帮下一个做病历数字化的团队少熬几个夜。