如何在Python中创建图像掩码并基于掩码使用OpenCV裁剪图像
子图自动分割与裁剪解决方案

1. 自动生成掩码可行性说明
你提出的用Python自动检测边缘生成掩码的方案完全可行,当前样图的子图边界清晰、背景为纯白色,无需借助Photoshop、GIMP等工具手动制作掩码,通过OpenCV的图像预处理、轮廓筛选逻辑即可自动完成掩码生成,适配你10张图的批量处理需求。
2. 环境依赖
首先安装所需库:
pip install opencv-python numpy
3. 完整实现代码
3.1 掩码生成函数
该函数可自动识别图像中的所有子图,生成对应掩码与外接矩形坐标:
import cv2 import numpy as np import os def generate_subimage_masks(img_path, min_area_threshold=10000): img = cv2.imread(img_path) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 二值化反转,将白色背景转为黑色,子图区域转为白色 _, binary = cv2.threshold(gray, 240, 255, cv2.THRESH_BINARY_INV) # 提取最外层轮廓 contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) mask_list = [] rect_list = [] for cnt in contours: # 过滤面积过小的噪声轮廓 if cv2.contourArea(cnt) < min_area_threshold: continue # 生成单通道掩码 mask = np.zeros_like(gray) cv2.drawContours(mask, [cnt], -1, 255, thickness=cv2.FILLED) # 记录子图外接矩形 x, y, w, h = cv2.boundingRect(cnt) mask_list.append(mask) rect_list.append((x, y, w, h)) return img, mask_list, rect_list
3.2 基于掩码的裁剪函数
def crop_by_mask(img, mask, rect): x, y, w, h = rect # 保留掩码覆盖的子图区域 masked_img = cv2.bitwise_and(img, img, mask=mask) # 裁剪到最小外接矩形,去除多余黑边 cropped_subimg = masked_img[y:y+h, x:x+w] return cropped_subimg
3.3 调用示例
单张图片处理
# 替换为你的实际路径 input_img_path = "Z8Vyy.png" output_dir = "./sub_images" os.makedirs(output_dir, exist_ok=True) img, masks, rects = generate_subimage_masks(input_img_path) for i, (mask, rect) in enumerate(zip(masks, rects)): subimg = crop_by_mask(img, mask, rect) cv2.imwrite(os.path.join(output_dir, f"subimg_{i+1}.png"), subimg)
批量处理10张图片
input_dir = "./your_input_images" output_root = "./all_sub_images" os.makedirs(output_root, exist_ok=True) for filename in os.listdir(input_dir): if not filename.lower().endswith(('.png', '.jpg', '.jpeg')): continue # 为每张原图创建单独的子图保存目录 img_name = os.path.splitext(filename)[0] img_output_dir = os.path.join(output_root, img_name) os.makedirs(img_output_dir, exist_ok=True) img_path = os.path.join(input_dir, filename) img, masks, rects = generate_subimage_masks(img_path) for i, (mask, rect) in enumerate(zip(masks, rects)): subimg = crop_by_mask(img, mask, rect) cv2.imwrite(os.path.join(img_output_dir, f"subimg_{i+1}.png"), subimg)
4. 适配调整说明
如果你的其他图片存在背景色不统一、子图边界模糊的情况,可调整以下参数适配:
- 调整
generate_subimage_masks中的min_area_threshold阈值,过滤不符合大小的噪声轮廓 - 调整
cv2.threshold的第二个参数(当前为240),适配不同亮度的背景 - 边界不清晰时可在二值化前添加高斯模糊操作:
gray = cv2.GaussianBlur(gray, (3,3), 0)
内容的提问来源于stack exchange,提问作者Takuya2412
相关产品推荐
相关产品推荐

