如何在Python中通过OpenCV手动框选图像区域并裁剪
使用OpenCV实现手动框选区域裁剪图像
要实现手动框选目标区域再裁剪,核心是借助OpenCV的鼠标事件回调函数捕获框选操作,下面是完整的可运行代码和关键说明:
实现思路
- 用全局变量存储矩形框的起点、终点坐标,以及是否处于绘制状态
- 注册鼠标回调函数,处理左键按下、移动、释放三个事件,实时更新并绘制矩形
- 主循环中监听按键,按
c执行裁剪,按q退出程序
完整代码
import cv2 import numpy as np # 全局变量:存储矩形坐标和绘制状态 rect_start = (-1, -1) rect_end = (-1, -1) drawing = False def mouse_callback(event, x, y, flags, param): global rect_start, rect_end, drawing, img_copy if event == cv2.EVENT_LBUTTONDOWN: # 左键按下,记录起点,开始绘制 drawing = True rect_start = (x, y) # 复制原图,用于每次绘制时清除之前的矩形轨迹 img_copy = img.copy() elif event == cv2.EVENT_MOUSEMOVE and drawing: # 鼠标移动且处于绘制状态,更新终点,实时绘制矩形 rect_end = (x, y) temp_img = img_copy.copy() cv2.rectangle(temp_img, rect_start, rect_end, (0, 255, 0), 2) cv2.imshow('Select Region', temp_img) elif event == cv2.EVENT_LBUTTONUP: # 左键释放,结束绘制,确定最终矩形 drawing = False rect_end = (x, y) # 绘制最终的矩形 cv2.rectangle(img, rect_start, rect_end, (0, 255, 0), 2) cv2.imshow('Select Region', img) # 读取图片 img = cv2.imread('your_image_path.jpg') # 替换成你的图片路径 if img is None: print("无法读取图片,请检查路径是否正确") exit() img_copy = img.copy() cv2.namedWindow('Select Region') cv2.setMouseCallback('Select Region', mouse_callback) print("操作说明:") print("- 按住左键拖动,框选目标区域") print("- 松开左键确认框选") print("- 按 'c' 键裁剪并显示选中区域") print("- 按 'q' 键退出程序") while True: cv2.imshow('Select Region', img) key = cv2.waitKey(1) & 0xFF if key == ord('c'): # 确保坐标顺序正确(x1 < x2,y1 < y2) x1 = min(rect_start[0], rect_end[0]) y1 = min(rect_start[1], rect_end[1]) x2 = max(rect_start[0], rect_end[0]) y2 = max(rect_start[1], rect_end[1]) # 裁剪区域,要确保坐标在图像范围内 if x1 >=0 and y1 >=0 and x2 < img.shape[1] and y2 < img.shape[0]: cropped_img = img[y1:y2, x1:x2] cv2.imshow('Cropped Region', cropped_img) # 可选:保存裁剪后的图片 # cv2.imwrite('cropped_image.jpg', cropped_img) else: print("框选区域超出图片范围,请重新框选") elif key == ord('q'): break cv2.destroyAllWindows()
关键细节说明
- 轨迹清除:每次左键按下时复制原图,移动时在复制图上绘制矩形,避免留下多条矩形轨迹
- 坐标处理:裁剪前统一坐标顺序,防止因从右下往左上框选导致切片错误
- 边界检查:裁剪前判断坐标是否在图像范围内,避免数组越界报错
内容的提问来源于stack exchange,提问作者nisa kıraç
相关产品推荐
相关产品推荐

