|
@@ -0,0 +1,158 @@
|
|
|
+import easyocr
|
|
|
+import numpy as np
|
|
|
+from PIL import Image, ImageDraw, ImageEnhance, ImageFilter
|
|
|
+from pdf2image import convert_from_path
|
|
|
+
|
|
|
+# 初始化 EasyOCR 阅读器,指定语言为中文,使用手动下载的模型路径
|
|
|
+reader = easyocr.Reader(['ch_sim'])
|
|
|
+reader.model_dir = r"E:\Anaconda3\Lib\site-packages\easyocr\model\EasyOCR-master" # 指定模型存放路径
|
|
|
+
|
|
|
+
|
|
|
+# 将传入的 cropped_image 图像按指定高度(line_height)分割成若干行,并在图像上绘制每行的矩形框。
|
|
|
+def split_image_into_lines_and_mark(cropped_image, line_height):
|
|
|
+ """
|
|
|
+ 将裁剪后的图片分割成若干行,并在图像上标出每一行的区域
|
|
|
+ :param cropped_image: 已经裁剪后的图片
|
|
|
+ :param line_height: 每一行的高度,默认是100像素
|
|
|
+ :return: 返回分割后的每一行图像,并且图像上标记了每一行的矩形框
|
|
|
+ """
|
|
|
+ # 获取图像的宽度和高度
|
|
|
+ image_width, image_height = cropped_image.size
|
|
|
+ lines = []
|
|
|
+ draw = ImageDraw.Draw(cropped_image) # 创建绘图对象
|
|
|
+
|
|
|
+ # 计算分割成多少行
|
|
|
+ for top in range(0, image_height, line_height):
|
|
|
+ bottom = min(top + line_height, image_height) # 保证最后一行不会超出图片高度
|
|
|
+ # 在图像上绘制矩形框,标出当前行
|
|
|
+ draw.rectangle((0, top, image_width, bottom), outline="green", width=2)
|
|
|
+ # 提取每一行的图像,并将其存储到 lines 列表中。
|
|
|
+ cropped_line = cropped_image.crop((0, top, image_width, bottom))
|
|
|
+ lines.append(cropped_line)
|
|
|
+
|
|
|
+ return lines, cropped_image
|
|
|
+
|
|
|
+
|
|
|
+# 在图像上绘制矩形框
|
|
|
+def draw_rectangle_on_pdf_image(image, outline_color="red", width=3):
|
|
|
+ """
|
|
|
+ 在PDF转为的图片上绘制矩形框
|
|
|
+ :param image: 转换后的PDF页面图像
|
|
|
+ :param crop_area: 裁剪区域,元组格式 (left, top, right, bottom)
|
|
|
+ :param outline_color: 矩形框的颜色,默认是红色
|
|
|
+ :param width: 矩形框的线条宽度,默认是3
|
|
|
+ """
|
|
|
+ # dpi为300时的参数
|
|
|
+ crop_area = (100, 200, 1550, 2400) # 调整裁剪区域
|
|
|
+ draw = ImageDraw.Draw(image) # 创建绘图对象
|
|
|
+ draw.rectangle(crop_area, outline=outline_color, width=width) # 绘制矩形框
|
|
|
+ return image
|
|
|
+
|
|
|
+
|
|
|
+# 裁剪图片的指定区域
|
|
|
+def crop_image(image):
|
|
|
+ """
|
|
|
+ 从图像中裁剪出指定区域
|
|
|
+ :param image: 要裁剪的图像
|
|
|
+ :param crop_area: 裁剪区域,元组格式 (left, top, right, bottom)
|
|
|
+ :return: 裁剪后的图像
|
|
|
+ """
|
|
|
+ crop_area = (250, 300, 1500, 2350) # 调整裁剪区域
|
|
|
+ cropped_image = image.crop(crop_area) # 使用crop方法裁剪
|
|
|
+ return cropped_image
|
|
|
+
|
|
|
+
|
|
|
+# 对图像进行预处理(增强对比度等)
|
|
|
+def preprocess_image(image):
|
|
|
+ # 转为灰度图
|
|
|
+ image_gray = image.convert('L')
|
|
|
+
|
|
|
+ # 去噪(使用模糊来去除噪声)
|
|
|
+ image_denoised = image_gray.filter(ImageFilter.MedianFilter(3)) # 使用3x3的中值滤波器去噪
|
|
|
+
|
|
|
+ # 增加对比度
|
|
|
+ enhancer = ImageEnhance.Contrast(image_denoised)
|
|
|
+ image_enhanced = enhancer.enhance(2.0) # 增加对比度
|
|
|
+
|
|
|
+ # 返回 NumPy 数组
|
|
|
+ return np.array(image_enhanced)
|
|
|
+
|
|
|
+# 将PDF转换为图片的函数
|
|
|
+def convert_pdf_to_images(pdf_file_path, dpi=300):
|
|
|
+ """
|
|
|
+ 将PDF文件转换为图片
|
|
|
+ :param pdf_file_path: PDF文件路径
|
|
|
+ :param dpi: 图片分辨率,默认300
|
|
|
+ :return: 转换后的图片列表
|
|
|
+ """
|
|
|
+ pages = convert_from_path(pdf_file_path, dpi)
|
|
|
+ return pages
|
|
|
+
|
|
|
+
|
|
|
+# 从图片中提取文本(使用easyocr)
|
|
|
+def extract_text_from_pict(page):
|
|
|
+ """
|
|
|
+ 从图片中提取文本
|
|
|
+ :param page: 要处理的图片
|
|
|
+ :return: 提取的文本
|
|
|
+ """
|
|
|
+ # 将 PIL 图片转换为 NumPy 数组
|
|
|
+ page_np = np.array(page)
|
|
|
+
|
|
|
+ # 进行图像预处理,确保返回的是 numpy 数组
|
|
|
+ page_np = preprocess_image(page) # 确保预处理后的图像是 numpy 数组
|
|
|
+
|
|
|
+ # 确保传递给 EasyOCR 的是 numpy 数组
|
|
|
+ result = reader.readtext(page_np) # 使用 EasyOCR 识别图片中的文本
|
|
|
+
|
|
|
+ text = ""
|
|
|
+ for detection in result:
|
|
|
+ text += detection[1] + '\n' # detection[1] 是识别出的文本内容
|
|
|
+
|
|
|
+ return text
|
|
|
+
|
|
|
+
|
|
|
+# 将提取的文本写入TXT文件
|
|
|
+def write_text_to_file(text, output_file_path):
|
|
|
+ with open(output_file_path, 'w', encoding='utf-8') as f:
|
|
|
+ f.write(text)
|
|
|
+
|
|
|
+
|
|
|
+# 主程序
|
|
|
+pdf_file_path = r'C:\Users\Admin\Desktop\女性文学exm.pdf'
|
|
|
+
|
|
|
+# 使用新封装的函数将PDF转换为图片
|
|
|
+pages = convert_pdf_to_images(pdf_file_path, dpi=300)
|
|
|
+
|
|
|
+# 在每一页图片上绘制矩形框
|
|
|
+for i, page in enumerate(pages):
|
|
|
+ # 绘制矩形框
|
|
|
+ page_with_box = draw_rectangle_on_pdf_image(page)
|
|
|
+ page_with_box.save(f'标记后的页面_{i + 1}.png', 'PNG') # 保存带有矩形框的图片
|
|
|
+ print(f"当前标记的是_{i + 1}页面")
|
|
|
+
|
|
|
+ # 裁剪图像
|
|
|
+ cropped_page = crop_image(page)
|
|
|
+ cropped_page.save(f'裁剪后的页面_{i + 1}.png', 'PNG') # 保存裁剪后的图片
|
|
|
+
|
|
|
+ # 提取未裁剪图片文本并保存
|
|
|
+ text = extract_text_from_pict(page) # 提取文本
|
|
|
+ write_text_to_file(text, f'未裁剪图片文本_{i + 1}.txt') # 保存提取的文本
|
|
|
+
|
|
|
+ # 提取裁剪后图片文本并保存
|
|
|
+ text = extract_text_from_pict(cropped_page) # 提取文本
|
|
|
+ write_text_to_file(text, f'裁剪后图片文本_{i + 1}.txt') # 保存提取的文本
|
|
|
+
|
|
|
+ # 分割裁剪后的图片为多行,并标出每行区域
|
|
|
+ lines, marked_image = split_image_into_lines_and_mark(cropped_page, line_height=80) # 调整每行的高度
|
|
|
+ # 保存标记了分割区域的图片
|
|
|
+ marked_image.save(f'按行分割后的裁剪页面_{i + 1}.png', 'PNG') # 保存标记区域后的图片
|
|
|
+
|
|
|
+ # 保存每一行图像
|
|
|
+ for j, line in enumerate(lines):
|
|
|
+ line.save(f'裁剪后页面_{i + 1}_行_{j + 1}.png', 'PNG') # 保存每行图像
|
|
|
+ print(f"当前保存的是裁剪后页面_{i + 1}_行_{j + 1}.png")
|
|
|
+ line_text = extract_text_from_pict(line)
|
|
|
+ write_text_to_file(line_text, f'裁剪后页面_{i + 1}分割的第_{j + 1}行.txt') # 保存提取的文本
|
|
|
+ break
|
|
|
+print("标记完毕")
|