np.eye解释较好的

博客提供了一个关于np.eye解释较好的链接,链接为https://www.cnblogs.com/fpzs/p/10083846.html ,可从此链接获取相关解释信息。
import numpy as np import matplotlib.pyplot as plt from scipy.sparse import diags, kron from scipy.sparse.linalg import spsolve # 参数设置 L = 2.0 # 空间域边长 [-1,1] Nx, Ny = 101, 101 # 空间网格数 dx = L/(Nx-1) # 空间步长 dy = L/(Ny-1) T = 1.0 # 总时间 Nt = 100 # 时间步数 dt = T/Nt # 时间步长 x = np.linspace(-1,1,Nx) y = np.linspace(-1,1,Ny) X, Y = np.meshgrid(x, y) # 系数矩阵生成函数 def build_system_matrix(N, a_func, dx): main_diag = np.zeros(N) off_diag = np.zeros(N-1) for i in range(1,N-1): a_L = 0.5*(a_func[i] + a_func[i-1]) a_R = 0.5*(a_func[i] + a_func[i+1]) main_diag[i] = -(a_L + a_R)/dx**2 off_diag[i-1] = a_R/dx**2 return diags([off_diag, main_diag, off_diag], [-1, 0, 1]) # 定义变系数函数 a = np.exp(-(2*X-1)**2 - (2*Y-1)**2) # 初始化解矩阵 u = np.sin(np.pi*X) * np.sin(np.pi*Y) # 初始条件 u = u.reshape(-1) # 展平为一维向量 # 构建x方向和y方向的离散矩阵 A_x = build_system_matrix(Nx, a[0,:], dx) A_y = build_system_matrix(Ny, a[:,0], dy) A_total = kron(A_y, np.eye(Nx)) + kron(np.eye(Ny), A_x) # 隐式时间推进 I = diags([np.ones(Nx*Ny)], [0]) for n in range(Nt): rhs = u + 0.1*dt*(A_total.dot(u)) u = spsolve(I - 0.1*dt*A_total, rhs) # 结果可视化 u_plot = u.reshape(Ny, Nx) fig = plt.figure(figsize=(12,5)) ax1 = fig.add_subplot(121, projection='3d') ax1.plot_surface(X, Y, u_plot, cmap='coolwarm') ax1.set_title('Numerical Solution') ax2 = fig.add_subplot(122) levels = np.linspace(u_plot.min(), u_plot.max(), 20) contour = ax2.contourf(X, Y, u_plot, levels=levels, cmap='coolwarm') plt.colorbar(contour) ax2.set_title('Heatmap') plt.show()解释这个代码中的方程并检查错误
03-14
能否在这段代码中加入回环估计,使得每一变换矩阵可以校准import math import numpy as np import matplotlib.pyplot as plt import matplotlib matplotlib.rc("font", family='YouYuan') EPS = 0.0001 MAX_ITER = 100 show_animation = False def icp_matching(previous_points, current_points): """ Iterative Closest Point matching """ H = None dError = np.inf preError = np.inf count = 0 while dError >= EPS: count += 1 indexes, error = nearest_neighbor_association(previous_points, current_points) Rt, Tt = svd_motion_estimation(previous_points[:, indexes], current_points) # 更新当前点 current_points = (Rt @ current_points) + Tt[:, np.newaxis] dError = preError - error if dError < 0: break preError = error H = update_homogeneous_matrix(H, Rt, Tt) if dError <= EPS or MAX_ITER <= count: break R = np.array(H[0:-1, 0:-1]) T = np.array(H[0:-1, -1]) return R, T def update_homogeneous_matrix(Hin, R, T): r_size = R.shape[0] H = np.zeros((r_size + 1, r_size + 1)) H[0:r_size, 0:r_size] = R H[0:r_size, r_size] = T H[r_size, r_size] = 1.0 if Hin is None: return H else: return Hin @ H def nearest_neighbor_association(previous_points, current_points): """ 找到 current_points 中每个点在 previous_points 中的最近邻索引。 支持两组点数不同。 """ # 计算两组点的欧氏距离矩阵 n_prev = previous_points.shape[1] n_curr = current_points.shape[1] d = np.zeros((n_curr, n_prev)) for i in range(n_curr): diff = previous_points - current_points[:, i:i+1] d[i, :] = np.linalg.norm(diff, axis=0) indexes = np.argmin(d, axis=1) error = np.mean(np.min(d, axis=1)) return indexes, error def svd_motion_estimation(previous_points, current_points): pm = np.mean(previous_points, axis=1) cm = np.mean(current_points, axis=1) p_shift = previous_points - pm[:, np.newaxis] c_shift = current_points - cm[:, np.newaxis] W = c_shift @ p_shift.T u, s, vh = np.linalg.svd(W) R = (u @ vh).T t = pm - (R @ cm) return R, t # ===== 新增功能部分 ===== def generate_rectangle_points(length=20, width=10, n_points=2000, noise=0.05): """生成矩形边界点云并加噪声""" n_side = n_points // 4 top = np.vstack((np.linspace(-length / 2, length / 2, n_side), np.ones(n_side) * width / 2)) bottom = np.vstack((np.linspace(-length / 2, length / 2, n_side), np.ones(n_side) * -width / 2)) left = np.vstack((np.ones(n_side) * -length / 2, np.linspace(-width / 2, width / 2, n_side))) right = np.vstack((np.ones(n_side) * length / 2, np.linspace(-width / 2, width / 2, n_side))) points = np.hstack((top, bottom, left, right)) points += np.random.randn(2, points.shape[1]) * noise return points def split_by_angle(points, center=np.array([0, 0]), start=-30, step=0.2): """按角度扇区划分点云""" sectors = [] angles = np.degrees(np.arctan2(points[1, :] - center[1], points[0, :] - center[0])) angles = (angles + 360) % 360 t=int(360/step) for k in range(t): theta1 = (start + k * step) % 360 theta2 = (theta1 + 60) % 360 # 每个扇区宽度为60° if theta1 < theta2: mask = (angles >= theta1) & (angles <= theta2) else: # 角度跨越360°边界 mask = (angles >= theta1) | (angles <= theta2) Ak = points[:, mask] sectors.append(Ak) return sectors def merge_point_clouds(A_list, R_list, T_list): """将所有点云A_k变换到A1坐标系并融合""" merged = [A_list[0]] R_total = [np.eye(2)] T_total = [np.zeros(2)] # 累积每个点云的全局变换 for k in range(1, len(A_list)): Rk, Tk = R_list[k - 1], T_list[k - 1] R_acc = R_total[-1] @ Rk T_acc = R_total[-1] @ T_list[k - 1] + T_total[-1] R_total.append(R_acc) T_total.append(T_acc) Ak_global = R_acc @ A_list[k] + T_acc[:, None] merged.append(Ak_global) merged_points = np.hstack(merged) merged_points = np.unique(np.round(merged_points, 2), axis=1) return merged_points, R_total, T_total # ===== 主逻辑 ===== def main(): print("开始运行改造后的 ICP 例子...") # Step 1: 生成矩形点云 rect_points = generate_rectangle_points() # Step 2: 按角度扇区切分 sectors = split_by_angle(rect_points) R_list, T_list = [], [] used_sectors = [] # Step 3: 对相邻扇区进行 ICP for k in range(1, len(sectors)): A_prev = sectors[k - 1] A_curr = sectors[k] if A_prev.shape[1] < 5 or A_curr.shape[1] < 5: continue R, T = icp_matching(A_prev, A_curr) R_list.append(R) T_list.append(T) used_sectors.append(A_curr) print(f"ICP {k}: R=\n{R}\nT={T}") # Step 4: 融合所有点云到A1坐标系 merged_points, R_total, T_total = merge_point_clouds(sectors, R_list, T_list) # Step 5: 可视化结果 plt.figure() plt.scatter(rect_points[0, :], rect_points[1, :], s=3, label="原始矩形点云") plt.scatter(merged_points[0, :], merged_points[1, :], s=3, label="ICP融合点云") plt.legend() plt.axis("equal") plt.title("ICP融合结果对比") plt.show() if __name__ == "__main__": main()
最新发布
10-22
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值