AI_python_yoooger/event/zhuanhuan1.py
2025-07-09 17:26:38 +08:00

167 lines
7.2 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import numpy as np
import cv2
from pyproj import Transformer
import math
from PIL import Image
from pylab import *
from dataclasses import dataclass
def rotate_points_around_axis(points, axis, angle):
# 将轴转换为单位向量
axis =axis.squeeze()
axis = axis / np.linalg.norm(axis)
# 将角度转换为弧度
theta = np.radians(angle)
# 计算旋转矩阵
K = np.array([[0, -axis[2], axis[1]],
[axis[2], 0, -axis[0]],
[-axis[1], axis[0], 0]])
I = np.eye(3) # 单位矩阵
R = I + np.sin(theta) * K + (1 - np.cos(theta)) * np.dot(K, K)
# 将点平移到旋转轴的起点
# 旋转多个点
rotated_points = np.dot(R.T,points.T) # 矩阵乘法
# 再平移回去
return rotated_points
def rotate_points(points, center, theta):
"""
批量旋转二维点
:param points: 输入的二维点矩阵,形状为 (N, 2)
:param center: 旋转中心 (x_c, y_c)
:param theta: 旋转角度(弧度)
:return: 旋转后的点矩阵,形状为 (N, 2)
"""
# 平移到旋转中心
translated = points - center # 平移,使得中心在原点
rotation_matrix = np.array([[np.cos(theta), np.sin(theta)],
[-np.sin(theta), np.cos(theta)]])
# 应用旋转
rotated = translated @ rotation_matrix.T # 矩阵乘法
return rotated + center # 将旋转后的点移回原位置
def compute_rotation_matrix(pitch, roll1, yaw):
c2w_x = np.array([[1, 0, 0],
[0, math.cos(pitch), -math.sin(pitch)],
[0, math.sin(pitch), math.cos(pitch)]], dtype=np.float32)
c2w_y = np.array([[math.cos(roll1), 0, math.sin(roll1)],
[0, 1, 0],
[-math.sin(roll1), 0, math.cos(roll1)]], dtype=np.float32)
c2w_z = np.array([[math.cos(yaw), -math.sin(yaw), 0],
[math.sin(yaw), math.cos(yaw), 0],
[0, 0, 1]], dtype=np.float32)
c2w = c2w_x @ c2w_y @ c2w_z
# 按 Z-Y-X 顺序组合旋转矩阵
y=np.array([[0],[0],[0]])
c2w1 = np.hstack([c2w,y])
new_row = np.array([[0, 0, 0, 1]])
c2w1 = np.vstack([c2w1, new_row])
return c2w, c2w1
def create_transformation_matrix(tvec):
transform_matrix = np.eye(4) # 创建单位矩阵
transform_matrix[:3, 3] = tvec.flatten() # 平移向量
return transform_matrix
def dms2dd(x,y,z):
return x+y/60+z/3600
@dataclass
class ProjectTrans:
'''
计算坐标
'''
def __init__(self, f_mm, sensor_width_mm, sensor_height_mm, image_width_px, image_height_px, k1, k2, k3, k4, k5):
self.image_points = None
self.tvec = None
self.rvec = None
self.object_point = None
self.f_mm = f_mm # 物理焦距 (mm)
self.sensor_width_mm= sensor_width_mm # 传感器宽度 (mm)
self.sensor_height_mm=sensor_height_mm # 传感器高度 (mm)
self.image_width_px= image_width_px # 图像宽度 (px)
self.image_height_px= image_height_px # 图像高度 (px)
self.Ji = np.array([[k1], [k2], [k3], [k4],[k5]], dtype=np.float32)
self.camera_matrix = None
def apply_transformation(self, c2w, transform_matrix):
# 齐次化
homogeneous_points = np.hstack([self.object_point, np.ones((self.object_point.shape[0], 1))])
# 旋转平移
transformed_points = transform_matrix @ homogeneous_points.T
transformed_points = c2w.T @ transformed_points
return transformed_points[:3, :] # 返回前3列x, y, z坐标
def compute_camera_matrix(self): #返回内参矩阵
"""计算并返回相机内参矩阵."""
fx = floor((self.f_mm * self.image_width_px) / self.sensor_width_mm)
fy = floor((self.f_mm * self.image_height_px) / self.sensor_height_mm)
cx = self.image_width_px / 2
cy = self.image_height_px / 2
fx=3725
fy=3725
cx= 2640
cy=1978
# 构造内参矩阵
self.camera_matrix = np.array([
[fx, 0, cx],
[0, fy, cy],
[0, 0, 1]
], dtype=np.float32)
# def transform_Y(self):
# num_rows = self.image_points.shape[0]
# new_column = np.ones((num_rows, 1))
# self.image_points[:,0] +=80
# self.image_points[:,1] +=100
# self.image_points = np.hstack([self.image_points, new_column])
# transform = np.array([[math.cos(radians(-84.8)), -math.sin(radians(-84.8)), 2728*(1-math.cos(radians(-84.8)))+1980.*math.sin(radians(-84.8))],
# [math.sin(radians(-84.8)), math.cos(radians(-84.8)), 1980*(1-math.cos(radians(-84.8)))-2728*math.sin(radians(-84.8))],
# [0, 0, 1]], dtype=np.float32)
# self.image_points = (transform @ self.image_points.T).T
def projectPoints(self, object_point, tvec, rvec):
self.object_point = object_point
self.tvec=tvec
self.rvec=np.radians(rvec)
# transformer = Transformer.from_crs("epsg:4326", "epsg:4544")
# for index, point in enumerate(object_point):
# lat,lon,z = point
# self.object_poin t[index,1],self.object_point[index,0] = transformer.transform(lat, lon)
# self.tvec[1] ,self.tvec[0] = transformer.transform(tvec[0], tvec[1])
self.tvec = -self.tvec
# c2w = compute_rotation_matrix(np.pi - 0.1 / 180 * np.pi, 0.85 / 180 * np.pi, 0) # 计算旋转矩阵
# transform_matrix = create_transformation_matrix(self.tvec) # 创建平移矩阵
# self.object_point = self.apply_transformation(c2w, transform_matrix) # 旋转平移
# self.object_point = rotate_points_around_axis(self.object_point, np.array([0.0148148, -0.00174533, 0.999901]), -rvec[1])
c2w1, c2w = compute_rotation_matrix(np.pi-0.1/180*np.pi, -1/180*np.pi, 1/180*np.pi) #计算旋转矩阵
transform_matrix = create_transformation_matrix(self.tvec) #创建平移矩阵
self.object_point = self.apply_transformation(c2w, transform_matrix) #旋转平移
axis = c2w1.T @ np.array([[0],[0],[1]],dtype=np.float32)
self.object_point = rotate_points_around_axis(self.object_point.T,axis.T,- rvec[1])
self.object_point = rotate_points_around_axis(self.object_point.T, np.array((0.9999,-0.00174533,-0.0148)), (rvec[0]+90))
self.object_point = self.object_point.T
self.compute_camera_matrix() #计算相机内参矩
BUP=np.array([0,0,0],dtype=np.float32)
self.rvec = np.array([0,0,0],dtype=np.float32)
self.image_points, _ = cv2.projectPoints(self.object_point, self.rvec, BUP, self.camera_matrix, self.Ji)
self.image_points = self.image_points.squeeze()
# self.transform_Y()
# self.image_points = rotate_points(self.image_points, np.array([2640, 1978]), rvec[1]/180*np.pi)
return self.image_points
def plot(self):
x_coords=self.image_points[:,0]
y_coords=self.image_points[:,1]
print(self.image_points,self.rvec)
# 打开图像并绘制投影点
im = Image.open('DJI_正.jpeg')
imshow(im)
# plot(x_coords, y_coords, 'r*')
plot(2647.02,1969.38,'b*')# 绘制红色星标
show()
cv2.imwrite('result1.jp eg', im)