基于Python与OpenCV的图片网格切割与不规则区域提取

青禾
青禾
发布时间:2026-10-12| 6人浏览过
原创

介绍如何使用Python结合Pillow与OpenCV库,将图片按行列网格自动拆分为若干子图,或通过多边形坐标提取不规则感兴趣区域。提供完整代码示例、参数配置方法及透明度通道处理技巧。

环境与前置准备

操作前请确保已安装图像处理核心库。命令行输入以下指令完成依赖安装:

pip install opencv-python pillow numpy

方法一:按行列等分网格切割(适用常规拆分)

第1步:初始化切割函数与参数校验

目的是读取源图片尺寸并计算单块宽高。脚本通过终端交互获取图片路径、输出目录、目标行数与列数。运行后需检查控制台输出是否显示原始分辨率及行列参数合法性,确认无异常后即可继续执行。

import os
from PIL import Image

def split_grid_image(src_path, row_num, col_num, out_dir):
    img = Image.open(src_path)
    width, height = img.size
    print(f'原始图片信息: {width}x{height}, 格式: {img.format}, 模式: {img.mode}')

    os.makedirs(out_dir, exist_ok=True)
    basename, ext = os.path.splitext(os.path.basename(src_path))

    cell_w = width // col_num
    cell_h = height // row_num

    count = 0
    for r in range(row_num):
        for c in range(col_num):
            left = c * cell_w
            top = r * cell_h
            right = left + cell_w
            bottom = top + cell_h
            box = (left, top, right, bottom)
            img.crop(box).save(os.path.join(out_dir, f'{basename}_{count}.{ext}'), ext.upper())
            count += 1
    print(f'切割完成,共生成 {count} 张子图至 {out_dir}')

# 交互入口示例
if __name__ == '__main__':
    target_img = input('请输入图片文件路径:')
    save_folder = input('请输入输出目录(直接回车则使用原图同级目录):')
    if not save_folder: save_folder = os.path.dirname(target_img)
    r = int(input('请输入切割行数:'))
    c = int(input('请输入切割列数:'))
    split_grid_image(target_img, r, c, save_folder)

第2步:执行切割并验证结果文件

运行脚本后,在指定输出文件夹内检查生成的图片命名格式是否严格遵循源文件名_索引.ext。若所有切片尺寸一致且拼接回原图无明显错位,即表示切割成功。注意:连续运行相同路径会覆盖旧文件,务必提前备份或使用新目录以避免数据丢失。

方法二:基于多边形坐标的区域提取(适用不规则裁剪)

第1步:构建掩膜与定义感兴趣区域

通过NumPy创建二维零矩阵,利用OpenCV的polylines勾勒轮廓,再用fillPoly填充白色作为透明遮罩。此步骤用于精确划定需要保留的像素范围,参数入口为坐标数组列表。

import cv2
import numpy as np
from PIL import Image

img = cv2.imread('target_photo.jpg')  # 替换为实际路径
pts_top = np.array([[0, 248], [512, 254], [512, 512], [0, 512]], dtype=np.int32)
pts_body = np.array([[0, 0], [512, 0], [512, 254], [0, 248]], dtype=np.int32)

mask_t = np.zeros(img.shape[:2], dtype='uint8')
cv2.fillPoly(mask_t, [pts_top], 255)
mask_b = np.zeros(img.shape[:2], dtype='uint8')
cv2.fillPoly(mask_b, [pts_body], 255)

第2步:应用位运算转换RGBA并保存

使用bitwise_and提取前景,并将BGR转为含Alpha通道的PNG以支持透明背景。遍历RGB阈值动态计算Alpha值,最后调用PIL另存。完成判断为终端打印通道最大值接近255,且对应目录下出现带透明背景的独立截图。

extracted_top = cv2.bitwise_and(img, img, mask=mask_t)
extracted_body = cv2.bitwise_and(img, img, mask=mask_b)

def bgr_to_rgba_alpha(src_arr, threshold=2):
    rgba = np.zeros((src_arr.shape[0], src_arr.shape[1], 4), dtype=np.uint8)
    rgba[:, :, :3] = src_arr
    alpha_mask = (src_arr[:,:,0] > threshold) | (src_arr[:,:,1] > threshold) | (src_arr[:,:,2] > threshold)
    rgba[:, :, 3][alpha_mask] = 255
    return rgba

pil_top = Image.fromarray(bgr_to_rgba_alpha(extracted_top))
pil_top.save('region_top.png', 'PNG')
print('不规则区域提取完成并已保存为PNG。')

完成判断与常见问题排查

切割任务结束后,打开输出文件夹核对切片数量是否与 行数 × 列数 完全匹配。若发现部分切片空白或越界,通常因源图非目标尺寸的整数倍导致余量分配不均,属正常现象。OpenCV 读写中文路径易报编码错误,建议在代码首行添加 cv2.imdecode(np.fromfile(path, dtype=np.uint8), -1) 替代标准读取函数。如需批量处理,可将交互输入替换为文件列表遍历逻辑。

简要总结

本文梳理了基于Python生态的图片拆解方案。网格法依赖PIL原生接口,代码轻量且适合规则数据集预处理;掩膜法借助OpenCV的图形绘制与位运算模块,能够灵活剥离复杂形状。开发者可根据数据清洗或视觉标注的实际需求,自由调整行列参数与坐标阵列,快速搭建自动化切图工作流。

以上就是基于Python和OpenCV进行图片切割处理的详细内容,更多关于Python图像处理及自动化办公的资料请关注本站其它相关文章!

相关标签:

免责声明:本文内容仅供参考,不代表本站观点。转载或引用请注明出处。

Python 相关产品和应用

全部下载
Selenium

Selenium

4.51.0 · Windows

用于浏览器自动化和 Web 测试的 Python 工具。

scikit-learn

scikit-learn

1.9.1 · Windows

常用 Python 机器学习算法与模型评估工具库。

Black

Black

26.10.1 · Windows

强调一致性的 Python 自动代码格式化工具。

Ruff

Ruff

0.17.1 · macOS

由 Rust 编写的高速 Python 代码检查和格式化工具。

pytest

pytest

9.1.1 · Windows

简洁而强大的 Python 自动化测试框架。

FastAPI

FastAPI

0.146.0 · Windows

高性能 Python API 框架,支持类型提示和自动接口文档。

Flask

Flask

3.1.3 · Windows

轻量灵活的 Python Web 应用框架。

Django

Django

6.1.2 · Windows

成熟的 Python Web 框架,适合构建内容站点和业务系统。

Spyder

Spyder

6.1.7 · Windows

面向科学计算与数据分析的 Python 集成开发环境。

SciPy

SciPy

1.18.1 · Windows

面向科学、工程和技术计算的 Python 算法库。