Python交互式获取图像坐标并完成无损裁剪

追风的人
追风的人
发布时间:2026-10-12 | 2人浏览过
原创

本文演示如何利用Python结合Pillow与OpenCV,通过GUI交互点击方式精准获取图像任意两点的像素坐标,并以这两点为对角线无损提取矩形区域。内容涵盖完整脚本编写、坐标轴序对照、超大图安全加载策略及边界容错处理,适用于数据集清洗与视觉标注前期准备。

实现目标与环境准备

本文介绍如何使用Python交互式获取图像中任意两点的像素坐标,并以这两点为对角线无损裁剪出目标矩形区域。需要准备基础运行环境:Python 3.x,以及核心依赖库 Pillow、OpenCV 和 Matplotlib。

第1步:编写交互式取点脚本

目的:在图形界面中点击目标区域的起点与终点,自动记录并返回浮点数坐标。使用 pylab 的 ginput 功能最为直观,无需复杂UI框架。

from PIL import Image
from pylab import *


def get_point_coords(img_path):
    # 临时提高阈值,防止部分超大图预览时触发安全拦截
    Image.MAX_IMAGE_PIXELS = 1000000000

    im = array(Image.open(img_path))
    imshow(im)
    print('请点击图像的两个对角点,然后关闭窗口')
    coords = ginput(2)
    close()
    return coords

if __name__ == '__main__':
    points = get_point_coords('sample.jpg')
    print('返回坐标:', points)

运行后弹出窗口显示原图,光标十字准星跟随鼠标。分别单击确定起点与终点后按 Esc 或右键关闭窗口,终端将打印 (x1, y1), (x2, y2) 格式的元组数据。

待处理的原图示例
需要截取坐标的目标原图

第2步:读取坐标并执行无损裁剪

目的:将上一步得到的坐标传入裁剪逻辑,利用 OpenCV 读取图像矩阵并按像素范围切片,最终保存为无损 PNG 格式。

import cv2
import numpy as np
from point import get_point_coords


def crop_image_losslessly(img_path, point_list):
    [(x1, y1), (x2, y2)] = point_list
    img = cv2.imread(img_path)
    if img is None:
        raise FileNotFoundError("无法读取图片,请检查路径")
    
    # 确保坐标顺序正确:行对应Y轴(高度),列对应X轴(宽度)
    h, w = img.shape[:2]
    x1, y1 = int(min(x1, x2)), int(min(y1, y2))
    x2, y2 = int(max(x1, x2)), int(max(y1, y2))
    
    # 边界校验防止越界访问
    x2 = min(x2, w)
    y2 = min(y2, h)
    
    # NumPy切片严格遵循 [y_start:y_end, x_start:x_end]
    cropped_img = img[y1:y2, x1:x2, :]
    print(f"裁剪完成: 起始({x1}, {y1}) → 结束({x2}, {y2})")
    
    # 无损保存原始像素值
    cv2.imwrite("output_crop.png", cropped_img)
    return cropped_img

if __name__ == '__main__':
    raw_points = get_point_coords('sample.jpg')
    # 转换类型便于计算
    clean_points = [[int(p[0]), int(p[1])] for p in raw_points]
    crop_image_losslessly('sample.jpg', clean_points)

关键参数说明:cv2.imread() 加载的是多维数组,形状为 (高度H, 宽度W, 通道C)。因此切片必须严格遵循 [y1:y2, x1:x2] 的顺序。代码中加入了最小/最大值排序与边界裁剪,避免用户反向点击或点出画布边缘时报错。

按坐标裁剪后的青蛙局部截图
控制台输出指定坐标后生成的无损裁剪结果

常见报错与大图加载优化

当处理超过 8947 万像素(约 1.2千万分辨率以上)的高清扫描图或医疗影像时,Pillow 默认的安全策略会抛出 DecompressionBombWarning 并拒绝加载。此时需在项目入口处调整全局阈值。

添加以下配置即可恢复工作:

from PIL import Image
# 方法A:放宽限制至特定数值(如23亿像素)
Image.MAX_IMAGE_PIXELS = 2300000000

# 方法B:完全关闭像素数量拦截(适合内存充足的机器)
from PIL import ImageFile
ImageFile.LOAD_TRUNCATED_IMAGES = True
Image.MAX_IMAGE_PIXELS = None

若使用 IDE(如 PyCharm 或 VS Code)运行时弹窗卡顿或渲染异常,请检查编辑器设置中是否开启了「显示像素网格」或类似高 DPI 干扰选项,将其关闭可提升 Matplotlib 窗口的响应速度。

IDE内关闭像素网格显示的设置界面
IDE相关渲染设置建议关闭以保障绘图流畅

完成判断与总结

成功完成的操作标志为:终端无 Traceback 报错,且当前目录生成 output_crop.png。打开该文件核对,内容应为原图中鼠标点击的两点围成的矩形区域,无任何压缩失真或尺寸缩放。

以上就是Python交互式获取图像坐标并完成无损裁剪的详细内容,更多关于Python图像预处理与坐标定位的资料请关注本站其它相关文章!

本站声明

本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。

Python 相关产品和应用

全部下载

专题列表