You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python从复杂PDF提取/移除红色字符、读取验血文本异常结果?

解决方案:PDF红色字符处理与验血结果提取

一、提取PDF中的红色字符(基于Tesseract+OpenCV)

核心步骤

  1. 将PDF每页转为可处理的图片
  2. 过滤图片中的红色区域,保留红色像素
  3. 用Tesseract识别红色区域内的文本

依赖安装

pip install pdf2image pytesseract opencv-python pillow

注意:需提前安装Tesseract OCR引擎,若未加入系统环境变量,需在代码中指定引擎路径

代码实现

import cv2
import numpy as np
from pdf2image import convert_from_path
import pytesseract

# 配置Tesseract路径(按需启用)
# pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe'

def extract_red_text_from_pdf(pdf_path):
    pages = convert_from_path(pdf_path)
    red_texts = []
    
    for page in pages:
        # 转OpenCV格式(BGR)
        img = cv2.cvtColor(np.array(page), cv2.COLOR_RGB2BGR)
        # 转HSV空间,便于精准过滤红色
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        
        # 红色的HSV双区间(红色在HSV中跨0度)
        lower_red1 = np.array([0, 120, 70])
        upper_red1 = np.array([10, 255, 255])
        lower_red2 = np.array([170, 120, 70])
        upper_red2 = np.array([180, 255, 255])
        
        # 生成红色掩码
        mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
        mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
        red_mask = mask1 + mask2
        
        # 提取红色区域并转灰度图,提升OCR准确率
        red_img = cv2.bitwise_and(img, img, mask=red_mask)
        gray_red = cv2.cvtColor(red_img, cv2.COLOR_BGR2GRAY)
        
        # 识别红色文本(中文用chi_sim,英文留空)
        text = pytesseract.image_to_string(gray_red, lang='chi_sim')
        if text.strip():
            red_texts.append(text.strip())
    
    return '\n'.join(red_texts)

# 使用示例
red_content = extract_red_text_from_pdf('complex.pdf')
print(red_content)

二、移除PDF中的红色字符

分文本型PDF(可编辑)和扫描型PDF(图片格式)两种场景处理

场景1:文本型PDF(用PyMuPDF)

import fitz  # PyMuPDF

def remove_red_text_from_text_pdf(input_pdf, output_pdf):
    doc = fitz.open(input_pdf)
    
    for page in doc:
        blocks = page.get_text("dict")["blocks"]
        for block in blocks:
            if "lines" not in block:
                continue
            for line in block["lines"]:
                for span in line["spans"]:
                    # 匹配红色(PyMuPDF中颜色为0-1浮点数,接近(1,0,0)即为红色)
                    if abs(span["color"][0] - 1) < 0.1 and abs(span["color"][1]) < 0.1 and abs(span["color"][2]) < 0.1:
                        span["text"] = ""
        
        # 更新页面内容
        page.set_text(blocks)
    
    doc.save(output_pdf)
    doc.close()

# 使用示例
remove_red_text_from_text_pdf('input.pdf', 'output_no_red.pdf')

场景2:扫描型PDF(图片格式)

import cv2
import numpy as np
from pdf2image import convert_from_path
from PIL import Image
import img2pdf

def remove_red_from_scanned_pdf(input_pdf, output_pdf):
    pages = convert_from_path(input_pdf)
    processed_imgs = []
    
    for page in pages:
        img = cv2.cvtColor(np.array(page), cv2.COLOR_RGB2BGR)
        hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
        
        # 生成红色掩码(同提取步骤)
        lower_red1 = np.array([0, 120, 70])
        upper_red1 = np.array([10, 255, 255])
        lower_red2 = np.array([170, 120, 70])
        upper_red2 = np.array([180, 255, 255])
        mask1 = cv2.inRange(hsv, lower_red1, upper_red1)
        mask2 = cv2.inRange(hsv, lower_red2, upper_red2)
        red_mask = mask1 + mask2
        
        # 将红色区域替换为白色(可根据实际背景色调整)
        img[red_mask > 0] = [255, 255, 255]
        
        # 转回PIL格式并收集
        processed_img = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
        processed_imgs.append(processed_img)
    
    # 生成无红色的PDF
    with open(output_pdf, "wb") as f:
        f.write(img2pdf.convert([img.filename for img in processed_imgs]))

# 使用示例
remove_red_from_scanned_pdf('scanned.pdf', 'scanned_no_red.pdf')

三、从验血文本文件读取异常结果

核心逻辑

通过正则表达式匹配包含↑、↓、H(偏高)、L(偏低)或“异常”标记的行,提取项目名称与结果

代码实现

import re

def extract_abnormal_blood_test(txt_path):
    abnormal_items = []
    # 正则匹配:适配常见验血报告格式,可根据实际调整
    pattern = re.compile(r'([^\d]+?)\s+([\d.]+)\s*(↑|↓|H|L|异常)')
    
    with open(txt_path, 'r', encoding='utf-8') as f:
        for line in f:
            line = line.strip()
            if not line:
                continue
            match = pattern.search(line)
            if match:
                item = match.group(1).strip()
                result = match.group(2).strip()
                flag = match.group(3).strip()
                abnormal_items.append(f"{item}: {result} ({flag})")
    
    return abnormal_items

# 使用示例
abnormal_results = extract_abnormal_blood_test('blood_test.txt')
for item in abnormal_results:
    print(item)

内容的提问来源于stack exchange,提问作者Bambi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 05:55:32