如何用Python从复杂PDF提取/移除红色字符、读取验血文本异常结果?
解决方案:PDF红色字符处理与验血结果提取
一、提取PDF中的红色字符(基于Tesseract+OpenCV)
核心步骤
- 将PDF每页转为可处理的图片
- 过滤图片中的红色区域,保留红色像素
- 用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
相关产品推荐
相关产品推荐

