You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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ç

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 20:19:57