Python如何实现显示图像并支持鼠标交互选择区域裁剪
交互式鼠标选框图像裁剪实现
不需要额外找专用裁剪库,直接基于OpenCV鼠标事件+PIL裁剪能力就能实现完整的交互选框裁剪功能,完全匹配鼠标自由选区域裁剪的需求。
交互操作规则
- 运行代码后自动弹出原始图像展示窗口
- 按住鼠标左键拖动即可实时看到绿色选框,框选需要裁剪的区域
- 松开鼠标左键自动完成选区内图像裁剪,自动弹出裁剪结果预览,同时将结果保存到本地
- 选框过程中按
r键可清空当前选框重新选择,按ESC键直接退出程序 - 支持任意方向拖动选框(从左上到右下/右下到左上都可自动适配坐标),自动过滤误触的极小无效选框
完整实现代码
import cv2 from PIL import Image # 全局状态变量 drawing = False # 标记是否正在拖动绘制选框 ix, iy = -1, -1 # 选框起始坐标 fx, fy = -1, -1 # 选框终点坐标 original_img = None # 存储原始图像,用于重置和裁剪 display_img = None # 窗口展示用图像,用于实时绘制选框 def mouse_crop_callback(event, x, y, flags, param): global drawing, ix, iy, fx, fy, display_img, original_img # 鼠标左键按下:记录选框起始点 if event == cv2.EVENT_LBUTTONDOWN: drawing = True ix, iy = x, y fx, fy = x, y # 鼠标拖动:实时更新选框 elif event == cv2.EVENT_MOUSEMOVE: if drawing: # 每次重绘先恢复原始图像,避免选框拖影残留 display_img = original_img.copy() cv2.rectangle(display_img, (ix, iy), (x, y), (0, 255, 0), 2) fx, fy = x, y # 鼠标左键松开:完成选框,执行裁剪 elif event == cv2.EVENT_LBUTTONUP: drawing = False fx, fy = x, y # 绘制最终选框 cv2.rectangle(display_img, (ix, iy), (fx, fy), (0, 255, 0), 2) # 坐标归一化,兼容任意拖选方向 x1, y1 = min(ix, fx), min(iy, fy) x2, y2 = max(ix, fx), max(iy, fy) # 过滤无效的极小选框(小于5像素判定为误触) if x2 - x1 < 5 or y2 - y1 < 5: print("选框范围过小,请重新选择") return # 转换为PIL格式执行裁剪,兼容原有PIL处理逻辑 pil_original = Image.fromarray(cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)) cropped_result = pil_original.crop((x1, y1, x2, y2)) # 预览并保存裁剪结果 cropped_result.show() cropped_result.save("cropped_result.jpg") print(f"裁剪完成,结果已保存为cropped_result.jpg,裁剪区域坐标:左上({x1},{y1}) 右下({x2},{y2})") if __name__ == "__main__": # 替换为你的目标图片路径 img_path = "test.jpg" original_img = cv2.imread(img_path) if original_img is None: print("图片读取失败,请检查文件路径是否正确") exit() display_img = original_img.copy() # 初始化窗口和鼠标回调 cv2.namedWindow("interactive_crop") cv2.setMouseCallback("interactive_crop", mouse_crop_callback) print("操作提示:按住左键拖动选择裁剪区域 | 按r重置选框 | 按ESC退出") # 窗口事件循环 while True: cv2.imshow("interactive_crop", display_img) key = cv2.waitKey(1) & 0xFF if key == 27: # ESC键退出 break elif key == ord('r'): # r键重置选框 display_img = original_img.copy() ix, iy, fx, fy = -1, -1, -1, -1 cv2.destroyAllWindows()
运行前准备
执行以下命令安装依赖库:pip install opencv-python pillow
扩展说明
- 代码默认是1:1像素匹配裁剪,如果需要对大图做缩放展示后再选框,只需要在计算裁剪坐标时乘上原图和展示图的缩放比例即可,不会出现裁剪区域偏移的问题
- 如果需要实现多区域连续裁剪,只需要把每次裁剪完成后的坐标和结果存到列表中,不需要修改核心交互逻辑
- 裁剪逻辑完全基于PIL实现,可以直接对接你之前写的PIL图像后处理流程,不需要做额外格式转换
内容的提问来源于stack exchange,提问作者willyro93
相关产品推荐
相关产品推荐

