You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
164 lines
5.3 KiB
164 lines
5.3 KiB
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)
|