“开运算”在 PDF 清洗里的作用
1. 问题
把一本 100 页的报告转成 Markdown 时,页眉和页脚(公司 Logo、日期、页码、栏目名等)会在每一页重复。
如果不去掉它们,最后的文字会变成这样:
第 1 页:正文
页码:1 / 100
Logo
第 2 页:正文
页码:2 / 100
Logo
需要一种办法,让电脑自动找到“哪一条线以上是页眉”“哪一条线以下是页脚”,然后把它们剪掉。
2. 代码
_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)
kernel_width = max(5, w // 6)
detected_lines = cv2.morphologyEx(
binary,
cv2.MORPH_OPEN,
cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_width, 1)),
iterations=1,
)
_, binary = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY_INV)gray是灰度图;threshold把每个像素分成“黑或白”;200是阈值(亮度高于 200 的变白,低于 200 的变黑);THRESH_BINARY_INV表示“结果取反”,所以线条会变白、背景变黑;_表示我们不关心返回的第一个值,只要第二个binary。
kernel_width = max(5, w // 6)w是页面宽度的像素数;w // 6大约等于“把页面横向分成 6 份后的宽度”;max(5, ...)确保尺子至少 5 像素,避免页面很窄时无从下手。
detected_lines = cv2.morphologyEx(cv2.morphologyEx是 OpenCV 提供的“形态学运算”函数;- 这里用它来执行“开运算”;
- 结果会存到
detected_lines。binary,:输入图像就是刚才得到的黑白图。cv2.MORPH_OPEN,:指定操作模式为开运算(先腐蚀再膨胀)。cv2.getStructuringElement(cv2.MORPH_RECT, (kernel_width, 1)),:cv2.MORPH_RECT表示矩形结构元素;(kernel_width, 1)表示“宽 kernel_width、高 1 像素”的横向尺子;- 这个尺子越长,对长线越友好,对短线越苛刻。
iterations=1,:只执行一次,保证既能过滤噪声又不会把主要线条削掉。
):调用结束。此时detected_lines图像中就只剩下那些通过尺子考验的长横线。
3. 功能
想象把 PDF 页面打印出来,然后拿一把很长的尺子横着贴在纸上:
- 第一步:腐蚀(Erosion)——像用橡皮擦沿着尺子擦一遍
- 所有比尺子短的线段都会被彻底擦掉;
- 只有足够长、足够直的线还能撑住。
- 第二步:膨胀(Dilation)——再沿着尺子重描一次
- 对刚才幸存下来的长线进行“加粗”,恢复它们原来的厚度;
- 短线已经被擦没了,所以不会再回来。
为了更具体地理解,想象尺子在图上“逐像素滑动”:
- 腐蚀阶段:尺子覆盖到某个位置时,只有在尺子下方的每一个像素点都为白色(表示线条)时,这个位置才会保留白色;只要尺子范围内出现一个黑点,就把整个位置判为黑色。也就是说,尺子要求“整段连续白像素”才能通过。
- 膨胀阶段:在上一阶段保留下来的白色像素区域,尺子再次滑过时,只要尺子下方有一个像素是白色,就把整个尺子区域重新涂成白色,相当于把那条线补回原来的厚度。
这两步连在一起就是“开运算”:先用非常苛刻的条件确认“这里确实存在连续的白像素(长横线)”,再把它恢复成原来的粗细。
最终只剩下页眉、页脚那种“整块横向区域”,我们就能根据它们的高度去裁掉重复内容。
4. Debug
- 页眉/页脚本来就是纯文字,没有横线
- 画面里压根没有“连续白像素”,尺子每次滑过都会遇到黑点 → 全判黑。
- 解决:把
kernel_width调短(例如从页宽 1/6 改成 1/10 或 1/12),让文字行也能被视作“长线”。
- 扫描模糊或纸张泛黄
- 二值化时,灰度值落在阈值附近,导致大部分像素都被判成黑色。
- 解决:把阈值从 200 调到 170~190,或使用自适应阈值,让亮度不足的线条仍能变成白色。
- 页面内容太复杂(表格/多栏)
- 尺子滑过去时经常遇到内容断点,导致整个区域判黑。
- 解决:先在样章上手动观察,记录能够稳定识别的
kernel_width和阈值,再批量应用;必要时对页眉、正文、页脚分别设置不同的裁剪策略。
5. 小结
- 开运算 = 找到长直线,借此推断页眉/页脚位置。
- 目的 = 自动裁掉重复的表格化区域,只保留正文。
- 记住:“尺子越长,过滤越严”,根据不同 PDF 自由调节即可。
把它想象成“先把 PDF 变黑白,再用大尺子扫一遍”:只要理解这个画面,就能明白开运算对清洗 PDF 有多重要。