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

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)