需求
通过鼠标框选某个区域,返回这个区域的像素大小。
源码
# e:path\to\cal_rectangle_area.py
import cv2
import numpy as np # 初始化变量
image = cv2.imread('./vlcsnap-2024-09-25-10h51m27s007.png')
if image is None: print("Error: Image could not be read.") exit() # 窗口和缩放参数
scale = 1.0
pan_x, pan_y = 0, 0
rectangles = [] # 存储所有矩形框
refPt = []def draw_rectangle(event, x, y, flags, param): global refPt if event == cv2.EVENT_LBUTTONDOWN: # 计算真实坐标real_x = int((x + pan_x) / scale)real_y = int((y + pan_y) / scale)print(f"Mouse Position (Real): ({real_x}, {real_y})")refPt = [[x, y]] elif event == cv2.EVENT_LBUTTONUP and len(refPt) == 1: refPt.append([x, y]) rectangles.append(refPt) # 保存矩形框cv2.rectangle(image, tuple(refPt[0]), tuple(refPt[1]), (0, 255, 0), 2) cv2.imshow('image', image) print(f"Width: {abs(refPt[1][0] - refPt[0][0])}, Height: {abs(refPt[1][1] - refPt[0][1])}") refPt = [] def update_image():# 应用缩放和平移h, w = image.shape[:2]new_image = cv2.resize(image, (int(w * scale), int(h * scale)))new_image = new_image[pan_y:pan_y + int(h * scale), pan_x:pan_x + int(w * scale)]# 绘制所有矩形框for rect in rectangles:cv2.rectangle(new_image, tuple(rect[0]), tuple(rect[1]), (0, 255, 0), 2)cv2.imshow('image', new_image)def crop_and_save_image(x, y):# 裁剪图像h, w = image.shape[:2]x1 = max(x - 320, 0) # 640/2y1 = max(y - 320, 0) # 640/2x2 = min(x + 320, w) # 640/2y2 = min(y + 320, h) # 640/2cropped_image = image[y1:y2, x1:x2]cv2.imwrite('cropped_image.png', cropped_image) # 保存裁剪后的图像print(f"Cropped image saved as 'cropped_image.png'.")# 设置鼠标回调函数
cv2.namedWindow('image')
cv2.setMouseCallback('image', draw_rectangle) # 显示图像直到有键被按下
while True: update_image() # 更新显示的图像key = cv2.waitKey(1) & 0xFF if key == ord('q'): break elif key == ord('+'): # 缩放放大scale *= 1.1elif key == ord('-'): # 缩放缩小scale /= 1.1elif key == ord('w'): # 向上移动pan_y -= 10elif key == ord('s'): # 向下移动pan_y += 10elif key == ord('a'): # 向左移动pan_x -= 10elif key == ord('d'): # 向右移动pan_x += 10elif key == ord('c'): # 输入坐标裁剪图像x = int(input("Enter x coordinate: "))y = int(input("Enter y coordinate: "))crop_and_save_image(x, y)cv2.destroyAllWindows()