- 作者帖子
小透明游客先交代起因,最近有坛友分享地理书籍 “宅葬书十一种.明抄本_第8册”,下来后发现是黑白版,能读 可就是有水印。原图如下所示
下面是修改完,去掉水印的效果(对该文件来说,几乎没有影响):
项目声明:
仅供学习交流,本人不对封面动手,仅仅只是为了便于自己读书,水印不影响读书的话,也没必要处理。且这个方法 仅仅对黑白版有不错的效果,对原生 或像素波动大的未必管用。
思路如下:(说完思路 上代码)
核心的处理逻辑:确定水印区域,和该区域的像素点的范围 n (一般是 200以上),通过算法,将该片区域像素值 p > n的像素信息去掉(即 p = 255 )
就这么简单,没什么技术含量,因为水印的值,远远大过字的值。
但有个问题: 如何确定水印范围?
也不废话,我是通过计算估计出的大概值,从任务来说 覆盖范围可以大于水印,不能小于水印,大多少没影响。通过计算两个文件的 水印部分占据整个画面的比例关系,大概得出 y 是占据整个画面高度的 41.5% 左右(y 作为短边是前提),而x可以根据y来计算,通过比例来确定的好处是,不受文件像素大小的影响,哪怕把竖版给处理了,也不会报错。
测试环节:(测试水印范围)
可以看到,两个范围,带来的水印明显的变化。而文字显然不受其影响,这就是本项目成功的前提。
探索的过程中,本人还尝试更加完美的方法,那就是通过水印来建立 alpha通道(决定透明关系的)如下
这是用 photoshop 做的(需要一定ps熟练度),最初是打算用 透明通道精细化处理的,且看到网上有 AI的项目,也需要透明通道。
后来发现,不同的文件水印有点不一样,难以做到统一覆盖,特别是像素值不同的对齐问题,在加上对一般用户不够友好。处理起来也比较漫长。就决定回归简单的思路,用划定范围的操作。
下面是代码:
作用是将pdf文件,读取image,经过转换格式,处理水印,最后输出到一个文件夹内,至于图片到pdf 暂未涉及 下面代码,输入最下方的「文件路径」「保存图片文件夹路径」,还有指定不需要处理的前几页,和倒数几页。
from PIL import Image import fitz # PyMuPDF from io import BytesIO import pathlib
#背景为白的图
def level_config(p, threshold = 214, midtone = 150, white_point = 255):
if p > threshold:
p = white_point
elif p > midtone:
p = ( p/threshold) * 255
return p#灰度图(红楼梦)
# def level_config(p, threshold = 197, midtone = 150, white_point = 242):
# if p > threshold:
# p = white_point
# elif p > midtone:
# p = p
# return pdef adjust_level(image, region_height_percent, region_width_ratio):
# 获取图片的宽度和高度
width, height = image.size# 计算固定区域的高度和宽度
region_height = int(height * region_height_percent)
region_width = int(region_height * region_width_ratio)# 确定固定区域的左上角和右下角坐标
left = (width - region_width) // 2
top = (height - region_height) // 2
right = left + region_width
bottom = top + region_height
# 获取固定区域的像素数据
region = image.crop((left, top, right, bottom))# 获取像素数据
region = region.point(level_config) #函数对象# 将处理后的区域放回原图
image.paste(region, (left, top, right, bottom))
return imagedef extract_images_from_pdf(pdf_path, image_folder,pass_head = 2,pass_tail = 1, out_ext ='.jpg'):
# 加载 PDF
pdf_document = fitz.open(pdf_path)
print('开始处理')page_all = len(pdf_document)
# Iterate over each page
for page_number in range(page_all):
page = pdf_document[page_number]# 获得页面图片 对象的链接
images = page.get_images(full=True)for img_index, img_info in enumerate(images):
# Get the XREF of the image
xref = img_info[0]# Extract the image
base_image = pdf_document.extract_image(xref)
image_bytes = base_image["image"]
#获得原图扩展名
img_ext = base_image["ext"]#创建目录
pathlib.Path(image_folder).mkdir(parents=True, exist_ok=True)
image_path = f"{image_folder}/page_{page_number+1}_img_{img_index}{out_ext}"# 使用 BytesIO 将 byte 对象转换为文件对象
image_file = BytesIO(image_bytes)image_ = Image.open(image_file)
if page_number < pass_head or page_number >= (page_all - pass_tail) :
image_.save(image_path, "JPEG")
image_.close()
continueimage_ = adjust_level(image_, region_height_percent=0.43, region_width_ratio=0.88)
image_.save(image_path, "JPEG")
image_.close()
print(image_path)# Close the PDF pdf_document.close() print('图片提取完毕')
#文件路径 和 保存路径
pdf_path = "./宅葬书十一种.明抄本_第8册(共8册).pdf"
image_folder = "./宅葬书十一种.明抄本_第8册(共8册)"# 设置需要跳过的头几页,倒数的几页
pass_head = 2
pass_tail = 1extract_images_from_pdf(pdf_path, image_folder, pass_head = pass_head, pass_tail = pass_tail)
#######
后续说明:
之后我又测试了灰度图,是之前下载的红楼梦文件,但效果不是特别好,,,需要使用可以,解掉上面代码的 #灰度图(红楼梦)# def level_config() 函数部分,
红楼梦的灰度图有很多残留的现象,差强人意,不介意的的话,也是可以读的。
此外,大多数参数,都写死了,按道理要用面向对象的,但会增加很多代码长度。有能力也可以自己修改。
最后,如果分享 “./宅葬书十一种.明抄本_第8册(共8册).pdf” 的坛友看到,能否提供下,预处理的方法,如果能把文件都处理到这个样子,我的脚本就非常合适了。
就写到这,欢迎大家一起交流。作为代码菜鸟,疏漏再所难免,欢迎指正。
terrencew游客借楼顺便说个小技巧,文档做二值化用scikit image里的这个函数比较好,我用了这个比OpenCV的Adaptive Threshold(otsu大津法效果要好),大津法会出现文档周围有黑边的情况(是的,在很多文档中你会发现这样的效果),而合适参数的sauvola方法不会有此种效果。
thresh_sauvola = threshold_sauvola(image, window_size=window_size)以下是空头支票:
我有一套PDF拆分图、图像超分辨率处理(Super Resolution)、图像增强、页面划分、图像二值化的处理代码,只是配置环境麻烦一些(最麻烦的是要有Pytorch依赖显卡),代码写的也不好。。。等以后有机会调整下代码,放出来。
最后,其实我可以训练一个用于专门恢复古籍文字的图像超分算法,当前的文档超分算法基本是针对文本行,为OCR识别服务的,而为了人更好阅读而进行可视化的图像超分增强似乎不多见, 可惜业余没有时间做这个。大家有兴趣的可以搞起来
QQ2111游客代码用于什么软件?
小透明游客@terrencew #138090
感谢分享,之前用scikit learn 做数据分析,没想到还有个scikit image。
我的查询是,Niblack 和 Sauvola 是 局部阈值算法,按照局部的像素的平均灰度值和标准差,动态调整阈值;而otsu 只是整张照片算灰度直方图,得出全局阈值。要将文字背景颜色统一化,这些方法,应该是很有用的。
用代码图像处理,本人是第一次接触,初衷是用最简单可靠的方法,避免很多依赖项,这样可以让更多人使用上,即便这样也不简单。目前古文圈还没有技术共识,各种厉害的技术,都沉在大神们的箱底,我这篇只是抛砖引玉,做个人技术探索用,其次 总觉得 好的项目得有群策群力才行,慢慢用的人多了也好优化,编程的人也知道 该把力量集中在哪几个方向。
小透明游客@QQ2111 #138094
为了给不懂 python 的朋友,一个尝鲜的机会,这里提供了一个可运行的小脚本。
pan.baidu.com/s/1S-...w?pwd=8i4f
注意:
不推荐随意使用 网上下载的exe文件,能不用尽量不用
文件说明:
执行文件,是需要自己加上后缀的(exe),如下图所示。
这里也提供sha-1值:SHA1: 2A0B7D13407096D4169A1A2909AAB848E8551D9C其次,本脚本只具有 单张图片的处理能力(不涉及pdf部分),相当于上面代码的,核心功能截取。仅供感兴趣的朋友试验。
使用说明:
使用方法:双击 exe文件(或python环境下 打开py文件) --> 会弹出命令行界面 --> 将要处理的图片 用鼠标拖到命令行(或手动输入路径)--> 应该立马就能得到结果,生成的图片,以“测试”结尾,保存在 处理图片的同目录下。
编写说明:
解释下为什么不包括更多功能,主要是精力有限,再是 打包单个脚本 到一个可执行的文件,会对性能造成很大影响(跑车秒变拖拉机那种),加上本项目并不成熟,需要使用过程不断修改参数,打包后是不能修改内部的,等价于没法用。
后续进展:
经过一天的思考,想到一些优化思路。
1 针对文字背景的不均匀,可以用 削峰和压缩的操作,如下图,是用 matplotlib库画的图片的直方图统计,左边是未处理,右边是压缩完成(按照 30%比例 处理188-222的试验)
2 图像之所以感觉处理不干净,实际并非处理未尽,很多地方 本身就存在的,问题是与周围颜色差距太大,又非字体,就会感觉很奇怪。
图中的地方,本就是书籍版内信息,虽说也可以直接去掉,但字体的信息也会损失,需要斟酌一二。
假使不再修改阈值,个人觉得可以尝试 边缘柔和的操作。再结合降低背景色,应该会改善很多。
最后:
忘了交代一件事,就是整个编写过程,gpt 帮助了很多,真的是时代的利器,如若不是这样,对代码菜鸟来说,可能一周也搞不定这么多任务,本篇文字也不会有诞生的机会。
z3243游客这种图用老马的CEP(Comic Enhancer Pro)可以一键操作,照度选项设为“黑白文字”就可以了。
相对于针对特定区域去水印,确实不那么精细,但是对于黑白图来说效果是可以的,而且操作更简单
小甜圈游客水印影响看书心情!
蒸鱼游客可以使用WPS自带的图片编辑器去水印,选择画质修复,黑白效果。效果感觉不错:
有水印.png (5889×5169) (zhengyq.cn)和无水印.png (2999×2632) (zhengyq.cn)
- 作者帖子
正在查看 9 个帖子:1-9 (共 9 个帖子)
正在查看 9 个帖子:1-9 (共 9 个帖子)
正在查看 9 个帖子:1-9 (共 9 个帖子)