Python如何去除带文字标识的移动扫描件图像边框?
扫描App边框去除解决方案
原代码无法去除底部边框的核心原因是:diff.getbbox()会把所有和背景色有差异的区域都纳入裁剪范围,底部的App广告文字和边框背景存在色差,因此会被识别为有效内容的一部分,导致裁剪边界包含了底部带广告的边框。
解决方案思路
基于扫描件实际内容区域的非背景像素是连续成片存在、而边框区域的广告仅存在零星分散像素的特点,对逐行/逐列的非背景像素数量设置占比阈值,过滤掉仅含广告的边框行/列,从而定位真实内容的边界。
优化后代码
from PIL import Image, ImageChops def trim(image_path, threshold=0.01): im = Image.open(image_path) # 生成背景差异图,原逻辑保留 bg = Image.new(im.mode, im.size, im.getpixel((0,0))) diff = ImageChops.difference(im, bg) diff = ImageChops.add(diff, diff, 2.0, -100) width, height = diff.size # 筛选内容行:非背景像素占比高于阈值的行 content_rows = [] for y in range(height): row = diff.crop((0, y, width, y+1)) non_zero_pixel = 0 for x in range(width): if row.getpixel((x, 0)) != 0: non_zero_pixel += 1 if non_zero_pixel / width > threshold: content_rows.append(y) # 筛选内容列:非背景像素占比高于阈值的列 content_cols = [] for x in range(width): col = diff.crop((x, 0, x+1, height)) non_zero_pixel = 0 for y in range(height): if col.getpixel((0, y)) != 0: non_zero_pixel += 1 if non_zero_pixel / height > threshold: content_cols.append(x) if not content_rows or not content_cols: return im # 计算真实内容的边界框并裁剪 real_bbox = (min(content_cols), min(content_rows), max(content_cols)+1, max(content_rows)+1) return im.crop(real_bbox) # 调用示例 crop_image = trim("你的图片路径.jpg")
调参说明
- 函数中的
threshold参数为判断内容行/列的最低非背景像素占比,默认值0.01代表非背景像素占比超过1%才会被识别为内容区域。如果底部广告残留,可适当调大该值(比如0.02、0.05);如果出现内容被误裁剪的情况,可调低该值。 - 如果是色差较小的彩色扫描件出现识别不准,可以调整
ImageChops.add中的-100参数,数值越小对色差的敏感度越低。
内容的提问来源于stack exchange,提问作者Jeril
相关产品推荐
相关产品推荐

