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.

199 lines
6.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

import math
import numpy as np
import model
model = model.Model()
u0 = model.u0
v0 = model.v0
f = model.f
H = model.H
dx = model.dx
dy = model.dy
alpha = model.alpha
beta = model.beta
"""
计算图像中一点到车辆坐标的距离
参数点在图像中的坐标x、y相机的外部偏转角参数alpha、beta
返回值:点在车辆坐标系下的二维坐标
"""
def calc_distance(x, y, alpha, beta):
Xp = (x - u0) * dx
Yp = -(y - v0) * dy
sq = math.sqrt(f * f + Yp * Yp)
eta = math.atan(Yp / f)
gamma = math.atan(1 / (math.tan(alpha) * math.tan(beta)))
seta = math.atan(1/math.sqrt(pow(math.tan(beta), 2) + 1 / pow(math.tan(alpha), 2)))
MP = H * math.fabs(Xp) / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))
OM = H / math.tan(seta + eta)
epsilon = math.atan((H * Xp / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))) / OM)
d = math.sqrt(MP ** 2 + OM ** 2)
Xw = d * math.cos(gamma + epsilon)
Yw = -d * math.sin(gamma + epsilon)
return Xw, Yw
"""
计算车辆坐标系下某点在图像中的位置
参数点在车辆坐标系下的坐标Xw、Yw相机的外部偏转角参数alpha、beta
返回值:点在图像中的二维坐标
"""
def calc_distance2(Xw, Yw, alpha, beta):
d = math.sqrt(Xw ** 2 + Yw ** 2)
seta = math.atan(1 / math.sqrt(pow(math.tan(beta), 2) + 1 / pow(math.tan(alpha), 2)))
gamma = math.atan(1 / (math.tan(alpha) * math.tan(beta)))
# 计算组合角度
angle = math.atan2(-Yw, Xw) # 使用atan2处理所有象限
# 解出epsilon
epsilon = angle - gamma
# 将结果调整到[-pi, pi]范围内
epsilon = (epsilon + math.pi) % (2 * math.pi) - math.pi
OM = math.fabs(d * math.cos(epsilon))
MP = math.fabs(d * math.sin(epsilon))
eta = math.atan(H / OM) - seta
Yp = math.tan(eta) * f
Xp = MP * math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta)/H
if epsilon > 0 :
Xp = Xp
else:
Xp = -Xp
x = Xp / dx +u0
y = -Yp / dy +v0
return int(x), int(y)
"""
计算图像中一点距离地面的高度
参数地面端点在图像中的坐标x_bot、y_bot垂线上端点在图像中的坐标x_top、y_top相机的外部偏转角参数alpha、beta
返回值:点距离地面的高度
"""
def calc_height(x_bot,y_bot,x_top,y_top,alpha,beta):
Xp = (x_bot - u0) * dx
Yp = -(y_bot - v0) * dy
sq = math.sqrt(f * f + Yp * Yp)
eta = math.atan(Yp / f)
gamma = math.atan(1 / (math.tan(alpha) * math.tan(beta)))
seta = math.atan(1/math.sqrt(pow(math.tan(beta), 2) + 1 / pow(math.tan(alpha), 2)))
MP = H * math.fabs(Xp) / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))
OM = H/math.tan(seta + eta)
Yp1 = -(y_top - v0) * dy
sq1 = math.sqrt(f * f + Yp1 * Yp1)
eta1 = math.atan(Yp1 / f)
# print(f"Yp1: {Yp1},eta1: {eta1}")
Zw = H - OM*math.tan(seta + eta1)
return Zw
"""
计算图像中车辆坐标系Xw、Yw所对应的轴线
参数:
返回值轴线上点在图像中的二维坐标x、y
"""
def calc_zeros_yto0(val):
# 定义搜索范围和步长
x_range = np.linspace(0, 1280, 1000)
y_range = np.linspace(0, 960, 1000)
# 存储解
solutions = []
tolerance = 1e-3 # 容忍误差
# 网格搜索
for x in x_range:
for y in y_range:
error = equations_yto0(x, y, val)
if error < tolerance:
solutions.append((x, y))
# 去除近似重复的解
unique_solutions = []
for sol in solutions:
# 检查是否与已找到的解近似
is_unique = True
for usol in unique_solutions:
if np.allclose(sol, usol, atol=1):
is_unique = False
break
if is_unique:
unique_solutions.append(sol)
x = []
y = []
print("找到的解:")
for sol in unique_solutions:
print(f"x = {sol[0]:.4f}, y = {sol[1]:.4f}")
x.append(sol[0])
y.append(sol[1])
return x, y
def equations_yto0(x, y, val):
Xp = (x - u0) * dx
Yp = -(y - v0) * dy
sq = math.sqrt(f * f + Yp * Yp)
eta = math.atan(Yp / f)
gamma = math.atan(1 / (math.tan(alpha) * math.tan(beta)))
seta = math.atan(1/math.sqrt(pow(math.tan(beta), 2) + 1 / pow(math.tan(alpha), 2)))
MP = H * math.fabs(Xp) / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))
OM = H / math.tan(seta + eta)
epsilon = math.atan((H * Xp / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))) / OM)
d = math.sqrt(MP ** 2 + OM ** 2)
Xw = d * math.cos(gamma + epsilon)
Yw = -d * math.sin(gamma + epsilon)
return (Yw - val)**2 # 误差平方和
"""
计算图像中车辆坐标系Yw=某一固定值所对应的轴线
参数:
返回值轴线上点在图像中的二维坐标x、y
"""
def calc_zeros_xto0(val):
# 定义搜索范围和步长
x_range = np.linspace(0, 1280, 1000)
y_range = np.linspace(0, 960, 1000)
# 存储解
solutions = []
tolerance = 1e-3 # 容忍误差
# 网格搜索
for x in x_range:
for y in y_range:
error = equations_xto0(x, y, val)
if error < tolerance:
solutions.append((x, y))
# 去除近似重复的解
unique_solutions = []
for sol in solutions:
# 检查是否与已找到的解近似
is_unique = True
for usol in unique_solutions:
if np.allclose(sol, usol, atol=1):
is_unique = False
break
if is_unique:
unique_solutions.append(sol)
x = []
y = []
# print("找到的解:")
for sol in unique_solutions:
# print(f"x = {sol[0]:.4f}, y = {sol[1]:.4f}")
x.append(sol[0])
y.append(sol[1])
return x, y
def equations_xto0(x, y, val):
Xp = (x - u0) * dx
Yp = -(y - v0) * dy
sq = math.sqrt(f * f + Yp * Yp)
eta = math.atan(Yp / f)
gamma = math.atan(1 / (math.tan(alpha) * math.tan(beta)))
seta = math.atan(1/math.sqrt(pow(math.tan(beta), 2) + 1 / pow(math.tan(alpha), 2)))
MP = H * math.fabs(Xp) / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))
OM = H / math.tan(seta + eta)
epsilon = math.atan((H * Xp / (math.sqrt(f ** 2 + Yp ** 2) * math.sin(seta + eta))) / OM)
d = math.sqrt(MP ** 2 + OM ** 2)
Xw = d * math.cos(gamma + epsilon)
Yw = -d * math.sin(gamma + epsilon)
return (Xw-val)**2 # 误差平方和