Apollo中三种相机外参的可视化分析

      • 一、什么是相机外参?为什么需要可视化?
      • 二、不同外参来源对比
      • 三、详细操作步骤
        • 1. 环境准备
        • 2. 获取 `NuScenes`外参数据
        • 3. 外参到空间位置的转换及可视化
      • 四、可视化对比
        • 1. `NuScenes`数据集外参
        • 2. Apollo BEV模型外参
        • 3. Apollo园区版外参
      • 五、关键结论与应用

一、什么是相机外参?为什么需要可视化?

在自动驾驶系统中,相机外参描述了相机在车辆坐标系中的位置和朝向。它包含两个关键信息:

  1. 位置:相机相对于车辆中心(通常是激光雷达位置)的坐标 (x, y, z)
  2. 朝向:相机的旋转角度(通常用四元数表示)

可视化相机外参的重要性在于:

  • 验证标定质量:直观检查相机位置和朝向是否符合物理布局
  • 检测标定错误:发现位置偏移或方向错误等重大问题
  • 理解感知系统:帮助理解不同相机视角的覆盖范围
  • 多传感器融合:确保相机和激光雷达的空间对齐关系正确

二、不同外参来源对比

本次分析对比了三种不同来源的外参数据:

  1. NuScenes数据集外参

    • 来源:公开数据集v1.0-mini
    • 特点:标准车辆坐标系,相机布局规范
  2. Apollo BEV模型自带外参

    • 来源:camera_detection_bev模型
    • 特点:针对特定感知模型优化
  3. Apollo园区版外参

    • 来源:nuscenes_165校准数据
    • 特点:Apollo实际部署使用的参数【怀疑是非真实的】

三、详细操作步骤

1. 环境准备
nuscenes-devkit              1.1.11     # NuScenes数据集解析工具
numpy                        1.26.0
opencv-contrib-python        4.12.0.88
opencv-python                4.9.0.80
opencv-python-headless       4.9.0.80
2. 获取 NuScenes外参数据
cat > get_nuscenes_extrinsics.py <<-'EOF'
import numpy as np
from nuscenes.nuscenes import NuScenesdef get_nuscenes_extrinsics(nusc, sample_token):"""获取6个相机的变换矩阵和位置"""sample = nusc.get('sample', sample_token)camera_channels = ["CAM_FRONT", "CAM_FRONT_RIGHT", "CAM_BACK_RIGHT","CAM_BACK", "CAM_BACK_LEFT", "CAM_FRONT_LEFT"]extrinsics = {}positions = {}rotations = {}directions = {}print("相机数据 (名称, 四元数(w,x,y,z), 位置(x,y,z))")print("[")for channel in camera_channels:camera_data = nusc.get('sample_data', sample['data'][channel])calib_sensor = nusc.get('calibrated_sensor', camera_data['calibrated_sensor_token'])rotation = np.array(calib_sensor['rotation'])trans = np.array(calib_sensor['translation'])print(f"[\"{channel:16s}\",[{rotation[0]:>7.4e},{rotation[1]:>7.4e},{rotation[2]:>7.4e},{rotation[3]:>7.4e}],[{trans[0]:>7.4f},{trans[1]:>7.4e},{trans[2]:>7.4e}]],")print("]")
dataroot = './'  # 替换为你的数据集路径
nusc = NuScenes(version='v1.0-mini', dataroot=dataroot, verbose=False)
sample_token = nusc.sample[0]['token']
get_nuscenes_extrinsics(nusc, sample_token)   
EOF# 执行脚本(需提前下载数据集)
python get_nuscenes_extrinsics.py

关键步骤解释

  1. 连接NuScenes数据库获取标定数据
  2. 提取6个相机的四元数旋转参数和平移向量
  3. 格式化输出外参矩阵(位置+旋转)

输出

相机数据 (名称, 四元数(w,x,y,z), 位置(x,y,z))
[
["CAM_FRONT       ",[4.9980e-01,-5.0303e-01,4.9978e-01,-4.9737e-01],[ 1.7008,1.5946e-02,1.5110e+00]],
["CAM_FRONT_RIGHT ",[2.0603e-01,-2.0269e-01,6.8245e-01,-6.7136e-01],[ 1.5508,-4.9340e-01,1.4957e+00]],
["CAM_BACK_RIGHT  ",[1.2281e-01,-1.3240e-01,-7.0043e-01,6.9050e-01],[ 1.0149,-4.8057e-01,1.5624e+00]],
["CAM_BACK        ",[5.0379e-01,-4.9740e-01,-4.9419e-01,5.0455e-01],[ 0.0283,3.4514e-03,1.5791e+00]],
["CAM_BACK_LEFT   ",[6.9242e-01,-7.0316e-01,-1.1648e-01,1.1203e-01],[ 1.0357,4.8480e-01,1.5910e+00]],
["CAM_FRONT_LEFT  ",[6.7573e-01,-6.7363e-01,2.1214e-01,-2.1123e-01],[ 1.5239,4.9463e-01,1.5093e+00]],
]
3. 外参到空间位置的转换及可视化
cat > infer_camera_pos_by_extrinsics.py <<-'EOF'
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import FancyArrowPatch
from mpl_toolkits.mplot3d import proj3d, Axes3D
import json
from scipy.spatial.transform import Rotation as R
from pyquaternion import Quaternion
from collections import OrderedDict
import yaml# 自定义3D箭头类
class Arrow3D(FancyArrowPatch):def __init__(self, xs, ys, zs, *args, **kwargs):super().__init__((0,0), (0,0), *args, **kwargs)self._verts3d = xs, ys, zsdef do_3d_projection(self, renderer=None):xs3d, ys3d, zs3d = self._verts3dxs, ys, zs = proj3d.proj_transform(xs3d, ys3d, zs3d, self.axes.M)self.set_positions((xs[0], ys[0]), (xs[1], ys[1]))return min(zs)# 四元数转旋转矩阵函数
def quaternion_to_rotation_matrix(translation, rotation):"""1.输入是从相机坐标系到车辆坐标系将四元数转换为3x3旋转矩阵,并调整平移部分"""q = Quaternion(rotation)  # 注意参数顺序:w,x,y,zR_w2c = q.rotation_matrix  # 世界坐标系到相机坐标系的旋转# 计算相机中心在世界坐标系中的位置: C = -R^T * TT = np.array(translation)C = -R_w2c.T @ T# 构建从相机坐标系到世界坐标系的变换矩阵transformation_matrix = np.eye(4)transformation_matrix[:3, :3] = R_w2c   # 旋转部分transformation_matrix[:3, 3] = C        # 平移部分: 相机中心在世界坐标系中的位置return transformation_matrix# 四元数转旋转矩阵函数
def quaternion_to_rotation_matrix_apollo(translation, rotation):"""将四元数转换为3x3旋转矩阵,并调整平移部分"""q = Quaternion(rotation)  # 注意参数顺序:w,x,y,zR_w2c = q.rotation_matrix  # 世界坐标系到相机坐标系的旋转# 计算相机中心在世界坐标系中的位置: C = -R^T * TT = np.array(translation)C = -R_w2c.T @ T# 构建从相机坐标系到世界坐标系的变换矩阵transformation_matrix = np.eye(4)transformation_matrix[:3, :3] = R_w2c   # 旋转部分transformation_matrix[:3, 3] = C        # 平移部分: 相机中心在世界坐标系中的位置return transformation_matrixcam_names = ["CAM_FRONT","CAM_FRONT_RIGHT","CAM_FRONT_LEFT","CAM_BACK","CAM_BACK_LEFT","CAM_BACK_RIGHT"]def gen_bev_kdata_from_nuscenes_extrinsics(extrinsics_data):'''通过nuscenes_extrinsics外参生成bev需要的外参矩阵(6,4,4)'''cameras = {}    for val in json.loads(extrinsics_data):name,rotation,translation=valname=name.strip()cameras[name]={"translation":translation,"rotation":rotation}with open("nuscenes_extrinsics.txt","w") as f:f.write("[\n")for name in cam_names:cam =cameras[name]            extrinsic = quaternion_to_rotation_matrix(cam["translation"],cam["rotation"])for line in extrinsic:print(line)f.write(",".join([f"{x:.8e}" for x in line])+",\n")f.write("]\n")def gen_bev_kdata_from_apollo_nuscenes_165():'''通过apollo的nuscenes_165外参生成bev需要的外参矩阵'''print("相机数据 (名称, 四元数(w,x,y,z), 位置(x,y,z))")with open("apollo_nuscenes_165.txt","w") as f:f.write("[\n")for name in cam_names:path=f"camera_params/{name}_extrinsics.yaml"with open(path, 'r',encoding="utf-8") as fi:config = yaml.safe_load(fi)extrinsic=config['transform']translation=extrinsic['translation']rotation=extrinsic['rotation']            rotation=[rotation['w'], rotation['x'], rotation['y'], rotation['z']]trans=[translation['x'], translation['y'], translation['z']]print(f"[\"{name:16s}\",[{rotation[0]:>7.4e},{rotation[1]:>7.4e},{rotation[2]:>7.4e},{rotation[3]:>7.4e}],[{trans[0]:>7.4f},{trans[1]:>7.4e},{trans[2]:>7.4e}]],")extrinsic = quaternion_to_rotation_matrix(trans,rotation)for line in extrinsic:f.write(",".join([f"{x:.8e}" for x in line])+",\n")f.write("]\n")def main(ext_params,name):ext_params = ext_params.reshape(6, 4, 4)# 创建3D图形fig = plt.figure(figsize=(14, 10))ax = fig.add_subplot(111, projection='3d')ax.set_title(f'Camera Positions Relative to LiDAR({name})', fontsize=16)# 绘制LiDAR原点ax.scatter([0], [0], [0], c='red', s=100, label='LiDAR Origin')# 相机颜色映射colors = {"CAM_FRONT": "blue","CAM_FRONT_RIGHT": "green","CAM_FRONT_LEFT": "cyan","CAM_BACK": "red","CAM_BACK_LEFT": "magenta","CAM_BACK_RIGHT": "yellow"}# 处理每个相机for i, matrix in enumerate(ext_params):# 提取数据name = cam_names[i]R = matrix[:3, :3]   # 旋转矩阵pos = matrix[:3, 3]  # 平移向量cam_pos=poscam_pos= - R @ cam_pos# 计算相机朝向向量 (Z轴方向)direction = R @ np.array([0, 0, 1])# 绘制相机位置ax.scatter(cam_pos[0], cam_pos[1], cam_pos[2], c=colors[name], s=80, label=name)# 绘制相机朝向箭头arrow = Arrow3D([cam_pos[0], cam_pos[0] + direction[0]*0.4],[cam_pos[1], cam_pos[1] + direction[1]*0.4],[cam_pos[2], cam_pos[2] + direction[2]*0.4],mutation_scale=15, arrowstyle="-|>", color=colors[name], linewidth=2)ax.add_artist(arrow)# 添加文本标签ax.text(cam_pos[0], cam_pos[1], cam_pos[2] + 0.1, name, fontsize=6)# 设置坐标轴ax.set_xlabel('X Axis (Front-Back)', fontsize=12)ax.set_ylabel('Y Axis (Left-Right)', fontsize=12)ax.set_zlabel('Z Axis (Height)', fontsize=12)# 设置等比例坐标轴max_range = 2 #np.array([max(abs(p) for cam in cameras for p in cam["translation"])]).max() * 1.5ax.set_xlim(-max_range, max_range)ax.set_ylim(-max_range, max_range)ax.set_zlim(-max_range, max_range)# 添加图例和网格ax.legend(loc='upper right', fontsize=10)ax.grid(True)# 调整视角以便观察ax.view_init(elev=25, azim=-45)plt.tight_layout()plt.show()# apollo bev自带的k_data modules/perception/camera_detection_bev/detector/petr/bev_obstacle_detector.h
apollo_bev_kdata = np.array([-1.40307297e-03, 9.07780395e-06,  4.84838307e-01,  -5.43047376e-02,-1.40780103e-04, 1.25770375e-05,  1.04126692e+00,  7.67668605e-01,-1.02884378e-05, -1.41007011e-03, 1.02823459e-01,  -3.07415128e-01,0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  1.00000000e+00,-9.39000631e-04, -7.65239349e-07, 1.14073277e+00,  4.46270645e-01,1.04998052e-03,  1.91798881e-05,  2.06218868e-01,  7.42717385e-01,1.48074005e-05,  -1.40855671e-03, 7.45946690e-02,  -3.16081315e-01,0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  1.00000000e+00,-7.0699735e-04,  4.2389297e-07,   -5.5183989e-01,  -5.3276348e-01,-1.2281288e-03,  2.5626015e-05,   1.0212017e+00,   6.1102939e-01,-2.2421273e-05,  -1.4170362e-03,  9.3639769e-02,   -3.0863306e-01,0.0000000e+00,   0.0000000e+00,   0.0000000e+00,   1.0000000e+00,2.2227580e-03,   2.5312484e-06,   -9.7261822e-01,  9.0684637e-02,1.9360810e-04,   2.1347081e-05,   -1.0779887e+00,  -7.9227984e-01,4.3742721e-06,   -2.2310747e-03,  1.0842450e-01,   -2.9406491e-01,0.0000000e+00,   0.0000000e+00,   0.0000000e+00,   1.0000000e+00,5.97175560e-04,  -5.88774265e-06, -1.15893924e+00, -4.49921310e-01,-1.28312141e-03, 3.58297058e-07,  1.48300052e-01,  1.14334166e-01,-2.80917516e-06, -1.41527120e-03, 8.37693438e-02,  -2.36765608e-01,0.00000000e+00,  0.00000000e+00,  0.00000000e+00,  1.00000000e+00,3.6048229e-04,   3.8333174e-06,   7.9871160e-01,   4.3321830e-01,1.3671946e-03,   6.7484652e-06,   -8.4722507e-01,  1.9411178e-01,7.5027779e-06,   -1.4139183e-03,  8.2083985e-02,   -2.4505949e-01,0.0000000e+00,   0.0000000e+00,   0.0000000e+00,   1.0000000e+00
])nuscenes_extrinsics_data = """
[
["CAM_FRONT       ",[4.9980e-01,-5.0303e-01,4.9978e-01,-4.9737e-01],[ 1.7008,1.5946e-02,1.5110e+00]],
["CAM_FRONT_RIGHT ",[2.0603e-01,-2.0269e-01,6.8245e-01,-6.7136e-01],[ 1.5508,-4.9340e-01,1.4957e+00]],
["CAM_BACK_RIGHT  ",[1.2281e-01,-1.3240e-01,-7.0043e-01,6.9050e-01],[ 1.0149,-4.8057e-01,1.5624e+00]],
["CAM_BACK        ",[5.0379e-01,-4.9740e-01,-4.9419e-01,5.0455e-01],[ 0.0283,3.4514e-03,1.5791e+00]],
["CAM_BACK_LEFT   ",[6.9242e-01,-7.0316e-01,-1.1648e-01,1.1203e-01],[ 1.0357,4.8480e-01,1.5910e+00]],
["CAM_FRONT_LEFT  ",[6.7573e-01,-6.7363e-01,2.1214e-01,-2.1123e-01],[ 1.5239,4.9463e-01,1.5093e+00]]
]
"""
gen_bev_kdata_from_nuscenes_extrinsics(nuscenes_extrinsics_data)
with open("nuscenes_extrinsics.txt","r") as f:nuscenes_bev_kdata=np.array(eval(f.read()))    gen_bev_kdata_from_apollo_nuscenes_165()
with open("apollo_nuscenes_165.txt","r") as f:apollo_nuscenes_kdata=np.array(eval(f.read())) main(apollo_bev_kdata,"apollo_bev_kdata")
main(nuscenes_bev_kdata,"nuscenes_bev_kdata")  
main(apollo_nuscenes_kdata,"apollo_nuscenes_kdata")
EOF
\cp /opt/apollo/neo/share/modules/calibration/data/nuscenes_165/camera_params ./ -rf
python infer_camera_pos_by_extrinsics.py

数学原理

  • 四元数 → 旋转矩阵:使用pyquaternion库转换
  • 相机位置计算:Cworld=−RT⋅TC_{world} = -R^T \cdot TCworld=RTT
  • 最终得到4x4变换矩阵(包含旋转和平移)

可视化要素

  • 坐标系:X(前/后), Y(左/右), Z(高/低)
  • 激光雷达:原点红色标记
  • 相机位置:不同颜色表示不同视角
  • 相机朝向:3D箭头指示拍摄方向

四、可视化对比

参考图片
请添加图片描述

1. NuScenes数据集外参
  • 特点
    • 车辆朝向:标准前向(Y轴正方向)
    • 相机布局:六相机均匀分布
    • 位置对称性:左右相机位置精确对称

请添加图片描述

2. Apollo BEV模型外参
  • 特点
    • 车辆朝向:非标准方向(约15度偏转)
    • 相机视角:六相机均匀分布

请添加图片描述

3. Apollo园区版外参
  • 特点
    • 位置正确:相机位置符合车辆布局
    • 车辆朝向:朝向X轴,不合理,应该是Y轴
    • 朝向错误:所有相机均朝向前方(应为各方向)
    • 问题原因:可能是标定时未设置正确方向
    • 实际影响:导致侧面和后方视角失效

请添加图片描述

相机数据 (名称, 四元数(w,x,y,z), 位置(x,y,z))
["CAM_FRONT       ",[7.0511e-01,-1.7317e-03,-7.0910e-01,2.2896e-03],[-0.0159,1.7008e+00,1.5110e+00]],
["CAM_FRONT_RIGHT ",[6.1737e-01,3.3363e-01,-6.2890e-01,-3.3472e-01],[ 0.4934,1.5508e+00,1.4957e+00]],
["CAM_FRONT_LEFT  ",[6.2786e-01,-3.2765e-01,-6.2564e-01,3.2712e-01],[-0.4946,1.5239e+00,1.5093e+00]],
["CAM_BACK        ",[2.2658e-03,-7.0116e-01,5.7708e-04,7.1300e-01],[-0.0035,2.8326e-02,1.5791e+00]],
["CAM_BACK_LEFT   ",[4.0822e-01,-5.7804e-01,-4.1698e-01,5.7040e-01],[-0.4848,1.0357e+00,1.5910e+00]],
["CAM_BACK_RIGHT  ",[3.9507e-01,5.8460e-01,-4.0790e-01,-5.7947e-01],[ 0.4806,1.0149e+00,1.5624e+00]],

五、关键结论与应用

  1. 标定质量验证

    • 理想情况:相机位置对称分布,高度一致(如NuScenes数据)
    • 危险信号:位置不对称、高度不一致、朝向错误
  2. 错误检测

    • Apollo园区版外参存在严重朝向错误
    • 通过可视化可快速发现此类基础错误

通过这种可视化方法,即使非专业人员也能直观理解相机空间关系,快速发现标定中的重大错误,显著提高自动驾驶系统的可靠性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/diannao/94519.shtml
繁体地址,请注明出处:http://hk.pswp.cn/diannao/94519.shtml
英文地址,请注明出处:http://en.pswp.cn/diannao/94519.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

虚拟化KVM常用命令汇总

KVM&#xff08;Kernel-based Virtual Machine&#xff09;是一种开源的硬件虚拟化解决方案&#xff0c;它是 Linux 内核的一部分&#xff0c;允许在支持虚拟化技术的硬件&#xff08;如 Intel VT-x 或 AMD-V&#xff09;上运行虚拟机。KVM 将 Linux 内核转变为一个裸机虚拟机监…

6s081环境配置以及使用vscode连接本地wsl2

6s081环境配置以及使用vscode连接wsl2 本人环境&#xff1a;windows11、wsl2ubuntu20.04 课程&#xff1a;6s081的2020版本的:https://pdos.csail.mit.edu/6.S081/2020/schedule.html 一、wsl2ubuntu20.04配置6s081环境 注&#xff1a;关于如何在window中安装wsl&#xff0c;这…

C++实现线程池(3)缓存线程池

三. CachedThreadPool 的实现3.1 需求:动态调整线程数量&#xff1a;与 FixedThreadPool 不同&#xff0c;CachedThreadPool 的线程数量是动态调整的。当有新任务提交时&#xff0c;如果线程池中有空闲的线程&#xff0c;则会立即使用空闲线程执行任务&#xff1b;如果线程池中…

WMS+自动化立库:无人仓的现在进行时

传统仓库正面临严峻挑战&#xff1a;效率瓶颈日益凸显&#xff0c;人力成本持续攀升&#xff0c;空间利用率逼近极限&#xff0c;而订单响应速度却难以满足市场需求。如何破局&#xff1f;WMS&#xff08;仓库管理系统&#xff09;与自动化立体库&#xff08;AS/RS&#xff09;…

多模态大模型研究每日简报【2025-08-05】

训练数据相关 EditGarment: An Instruction-Based Garment Editing Dataset Constructed with Automated MLLM Synthesis and Semantic-Aware Evaluation (https://arxiv.org/abs/2508.03497)&#xff1a;提出了一种自动化的流程&#xff0c;用于构建服装编辑数据集EditGarmen…

4、docker数据卷管理命令 | docker volume

1、命令总览命令作用出现频率备注★ docker volume create新建卷高-d 指定驱动&#xff0c;-o 指定驱动选项★ docker volume ls列出卷高--filter danglingtrue 查孤儿卷★ docker volume inspect查看卷详情高输出 JSON&#xff0c;可加 --format★ docker volume rm删除卷高只…

计数组合学7.14(对偶 RSK 算法)

7.14 对偶 RSK 算法 存在 RSK 算法的一种变体&#xff0c;其与乘积 ∏i,j(1xiyj)\prod_{i,j}(1 x_{i}y_{j})∏i,j​(1xi​yj​) 的关系类似于 RSK 算法本身与 ∏i,j(1−xiyj)−1\prod_{i,j}(1 - x_{i}y_{j})^{-1}∏i,j​(1−xi​yj​)−1 的关系。我们称此变体为对偶 RSK 算法…

C语言中的进程、线程与进程间通信详解

目录 引言 基本概念 1. 进程&#xff08;Process&#xff09; 2. 线程&#xff08;Thread&#xff09; 线程编程实战 1. 常见线程库 2. 合理设置线程数 3. pthread 创建线程 线程同步机制 1. 互斥锁 pthread_mutex_t 2. 条件变量 pthread_cond_t 3. 读写锁 pthread…

[假面骑士] 555浅谈

假面骑士555(faiz)是我最先接触的一部平成系列的假面骑士&#xff0c;同时也是我个人最喜欢的一部假面骑士。一、大纲简介震惊&#xff0c;人类最新的进化形态——奥菲一诺&#xff0c;横空出世&#xff01;日本的顶级财团&#xff0c;Smart Brain&#xff0c;的前任社长&#…

Vue Router 路由的创建和基本使用(超详细)

一、路由的基本概念 你是否好奇单页应用&#xff08;SPA&#xff09;是如何在不刷新页面的情况下实现页面切换的&#xff1f;这就离不开路由的功劳。 路由&#xff1a;本质是一组 key-value 的对应关系&#xff0c;在前端领域中&#xff0c;key 通常是路径&#xff0c;value …

深入理解设计模式:策略模式的艺术与实践

在软件开发中&#xff0c;我们经常会遇到需要根据不同情况选择不同算法或行为的场景。传统的做法可能是使用大量的条件语句&#xff08;if-else或switch-case&#xff09;&#xff0c;但随着需求的增加和变化&#xff0c;这种硬编码的方式会导致代码难以维护和扩展。策略模式&a…

概率/期望 DP llya and Escalator

题目链接&#xff1a;Problem - D - Codeforces 看了这篇文章来的&#xff1a;【算法学习笔记】概率与期望DP - RioTian - 博客园 这篇博客写得挺好的&#xff0c;讲了一些常见方法&#xff0c;概率 / 期望的题多练练就上手了。 题目大意&#xff1a; n 个人排队上电梯&…

大陆电子MBDS开发平台转到其他国产控制器平台产生的问题记录

u8_StComLowSpdGearSwt变量为例&#xff0c;之前用的时候只有输入&#xff0c;没什么实际意义&#xff0c;导致新环境下编译报错&#xff0c;缺少声明&#xff0c;解决办法&#xff1a;注释掉输入模块。今天解决的另一个比较大的问题&#xff0c;不同模型函数公用函数模块生成代…

机器学习模型调优实战指南

文章目录模型选择与调优&#xff1a;从理论到实战1. 引言2. 模型评估&#xff1a;为选择提供依据2.1 偏差-方差权衡2.2 数据集划分与分层抽样2.3 交叉验证&#xff08;Cross-Validation&#xff09;2.4 信息准则&#xff08;AIC / BIC&#xff09;3. 超参数调优&#xff1a;让模…

【教程】Unity CI/CD流程

测试机&#xff1a;红帽 Linux8 源码仓库&#xff1a;Gitee - MrRiver/Unity Example   系统环境准备 1&#xff09;yum 源 sudo curl -o /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-8.repo sudo sed -i s/\$releasever/8/g /etc/yum.repos…

文献阅读 | Briefings in Bioinformatics | Hiplot:全面且易于使用的生物医学可视化分析平台

文献介绍文献题目&#xff1a; Hiplot&#xff1a;一个综合且易于使用的 Web 服务&#xff0c;用于增强出版物准备的生物医学数据可视化 研究团队&#xff1a; Openbiox/Hiplot 社区 发表时间&#xff1a; 2022-07-05 发表期刊&#xff1a; Briefings in Bioinformatics 影响因…

【数字图像处理系列笔记】Ch04:灰度变换与空间域图像增强(2)

目录 一、空域滤波基础 一、空域滤波的基本概念 二、空域滤波的数学原理 三、空域滤波器的分类与典型示例 &#xff08;一&#xff09;线性滤波器&#xff08;Linear Filter&#xff09; &#xff08;二&#xff09;非线性滤波器&#xff08;Non-linear Filter&#xff0…

AI浪潮下,FPGA如何实现自我重塑与行业变革

引言&#xff1a;AI 与 FPGA&#xff0c;新时代的碰撞 2025 年&#xff0c;人工智能技术迎来爆发式增长&#xff0c;大模型、生成式 AI 和多模态技术持续突破&#xff0c;人形机器人量产元年正式开启&#xff0c;自动驾驶商业化进程加速&#xff0c;工业数字化转型全面铺开(1)…

系统集成项目管理工程师【第十一章 规划过程组】定义范围、创建WBS、规划进度管理和定义活动篇

系统集成项目管理工程师【第十一章 规划过程组】定义范围、创建WBS、规划进度管理和定义活动篇 一、定义范围&#xff1a;给项目画好"边界线" 定义范围是明确项目和产品"做什么、不做什么"的过程&#xff0c;直接影响后续所有工作的方向。 1. 核心概念与作…

Spring Boot 参数校验全指南

Spring Boot 参数校验全指南 在 Web 开发中&#xff0c;参数校验是保障接口安全性和数据合法性的关键环节。手动编写校验逻辑不仅繁琐&#xff0c;还容易遗漏边界情况。Spring Boot 整合了 validation 工具&#xff0c;提供了一套简洁高效的参数校验方案&#xff0c;可快速实现…