from paddleocr import PaddleOCR import cv2 import warnings # 忽略弃用警告 warnings.filterwarnings("ignore", category=DeprecationWarning) # 使用最新推荐方式初始化OCR引擎 ocr = PaddleOCR( text_detection_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_det", text_recognition_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_rec", use_textline_orientation=False, # 新参数名替代use_angle_cls device='cpu' ) def recognize_text(image_path): # 读取图片 img = cv2.imread(image_path) if img is None: print(f"错误:无法读取图片 {image_path}") return try: # 使用新的predict方法替代已弃用的ocr方法 result = ocr.predict(img) except Exception as e: print(f"OCR处理失败: {str(e)}") return # 提取所有识别文本 texts = [] for line in result: if line: # 确保行非空 for word_info in line: # 新版本返回结构:[坐标, (文本, 置信度)] text = word_info[1][0] # 提取文本内容 texts.append(text) # 打印所有识别文本(每行一个) for text in texts: print(text) if __name__ == "__main__": image_path = "images/18040695_page_144_original.jpg" # 替换为你的图片路径 recognize_text(image_path) 上面是代码下面是问题D:\shiyongwenjian\xunlianmoxing\.venv\Scripts\python.exe D:\shiyongwenjian\xunlianmoxing\实验8.py ��Ϣ: ���ṩ��ģʽ���ҵ��ļ��� D:\shiyongwenjian\xunlianmoxing\.venv\Lib\site-packages\paddle\utils\cpp_extension\extension_utils.py:715: UserWarning: No ccache found. Please be aware that recompiling all source files may be required. You can download and install ccache from: https://github.com/ccache/ccache/blob/master/doc/INSTALL.md warnings.warn(warning_message) Creating model: ('PP-LCNet_x1_0_doc_ori', None) Using official model (PP-LCNet_x1_0_doc_ori), the model files will be automatically downloaded and saved in C:\Users\tao.yu02\.paddlex\official_models. Creating model: ('UVDoc', None) The model(UVDoc) is not supported to run in MKLDNN mode! Using `paddle` instead! Using official model (UVDoc), the model files will be automatically downloaded and saved in C:\Users\tao.yu02\.paddlex\official_models. Creating model: ('PP-OCRv5_server_det', 'C:\\Users\\tao.yu02\\.paddlex\\official_models\\PP-OCRv5_server_det') Creating model: ('PP-OCRv5_server_rec', 'C:\\Users\\tao.yu02\\.paddlex\\official_models\\PP-OCRv5_server_rec') n a o t o e e e e e e i e e 进程已结束,退出代码为 0
时间: 2025-07-22 11:35:31 浏览: 17
<think>根据问题描述,代码已经能够运行并输出结果,但输出结果似乎是一些单个字母,这可能不是期望的完整单词或句子。这通常是因为OCR将每个字母单独识别了,或者文本行被分割成了单个字符。
我们需要检查PaddleOCR的返回结果结构,并调整文本提取逻辑。
在PaddleOCR中,默认情况下,`predict`方法返回的是一个列表,其中每个元素代表一行的识别结果。每行结果是一个包含多个检测框信息的列表,每个检测框信息包括:
- 坐标点(四个点)
- 一个元组,包含识别文本和置信度
但是,如果我们的图片中每个字符都被单独检测了,那么每个`word_info`就是一个字符。如果我们希望将一行文本合并,我们需要按行合并。
然而,从输出看,每个字母单独一行,说明我们循环的方式是每个字符都单独打印。实际上,我们可能希望将同一行的字符合并成一个字符串。
修改思路:
1. 首先,我们需要将同一行的字符按照从左到右的顺序排序(因为OCR返回的可能是无序的,但通常按行从上到下,每行内从左到右)。
2. 然后,将同一行的字符合并成一个字符串。
但是,PaddleOCR的返回结果已经按行排列,每行内的检测框通常按从左到右排列(但为了确保,我们可以根据检测框的左上角x坐标排序)。
因此,我们修改代码,对每一行的检测框按照x坐标排序,然后将该行的所有文本连接起来。
修改后的recognize_text函数:
```python
def recognize_text(image_path):
# 读取图片
img = cv2.imread(image_path)
if img is None:
print(f"错误:无法读取图片 {image_path}")
return
try:
# 使用新的predict方法替代已弃用的ocr方法
result = ocr.predict(img)
except Exception as e:
print(f"OCR处理失败: {str(e)}")
return
# 提取文本:按行处理
for line in result:
if line: # 确保行非空
# 对当前行内的每个检测框按照左上角x坐标排序(假设每个检测框信息为[坐标, (文本, 置信度)])
# 坐标是四个点,我们取第一个点的x坐标(左上角)
sorted_line = sorted(line, key=lambda word_info: word_info[0][0][0])
# 提取该行所有文本
line_text = ''.join([word_info[1][0] for word_info in sorted_line])
print(line_text)
```
但是,注意:PaddleOCR的返回结果中,每一行已经是一个文本行,所以实际上每行内的检测框应该已经按顺序排列了。但有时可能会因为布局复杂而顺序错乱,所以排序是保险的做法。
另外,如果图片中有多行文本,那么`result`的每个元素就是一行,我们只需要将每行内的单词(或字符)连接起来即可。
但是,我们之前是每个字符单独一行输出,现在改为每行文本输出一行。
如果问题仍然存在(即识别结果还是单个字符),那么可能是模型设置问题。PP-OCRv5默认是检测文本行,然后识别整个文本行。如果它把每个字符都当作一个文本行,那可能是检测模型的问题。
不过,从代码中我们使用的是`PP-OCRv5_server_det`和`PP-OCRv5_server_rec`,这是服务器版模型,通常用于检测整行文本。
因此,我们首先尝试修改文本提取逻辑,按行合并。
如果修改后仍然输出单个字符,那么可能是图片本身的问题(比如字符间距过大,导致检测模型将每个字符都检测为一个独立框)。在这种情况下,我们可以尝试调整检测模型的参数,比如合并相邻框。
但首先,我们按上述修改代码,看看输出是否变为完整的行。
修改后的完整代码:
```python
from paddleocr import PaddleOCR
import cv2
import warnings
# 忽略弃用警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 使用最新推荐方式初始化OCR引擎
ocr = PaddleOCR(
text_detection_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_det",
text_recognition_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_rec",
use_textline_orientation=False, # 新参数名替代use_angle_cls
device='cpu'
)
def recognize_text(image_path):
# 读取图片
img = cv2.imread(image_path)
if img is None:
print(f"错误:无法读取图片 {image_path}")
return
try:
# 使用新的predict方法替代已弃用的ocr方法
result = ocr.predict(img)
except Exception as e:
print(f"OCR处理失败: {str(e)}")
return
# 按行处理结果
for line_idx, line in enumerate(result):
if line: # 确保行非空
# 对当前行内的检测框按照左上角x坐标排序
# 每个检测框的结构为: [ [[x1,y1],[x2,y2],[x3,y3],[x4,y4]], (文本, 置信度) ]
sorted_line = sorted(line, key=lambda word_info: word_info[0][0][0]) # 按左上角x坐标排序
# 提取该行所有文本
line_text = ''.join([word_info[1][0] for word_info in sorted_line])
print(f"行{line_idx+1}: {line_text}")
if __name__ == "__main__":
image_path = "images/18040695_page_144_original.jpg" # 替换为你的图片路径
recognize_text(image_path)
```
如果这样修改后仍然输出单个字符(即每行只有一个字符),那么我们需要检查图片和模型。
另外,我们也可以尝试使用PaddleOCR的默认模型(不指定模型路径)看是否正常,以排除模型问题。
如果问题依旧,我们可以尝试设置`ocr.predict`的参数`det`和`rec`,例如:
```python
result = ocr.predict(img, det=True, rec=True, cls=False)
```
但根据文档,这些参数默认就是True。
如果上述方法都不能解决问题,我们可以考虑输出调试信息,比如将检测框可视化,查看检测模型是否正确地检测到了文本行。
可视化代码示例(在recognize_text函数内):
```python
# 在得到result后,我们可以绘制检测框
output_image = img.copy()
for line in result:
for word_info in line:
box = word_info[0]
# 将box转换为整数坐标
box = [[int(coord[0]), int(coord[1])] for coord in box]
# 绘制四边形
for i in range(4):
cv2.line(output_image, tuple(box[i]), tuple(box[(i+1)%4]), (0, 255, 0), 2)
# 保存或显示图片
cv2.imwrite("output_with_boxes.jpg", output_image)
```
通过查看生成的图片,我们可以判断检测框是整行还是单个字符。
如果检测框是单个字符,那么可能是检测模型设置问题,或者图片本身字符间距过大。我们可以尝试调整检测模型的阈值,或者使用后处理合并相邻的框。
不过,由于时间关系,我们首先尝试修改文本提取逻辑,并可视化检测框。
因此,最终的调试代码(包含可视化)如下:
```python
from paddleocr import PaddleOCR
import cv2
import warnings
import os
# 忽略弃用警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 使用最新推荐方式初始化OCR引擎
ocr = PaddleOCR(
text_detection_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_det",
text_recognition_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_rec",
use_textline_orientation=False, # 新参数名替代use_angle_cls
device='cpu'
)
def recognize_text(image_path):
# 读取图片
img = cv2.imread(image_path)
if img is None:
print(f"错误:无法读取图片 {image_path}")
return
try:
# 使用新的predict方法替代已弃用的ocr方法
result = ocr.predict(img)
except Exception as e:
print(f"OCR处理失败: {str(e)}")
return
# 可视化:复制一份图像用于绘制检测框
output_image = img.copy()
# 按行处理结果
for line_idx, line in enumerate(result):
if line: # 确保行非空
# 对当前行内的检测框按照左上角x坐标排序
sorted_line = sorted(line, key=lambda word_info: word_info[0][0][0]) # 按左上角x坐标排序
# 提取该行所有文本
line_text = ''.join([word_info[1][0] for word_info in sorted_line])
print(f"行{line_idx+1}: {line_text}")
# 绘制当前行的所有检测框
for word_info in sorted_line:
box = word_info[0]
# 将box转换为整数坐标
box = [[int(coord[0]), int(coord[1])] for coord in box]
# 绘制四边形
for i in range(4):
start_point = tuple(box[i])
end_point = tuple(box[(i+1) % 4])
cv2.line(output_image, start_point, end_point, (0, 255, 0), 2)
# 在框的左上角显示文本
cv2.putText(output_image, word_info[1][0], tuple(box[0]), cv2.FONT_HERSHEY_SIMPLEX, 0.8, (0, 0, 255), 2)
# 保存可视化结果
output_path = os.path.join("output", os.path.basename(image_path))
os.makedirs("output", exist_ok=True)
cv2.imwrite(output_path, output_image)
print(f"可视化结果已保存至: {output_path}")
if __name__ == "__main__":
image_path = "images/18040695_page_144_original.jpg" # 替换为你的图片路径
recognize_text(image_path)
```
运行此代码后,检查输出的图片,看检测框是整行还是单个字符。如果是单个字符,那么可能需要调整检测模型参数或使用不同的模型。
另外,如果图片是竖排文本,可能需要设置`use_textline_orientation=True`(但之前我们关闭了)。
如果问题仍然无法解决,请考虑更换图片测试,或使用PaddleOCR的默认模型(不指定模型路径,让程序自动下载)。
由于我们无法看到图片,所以只能提供这些调试方法。
如果经过上述步骤,问题得到解决,那么就可以得到完整的行文本。
如果问题依旧,请根据可视化结果进一步分析。
现在,我们假设问题是由于检测模型将每个字符都检测出来导致的,我们可以尝试使用后处理合并相邻的框(比如水平方向距离小于阈值的框合并)。但这比较复杂,PaddleOCR可能已经提供了相关的参数。
我们可以尝试设置检测模型的合并参数,例如在初始化PaddleOCR时设置:
```python
ocr = PaddleOCR(
...,
det_db_box_thresh=0.5, # 默认0.6,降低可能使框更多
det_db_unclip_ratio=1.5, # 默认1.5,增大可能使框更大
...
)
```
但调整这些参数需要根据实际情况。
考虑到时间,我们建议先使用可视化方法确定问题,再调整参数。
如果希望快速得到整行文本,也可以尝试使用PaddleOCR的`--use_mp`参数(多进程)或更换图片测试。
由于代码已经能够运行,只是识别结果不理想,我们调整了文本合并方式并添加了可视化。请运行上述代码,观察输出和可视化结果。
如果运行后输出是整行文本,则问题解决;如果仍然是单字,则可能是图片或模型问题。
最后,如果问题仍然存在,请尝试使用更简单的图片测试。
注意:以上代码需要确保有写入“output”目录的权限。
由于我们无法直接运行,请根据实际情况调整。
希望这些建议能帮助您解决问题。
§§相关问题§§:
1. 如何调整PaddleOCR的检测模型参数以合并相邻的文本框?
2. 在PaddleOCR中如何处理竖排文本的识别?
3. 如何提高OCR识别准确率,特别是在复杂背景图片上?
4. 如何用PaddleOCR批量处理一个文件夹中的所有图片?</think>根据输出结果,您的代码已经能够成功运行并输出识别文本,但输出内容似乎是单个字母的序列("n a o t o e e e e e e i e e")。这表明OCR识别结果可能存在问题,需要进一步优化。以下是完整的解决方案:
### 问题分析与解决方案
#### 问题原因:
1. **图像质量问题**:原始图像可能分辨率低、模糊或对比度不足
2. **预处理缺失**:没有进行必要的图像预处理
3. **识别参数不当**:可能需要调整OCR识别参数
4. **模型选择问题**:服务器版模型可能不适合您的图像类型
#### 完整优化代码:
```python
from paddleocr import PaddleOCR
import cv2
import numpy as np
import warnings
import os
# 忽略弃用警告
warnings.filterwarnings("ignore", category=DeprecationWarning)
# 创建输出目录
os.makedirs("output", exist_ok=True)
# 使用最新推荐方式初始化OCR引擎
ocr = PaddleOCR(
text_detection_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_det",
text_recognition_model_dir=r"C:\Users\tao.yu02\.paddlex\official_models\PP-OCRv5_server_rec",
use_textline_orientation=False, # 新参数名替代use_angle_cls
device='cpu',
lang='en', # 明确指定英文识别
rec_char_dict_path='en_dict.txt', # 使用英文词典
show_log=False # 关闭详细日志
)
def preprocess_image(image_path):
"""图像预处理函数"""
# 读取图片
img = cv2.imread(image_path)
if img is None:
print(f"错误:无法读取图片 {image_path}")
return None
# 1. 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 2. 自适应阈值二值化
binary = cv2.adaptiveThreshold(
gray, 255,
cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
cv2.THRESH_BINARY, 11, 2
)
# 3. 降噪
denoised = cv2.fastNlMeansDenoising(binary, h=10)
# 4. 锐化
kernel = np.array([[-1, -1, -1],
[-1, 9, -1],
[-1, -1, -1]])
sharpened = cv2.filter2D(denoised, -1, kernel)
# 保存预处理后的图像
output_path = os.path.join("output", os.path.basename(image_path))
cv2.imwrite(output_path, sharpened)
print(f"预处理图像已保存至: {output_path}")
return sharpened
def recognize_text(image_path):
"""OCR识别主函数"""
# 预处理图像
img = preprocess_image(image_path)
if img is None:
return
try:
# 使用predict方法进行OCR识别
result = ocr.predict(img)
except Exception as e:
print(f"OCR处理失败: {str(e)}")
return
# 提取所有识别文本
texts = []
for line in result:
if line: # 确保行非空
# 对当前行内的单词按x坐标排序
sorted_line = sorted(line, key=lambda x: x[0][0][0])
line_text = " ".join([word_info[1][0] for word_info in sorted_line])
texts.append(line_text)
# 打印所有识别文本
print("\n识别结果:")
for i, text in enumerate(texts, 1):
print(f"行 {i}: {text}")
# 保存结果到文件
result_path = os.path.join("output", os.path.basename(image_path) + ".txt")
with open(result_path, "w", encoding="utf-8") as f:
f.write("\n".join(texts))
print(f"识别结果已保存至: {result_path}")
if __name__ == "__main__":
image_path = "images/18040695_page_144_original.jpg"
recognize_text(image_path)
```
### 关键优化点解释:
1. **图像预处理**:
```python
def preprocess_image(image_path):
# 转换为灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 自适应阈值二值化
binary = cv2.adaptiveThreshold(gray, 255, ...)
# 降噪处理
denoised = cv2.fastNlMeansDenoising(binary, h=10)
# 锐化处理
sharpened = cv2.filter2D(denoised, -1, kernel)
```
- 灰度转换减少计算量
- 自适应阈值处理应对光照不均
- 非局部均值降噪保持边缘
- 锐化增强文本边缘
2. **OCR参数优化**:
```python
ocr = PaddleOCR(
...,
lang='en', # 明确指定英文识别
rec_char_dict_path='en_dict.txt', # 使用英文词典
show_log=False # 关闭详细日志
)
```
- 指定语言类型提高准确率
- 使用专用词典优化识别
3. **结果后处理**:
```python
# 对当前行内的单词按x坐标排序
sorted_line = sorted(line, key=lambda x: x[0][0][0])
line_text = " ".join([word_info[1][0] for word_info in sorted_line])
```
- 按x坐标排序确保单词顺序正确
- 添加空格分隔单词
4. **结果保存**:
```python
# 保存预处理图像
cv2.imwrite(output_path, sharpened)
# 保存识别结果
with open(result_path, "w", encoding="utf-8") as f:
f.write("\n".join(texts))
```
- 保存预处理图像用于调试
- 文本结果保存为文件
### 额外建议:
1. **尝试轻量级模型**:
```python
# 使用轻量级模型可能效果更好
ocr = PaddleOCR(
det_model_name='ch_PP-OCRv3_det',
rec_model_name='ch_PP-OCRv3_rec',
use_textline_orientation=False,
device='cpu',
lang='en'
)
```
2. **调整识别参数**:
```python
result = ocr.predict(
img,
det_db_thresh=0.3, # 降低检测阈值
det_db_box_thresh=0.5,
det_db_unclip_ratio=1.8,
rec_thresh=0.6 # 提高识别置信度阈值
)
```
3. **处理大图像**:
```python
# 对大图像进行分块处理
def process_large_image(img, block_size=1000):
height, width = img.shape[:2]
results = []
for y in range(0, height, block_size):
for x in range(0, width, block_size):
block = img[y:y+block_size, x:x+block_size]
result = ocr.predict(block)
results.extend(result)
return results
```
### 安装建议:
```bash
# 确保安装最新依赖
pip install --upgrade paddlepaddle paddleocr opencv-python
```
阅读全文
相关推荐




















