矩形图像旋转时同步旋转ROI的技术问题求助
矩形图像旋转时ROI(感兴趣区域)无法同步旋转的问题
我开发了一个图像查看程序,按下上箭头可将图像顺时针旋转90°,按下下箭头可逆时针旋转90°。图像上有一个带蓝色标记的ROI(感兴趣区域),当图像倒置(180度旋转)时ROI能同步旋转,但横向旋转(90°或270°)时,由于矩形图像宽高比反转,rotate_point函数及display_image中的逻辑无法正确实现ROI的同步旋转,特此求助。
程序代码如下:
import os import cv2 import keyboard import numpy as np current_dir = os.getcwd() # Get the current working directory. rotation_angle = 0 # Rotation angle of the image - initial rotation angle is obviously 0. engine_img = None # Placeholder for the image. # Function to rotate a point (x, y) around the image's center (cx, cy) by a given angle. def rotate_point(cx, cy, x, y, angle): angle_rad = np.deg2rad(angle) x_rot = (x - cx) * np.cos(angle_rad) - (y - cy) * np.sin(angle_rad) + cx y_rot = (x - cx) * np.sin(angle_rad) + (y - cy) * np.cos(angle_rad) + cy return int(x_rot), int(y_rot) def display_image(): global engine_img engine_img = cv2.imread(os.path.join(current_dir, "image.jpg")) # Read the image file - image is a RECTANGLE, not a square. if rotation_angle == 0: original_width, original_height = engine_img.shape[1], engine_img.shape[0] # Original dimensions when image is in standard position. desired_width, desired_height = 920, 690 # Desired dimensions when image is in standard position. if rotation_angle == 90 or rotation_angle == -270: original_width, original_height = engine_img.shape[0], engine_img.shape[1] # Swap original dimensions, since image has been flipped sideways. desired_width, desired_height = 690, 920 # Swap desired dimensions, since image has been flipped sideways. engine_img = cv2.rotate(engine_img, cv2.ROTATE_90_CLOCKWISE) elif rotation_angle == 180 or rotation_angle == -180: original_width, original_height = engine_img.shape[1], engine_img.shape[0] # Image is upside downm, so original dimensions are the same as when in standard position. desired_width, desired_height = 920, 690 # Image is upside downm, so desired dimensions are the same as when in standard position. engine_img = cv2.rotate(engine_img, cv2.ROTATE_180) elif rotation_angle == 270 or rotation_angle == -90: original_width, original_height = engine_img.shape[0], engine_img.shape[1] # Swap original dimensions, since image has been flipped sideways. desired_width, desired_height = 690, 920 # Swap desired dimensions, since image has been flipped sideways. engine_img = cv2.rotate(engine_img, cv2.ROTATE_90_COUNTERCLOCKWISE) engine_img = cv2.resize(engine_img, (desired_width, desired_height), interpolation=cv2.INTER_AREA) # Resize the image to desired dimensions. image_center_x, image_center_y = int(desired_width / 2), int(desired_height / 2) # Coordinates of point at the center of the image. cv2.circle(engine_img, (image_center_x, image_center_y), 5, (0,0,255), 5) # Draw a red circle at the image's center. bbox = { # Coordinates of ROI on the image (rectangle). "x_min": 2787, "y_min": 1385, "x_max": 3391, "y_max": 1881 } # Adjust coordinates based on the desired image's dimensions. x_min = int(bbox.get("x_min", 0) * desired_width / original_width) y_min = int(bbox.get("y_min", 0) * desired_height / original_height) x_max = int(bbox.get("x_max", 0) * desired_width / original_width) y_max = int(bbox.get("y_max", 0) * desired_height / original_height) # Function calls to get the position of the ROI after rotation x_min_rot, y_min_rot = rotate_point(image_center_x, image_center_y, x_min, y_min, rotation_angle) x_max_rot, y_max_rot = rotate_point(image_center_x, image_center_y, x_max, y_max, rotation_angle) center_x, center_y = int((x_min_rot + x_max_rot) / 2), int((y_min_rot + y_max_rot) / 2) # Coordinates of point at the center of the ROI on the image. cv2.circle(engine_img, (center_x, center_y), 3, (255,0,0), 3) # Draw a blue circle at the ROI's center. cv2.namedWindow("Image Viewer", cv2.WINDOW_AUTOSIZE | cv2.WINDOW_GUI_NORMAL) # Open a window. cv2.resizeWindow("Image Viewer", engine_img.shape[1], engine_img.shape[0]) # Resize opened window to the image's size. cv2.imshow("Image Viewer", engine_img) # Visualize the image on the opened window. display_image() # Initial call to open the window with the image while True: key = cv2.waitKey(0) if key == 27: # Close image window and end program when "ESC" key is pressed. break if keyboard.is_pressed('up arrow'): # Rotate image 90º clockwise. rotation_angle = (rotation_angle + 90) % 360 display_image() if keyboard.is_pressed('down arrow'): # Rotate image 90º counter-clockwise. rotation_angle = (rotation_angle - 90) % 360 display_image() cv2.destroyAllWindows()
所用图像:
需将图像下载至程序同目录并命名为image.jpg。
内容的提问来源于stack exchange,提问作者Matheus Caetano Rocha
相关产品推荐
相关产品推荐

