如何使用Python基于自定义掩码拆分网格图像并单独保存小图
Python拆分白色背景网格大图的实现方案
实现思路
利用白色背景和小图内容的像素差异,通过连通域分析定位所有独立小图的位置,再批量裁剪保存,完全兼容大小不固定的零散小图拆分需求。
依赖安装
首先安装需要用到的第三方库:
pip install opencv-python numpy pillow
完整实现代码
import cv2 import numpy as np from PIL import Image import os def split_grid_image(input_path, output_dir, white_threshold=240, min_area=100): # 创建输出目录 os.makedirs(output_dir, exist_ok=True) # 读取原图 img = cv2.imread(input_path, cv2.IMREAD_UNCHANGED) # 处理带透明度通道的图片,将透明区域转为白色 if img.shape[-1] == 4: alpha = img[:, :, 3] img[alpha == 0] = [255, 255, 255, 255] img_rgb = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR) else: img_rgb = img # 生成二值掩码:白色背景标为0,内容区域标为255 lower_white = np.array([white_threshold, white_threshold, white_threshold], dtype=np.uint8) upper_white = np.array([255, 255, 255], dtype=np.uint8) mask = cv2.inRange(img_rgb, lower_white, upper_white) mask = 255 - mask # 反转掩码,使内容区域为高亮状态 # 连通域分析,提取所有独立内容区域 num_labels, labels, stats, centroids = cv2.connectedComponentsWithStats(mask, connectivity=8) count = 0 # 遍历每个连通域,跳过第0个(全图背景区域) for i in range(1, num_labels): x = stats[i, cv2.CC_STAT_LEFT] y = stats[i, cv2.CC_STAT_TOP] w = stats[i, cv2.CC_STAT_WIDTH] h = stats[i, cv2.CC_STAT_HEIGHT] area = stats[i, cv2.CC_STAT_AREA] # 过滤面积过小的噪点区域 if area < min_area: continue # 裁剪对应区域并保存,转换OpenCV的BGR格式为常规RGB格式 crop_img = img_rgb[y:y+h, x:x+w] crop_img = cv2.cvtColor(crop_img, cv2.COLOR_BGR2RGB) Image.fromarray(crop_img).save(os.path.join(output_dir, f"crop_{count}.png")) count += 1 print(f"拆分完成,共导出{count}张小图") # 调用示例 if __name__ == "__main__": split_grid_image( input_path="你的输入大图路径.png", output_dir="./output_crops", white_threshold=240, min_area=200 )
参数说明
white_threshold:白色判断阈值,取值范围0-255,三个通道像素值均大于该阈值则判定为背景。如果你的图片背景不是纯白,可以适当调低该值。min_area:最小有效区域像素数,小于该值的连通域会被判定为噪点忽略,根据你要拆分的最小小图尺寸调整即可。connectivity=8:连通域判断规则,8连通比4连通对零散像素的合并效果更好,适合小图边缘不规整的场景。
内容的提问来源于stack exchange,提问作者Saujanya Kamthe
相关产品推荐
相关产品推荐

