import math import cv2 import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.use('TkAgg') elevation=0 azimuth=0 def circle3d(): global elevation,azimuth # 创建一个新的图和一个3D坐标轴 fig = plt.figure() ax = fig.add_subplot(111, projection='3d') # 定义圆的参数 radius = 1 # 半径 theta = np.linspace(0, 2 * np.pi, 100) # 参数角度 x = radius * np.cos(theta) # x坐标 y = radius * np.sin(theta) # y坐标 z = np.zeros_like(theta) # z坐标(这里圆在xy平面上) # 绘制圆 # ax.plot(x, y, z, label='3D Circle', color='b') # 绘制圆的正俯视图 # 正视图(xz平面) ax.plot(x, np.zeros_like(theta), z, label='z View', color='r') ax.plot(np.zeros_like(theta), y, z, label='h View', color='b') # 俯视图(xy平面) ax.plot(x, y, np.zeros_like(theta), label='Top View', color='g') # 设置坐标轴范围 ax.set_xlim([-2, 2]) ax.set_ylim([-2, 2]) ax.set_zlim([-2, 2]) ax.set_xlabel('X') ax.set_ylabel('Y') ax.set_zlabel('Z') # 添加图例 ax.legend() # 设置初始视角 # ax.view_init(elev=53, azim=-48,roll=-38) # 俯仰角30度,方位角45度 ax.view_init(elev=90, azim=0, roll=0) # 俯仰角30度,方位角45度 # 隐藏整个坐标轴 # ax.axis('off') # 设置窗口透明度 fig.canvas.manager.window.attributes('-alpha', 0.6) # 设置窗口透明度为 0.6 # 显示图形 plt.show() # input("请用鼠标转动 调整角度 elevation and azimuth: ") # 获取当前的 elevation 和 azimuth elevation = ax.elev azimuth = ax.azim def perspective_transform_by_angle(img, _elevation, _azimuth): h, w = img.shape[:2] # 根据角度计算目标点位置 fov = math.radians(45) # 假设视场角45度 dz = 1 / math.tan(_elevation) dx = dz * math.tan(_azimuth) # 源图像四个角点(原始斜视图) src_points = np.float32([[0, 0], [w, 0], [w, h], [0, h]]) # 计算目标点(俯视图) dst_points = np.float32([ [w * 0.5 * (1 - dx), h * 0.5 * (1 - dz)], # 左上 [w * 0.5 * (1 + dx), h * 0.5 * (1 - dz)], # 右上 [w * 0.5 * (1 + dx), h * 0.5 * (1 + dz)], # 右下 [w * 0.5 * (1 - dx), h * 0.5 * (1 + dz)] # 左下 ]) # 获取变换矩阵并应用 M = cv2.getPerspectiveTransform(src_points, dst_points) transformed_image=cv2.warpPerspective(img, M, (h,w)) # 显示原始图像和变换后的图像 fig, ax = plt.subplots(1, 2,figsize= (12, 6)) ax[0].imshow(img) ax[0].set_title("Original Image") ax[1].imshow(transformed_image) ax[1].set_title("Transformed Image") plt.show() def trans_img(image_path ,x,y): global elevation, azimuth image = cv2.imread(image_path) image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB) # 获取图像尺寸 height, width = image.shape[:2] center_x, center_y = 532,385 #圆心 # 定义源图像的四个点(假设为矩形) sx1=center_x-100 sx2=center_x+100 sy1=center_y-100 sy2=center_y + 100 src_points = np.float32([ [sx1, sy1], # 左上 [sx2, sy1], # 右上 [sx2, sy2], # 右下 [sx1, sy2] # 左下 ]) # src_points = np.float32([ # [center_x, sy1], # 上 # [sx2, center_y], # 右 # [center_x, sy2], # 下 # [sx1, center_y] # 左 # ]) # 根据 elevation 和 azimuth 计算目标点 # 这里是一个简化的计算方法,可以根据实际需求调整 # 假设目标点在透视变换后的坐标 # 将斜视的画面变成俯视的画面 radius = 100 # 根据俯仰角和方位角计算目标点的偏移 offset_x = radius * np.sin(elevation) * np.cos(azimuth) offset_y = radius * np.sin(elevation) * np.sin(azimuth) offset_z = radius * np.cos(elevation) print(f"offset_x={offset_x},offset_y={offset_y}") # 计算目标点 # dst_points = np.float32([ # [0 - offset_x, 0 - offset_y], # 左上 # [width + offset_x, 0 - offset_y], # 右上 # [width + offset_x, height + offset_y], # 右下 # [0 - offset_x, height + offset_y] # 左下 # ]) dst_points = np.float32([ [sx1- offset_x, sy1- offset_y], # 上 [sx2 + offset_x, sy1 - offset_y], # 右上 [sx2 + offset_x, sy2+ offset_y], # 右下 [sx1 - offset_x, sy2 + offset_y] # 下 ]) # 计算透视变换矩阵 matrix = cv2.getPerspectiveTransform(src_points, dst_points) # 应用透视变换 transformed_image = cv2.warpPerspective(image, matrix, (width, height)) # 显示原始图像和变换后的图像 fig, ax = plt.subplots(1, 2,figsize= (12, 6)) ax[0].imshow(image) ax[0].set_title("Original Image") ax[1].imshow(transformed_image) ax[1].set_title("Transformed Image") plt.show() if __name__ == '__main__': circle3d() print("测试============") print(f"elevation: {elevation}") print(f" azimuth: {azimuth}") img_path="images/trans/subRawImg.jpg" rawimg=cv2.imread(img_path) cv2.imshow("raw Image", rawimg) # trans_img(img_path,elevation,azimuth) elev = math.radians(elevation) azim = math.radians(azimuth) perspective_transform_by_angle(rawimg, elev,azim)