如何获取Numpy条件切片的索引以统一批量裁剪图片黑边?
批量去除图片左右黑边并统一裁剪的Python实现
核心思路
因为黑边渐变导致单图切片尺寸不一致,解决关键是先确定统一的裁剪边界索引,再将该索引复用至所有图片。可以通过两种可靠方式获取统一索引:选一张特征典型的基准图计算边界,或统计所有图片的有效列范围取公共区间。
步骤1:编写鲁棒的单图边界获取函数
放弃np.all(array > 10, axis=0)这种过于严格的判断(渐变黑边的列并非全黑),改用列像素均值/中位数来识别有效列,更适配渐变场景:
import numpy as np def get_crop_indices(gray_array, threshold=20): # 计算每列像素均值(对渐变黑边的识别更精准) col_stats = gray_array.mean(axis=0) # 也可以用中位数,对噪点更鲁棒:col_stats = np.median(gray_array, axis=0) # 筛选出所有有效列的索引 valid_cols = np.where(col_stats > threshold)[0] # 返回裁剪的左右边界(切片左闭右开,所以右边界要+1) return valid_cols[0], valid_cols[-1] + 1
步骤2:获取统一裁剪索引并批量处理
方式A:基于基准图复用索引
选一张黑边特征最典型的图片(比如无异常、黑边清晰的图),计算它的边界后直接应用到所有图:
from PIL import Image import glob # 获取所有图片路径 image_paths = glob.glob("./your_image_folder/*.jpg") # 先处理基准图,得到统一裁剪索引 base_img = Image.open(image_paths[0]).convert('L') base_gray = np.array(base_img) unified_left, unified_right = get_crop_indices(base_gray) # 批量裁剪所有图片 for path in image_paths: img = Image.open(path).convert('L') gray_array = np.array(img) # 应用统一索引裁剪 cropped_array = gray_array[:, unified_left:unified_right] # 后续数据分析或保存操作...
方式B:统计所有图的有效列取公共区间
如果担心基准图有偏差,可以统计所有图的边界范围,取所有图都覆盖的有效列区间:
all_lefts = [] all_rights = [] # 先遍历所有图,收集各自的裁剪边界 for path in image_paths: img = Image.open(path).convert('L') gray_array = np.array(img) left, right = get_crop_indices(gray_array) all_lefts.append(left) all_rights.append(right) # 取最大左边界(确保所有图的左黑边都被裁掉)、最小右边界(确保所有图的右黑边都被裁掉) unified_left = max(all_lefts) unified_right = min(all_rights) # 批量裁剪(同方式A的循环逻辑) for path in image_paths: img = Image.open(path).convert('L') gray_array = np.array(img) cropped_array = gray_array[:, unified_left:unified_right] # 后续操作...
注意事项
- 如果出现
unified_left >= unified_right,说明部分图片的有效区域过小,需要调整阈值或检查图片质量。 - 可根据实际黑边的深浅调整
threshold参数,渐变越明显,阈值可适当降低。
内容的提问来源于stack exchange,提问作者Madmem
相关产品推荐
相关产品推荐

