基于孪生网络的6DOF相机重定位:相对几何感知方法解析
1. 从相机丢在哪了说起6DOF重定位到底在解决什么问题如果你玩过AR应用或者接触过机器人自主导航、无人机室内飞行这类场景大概率遇到过一个很基础但极其棘手的问题设备开机之后不知道自己在哪里也不知道自己朝向哪个方向。摄像头拍到的画面是有的但画面和地图之间的对应关系断了。这时候就需要视觉重定位出场了。6DOF Camera Relocalization翻译过来就是六自由度相机重定位。六个自由度分别是三个平移x、y、z和三个旋转俯仰、偏航、翻滚。说白了就是给你一张当前拍摄的图像让你算出相机在世界坐标系里的精确位置和姿态。这件事的难度在于它不是简单的图像分类或者目标检测而是一个连续的回归问题而且对精度要求极高——平移误差超过几厘米AR物体就会飘旋转误差超过一两度虚拟物体就会歪。传统方案走的是特征点匹配加几何求解的路线。ORB-SLAM那一套东西在纹理丰富的场景下确实能跑但一旦遇到弱纹理、重复纹理、光照剧烈变化特征点就抓瞎了。后来深度学习进来之后大家开始尝试用神经网络直接回归位姿或者用场景坐标回归的方式间接求解。2019年前后这个方向涌现了不少有意思的工作其中一篇比较有代表性的就是Relative Geometry-Aware Siamese Neural Network for 6DOF Camera Relocalization。这篇论文的核心思路我读下来的感受是它没有去硬怼绝对位姿回归而是换了一个角度——让网络去学习两张图像之间的相对几何关系。这个思路的巧妙之处在于相对关系比绝对坐标更容易学习也更鲁棒。你想想让你直接说出自己在城市里的经纬度很难但让你判断两张照片拍摄位置之间的相对变化直觉上就简单一些。这篇文章适合谁看如果你正在做AR/VR、机器人定位、自动驾驶高精地图匹配或者单纯对视觉SLAM和深度学习结合感兴趣这篇论文的思路值得仔细拆解。我会从问题背景、网络设计、训练策略、实验细节到实际复现时可能踩的坑尽量讲透。2. 为什么绝对回归走不通相对几何感知的动机拆解2.1 绝对位姿回归的三大硬伤在Siamese网络被引入之前主流做法是训练一个CNN输入单张图像直接输出7维向量3维平移4维旋转四元数。听起来很直接但实际训练起来问题很多。第一个问题是尺度模糊。同一张图像在不同场景尺度下对应的绝对坐标差异巨大。网络要记住整个场景的绝对坐标分布参数量需求极大而且泛化能力很差。换一个场景模型基本要从头训练。第二个问题是旋转表示的连续性。四元数虽然比欧拉角好一些但仍然存在双覆盖问题网络在回归时容易出现不连续跳变。你可能会看到loss突然飙升然后模型就崩了。第三个问题是数据效率低。绝对坐标回归需要大量带精确位姿标注的数据而采集这些数据本身就很贵。室内场景还好可以用动捕系统室外大场景就非常麻烦。2.2 相对几何关系的直觉优势这篇论文的出发点很朴素与其让网络记住我在哪里不如让它学会我从A到B怎么动。举个例子。假设你蒙着眼睛被人带到一个房间里让你直接说出房间的经纬度你肯定说不出来。但如果给你看两张照片告诉你这是房间里两个位置拍的让你判断拍摄者移动了多远、转了多少度你大概率能估个八九不离十。这就是相对几何关系的优势——它不依赖于对全局坐标系的记忆而是依赖于对图像内容变化的感知。从数学上看相对位姿可以表示为T_rel T_abs2 * inv(T_abs1)其中T_abs1和T_abs2分别是两张图像的绝对位姿。网络学习的是T_rel而不是T_abs。这样一来网络不需要记住整个场景的绝对坐标分布只需要学会从图像对中提取相对运动信息。这个任务的泛化能力天然更强因为从A到B怎么动这个关系在不同场景之间是有共性的。2.3 Siamese结构为什么适合这个任务Siamese网络中文叫孪生网络最早用在签名验证和人脸比对里。它的核心特点是双分支共享权重。两个输入分别经过同一个网络提取特征然后在高维空间里比较这两个特征。放到重定位任务里这个结构天然适合处理图像对。两张图像分别过网络得到各自的特征表示然后在特征层面做交互回归出相对位姿。共享权重的好处是参数量减半而且强制网络学习一种对称的特征表示——不管图像是A还是B提取特征的逻辑是一样的。这里有个容易忽略的细节Siamese结构并不意味着两个分支完全独立。真正关键的是特征融合模块的设计。如果只是简单拼接两个特征向量网络很难学到精细的几何关系。这篇论文在融合模块上做了不少文章后面会详细拆解。3. 网络架构逐层拆解从双分支特征提取到几何感知回归3.1 骨干网络的选择与权衡论文采用的骨干网络是ResNet-34的变体。为什么选ResNet-34而不是更深的ResNet-50或者更轻的MobileNet我分析下来有几个考虑。ResNet-50参数量太大在相对位姿回归这种需要精细特征的任务上容易过拟合而且训练成本高。MobileNet虽然轻但深度可分离卷积对几何细节的捕捉能力偏弱位姿精度会打折扣。ResNet-34处在一个比较平衡的位置有足够的深度提取多尺度特征参数量又在可控范围内。具体实现上论文去掉了原始ResNet最后的全连接层和平均池化层保留了卷积部分作为特征提取器。输入图像分辨率统一缩放到256×256这个分辨率不算高但考虑到要处理图像对显存占用会翻倍所以是一个合理的折中。3.2 双分支权重共享的具体实现Siamese结构的实现方式有两种一种是真正的物理共享即两个分支用同一个网络实例前向传播时分两次调用另一种是逻辑共享即定义两个网络实例但强制参数相同。论文采用的是第一种方式也就是物理共享。这样做的好处是显存占用更小因为只需要存储一份权重。但要注意在PyTorch里如果直接用同一个module处理两个输入反向传播时梯度会自动累加这是正确的行为。class SiameseBackbone(nn.Module): def __init__(self): super().__init__() self.backbone resnet34_variant(pretrainedTrue) def forward(self, img_a, img_b): feat_a self.backbone(img_a) feat_b self.backbone(img_b) return feat_a, feat_b这段代码看起来简单但有一个坑如果batch size设得太大两个分支的特征图会占用大量显存。实测下来256×256输入、batch size 16的情况下单卡显存占用大约在8-10GB。如果显存不够可以考虑梯度累积或者混合精度训练。3.3 相对几何感知模块的设计逻辑这是整篇论文最核心的部分。两个分支提取出特征之后怎么融合才能让网络学到相对几何关系最简单的做法是直接拼接concatenation但这样网络很难学到精细的空间对应关系。论文设计了一个相对几何感知模块我理解它的核心思想是在特征层面显式地计算两个特征图之间的相关性然后用这个相关性来指导位姿回归。具体来说模块包含以下几个步骤特征对齐将两个分支的特征图在通道维度上保持一致然后计算逐像素的差值特征和乘积特征。相关性计算用一个轻量的卷积层计算两个特征图之间的空间相关性矩阵。几何编码将相关性矩阵和原始特征拼接送入几个残差块进行几何关系编码。回归头最后通过全连接层输出7维相对位姿向量。这个设计的关键在于它没有把两个图像的特征当作独立的向量来处理而是在空间维度上建立了对应关系。这就像你在做立体匹配时不是简单比较两个patch的相似度而是要考虑视差和几何约束。3.4 损失函数的选择与权重调优论文使用的损失函数是平移和旋转分开计算的。平移部分用L2损失旋转部分用四元数的角度损失。具体公式如下L_trans ||t_pred - t_gt||_2 L_rot arccos(|q_pred · q_gt|) L_total L_trans lambda * L_rot这里的lambda是一个超参数用来平衡平移和旋转的权重。论文里设的是10但我实际复现时发现这个值需要根据场景尺度来调整。如果场景尺度大比如室外平移误差的绝对值会很大这时候lambda可以适当调小如果场景尺度小比如桌面级ARlambda可以调大。还有一个细节旋转损失用的是四元数点积的绝对值这样可以避免四元数双覆盖带来的符号问题。这个技巧在实现时很容易漏掉导致训练不稳定。4. 训练策略与数据准备那些论文里没写清楚的实操细节4.1 数据集的选择与预处理论文在多个数据集上做了实验包括室内的小场景和室外的大场景。室内场景用的是7-Scenes数据集室外用的是Cambridge Landmarks数据集。这两个数据集在重定位领域算是标配了。7-Scenes包含7个室内场景每个场景有几千张图像位姿由Kinect Fusion重建得到。Cambridge Landmarks包含5个室外场景位姿由SfM重建得到。两者的共同问题是位姿标注存在噪声尤其是室外场景SfM重建的位姿在尺度上可能有漂移。预处理阶段有几个关键操作图像去畸变如果原始图像有畸变必须先校正否则网络学到的几何关系是错的。分辨率统一所有图像缩放到256×256但要注意保持宽高比避免拉伸变形。数据增强随机裁剪、颜色抖动、亮度对比度调整。但要注意几何相关的增强如随机旋转、透视变换要慎用因为它们会改变相对位姿的真值。4.2 图像对的采样策略这是训练中最容易被忽视但影响很大的环节。如果随机采样图像对可能会出现两种情况要么两张图像离得太近相对位姿接近零网络学不到东西要么离得太远重叠区域太少网络无法建立对应关系。论文采用的策略是在时间序列上采样间隔在一定范围内的图像对。具体来说对于每个场景按照拍摄顺序排列图像然后采样间隔在5到50帧之间的图像对。这样既能保证有一定的相对运动又能保证足够的重叠区域。我实际复现时发现这个间隔范围需要根据拍摄帧率来调整。如果帧率是30fps5到50帧对应的是0.17秒到1.67秒的运动对于手持设备来说这个范围是合理的。但如果帧率是10fps同样的帧数间隔对应的运动就太大了。4.3 学习率调度与优化器配置论文用的是Adam优化器初始学习率1e-4每30个epoch衰减为原来的0.1倍。Batch size设为16训练大约200个epoch。这里有一个实操经验Adam的默认betas参数0.9, 0.999在相对位姿回归任务上表现不错但epsilon建议从1e-8调到1e-6。原因是位姿回归的梯度尺度变化很大默认的epsilon在某些batch上会导致更新步长过小训练停滞。另外学习率预热warmup很重要。前5个epoch用线性预热从1e-6逐渐升到1e-4可以避免初期梯度爆炸。4.4 训练中的常见崩溃与恢复我在复现时遇到过几次训练崩溃loss突然变成NaN。排查下来主要有两个原因一是旋转四元数没有归一化。网络输出的四元数如果不做归一化点积计算会出现数值问题。解决方案是在回归头之后加一个L2归一化层。二是梯度裁剪没做。相对位姿回归的梯度在某些样本上会非常大尤其是当图像对之间的运动超出训练分布时。建议设置梯度裁剪阈值为1.0超过就截断。torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm1.0)这两条经验在论文里都没写但实际训练时几乎是必踩的坑。5. 实验结果的解读与复现时的偏差分析5.1 论文报告的精度指标论文在7-Scenes数据集上报告的平均平移误差大约在5-8厘米旋转误差在2-3度。在Cambridge Landmarks上平移误差在0.5-1.5米旋转误差在2-5度。这个精度在2019年算是比较有竞争力的但和后来的一些方法比如基于场景坐标回归的相比还有提升空间。需要注意的是论文报告的指标是中位数误差而不是平均值。中位数对异常值不敏感更能反映模型的典型表现。如果你复现时算的是平均值可能会发现数字比论文差不少这是正常的。5.2 复现时的精度差距来源我复现下来的精度比论文低大约10%-20%分析下来有几个原因数据预处理差异论文可能用了更精细的位姿优化而我只用了原始标注。训练轮数不足论文训练了200个epoch我只跑了100个就停了。图像对采样策略论文的采样间隔可能经过了精细调优而我用的是经验值。还有一个容易被忽略的点测试时的位姿精化。论文可能在测试时用了迭代精化或者RANSAC后处理而我只做了单次前向传播。如果你要对比一定要确认测试流程是否一致。5.3 不同场景下的表现差异从论文的实验结果来看室内场景的精度明显好于室外场景。这很好理解室内场景纹理丰富、光照稳定、尺度小室外场景纹理重复、光照变化大、尺度大。在室内场景中纹理较弱的白墙区域误差明显偏大。这说明网络仍然依赖纹理信息来建立对应关系。如果场景中有大面积无纹理区域相对几何感知模块的优势会被削弱。一个实用的建议如果你的应用场景中有大量弱纹理区域可以考虑在训练时加入合成纹理或者使用深度信息辅助。单纯靠RGB图像很难在这些区域做到高精度。6. 从论文到落地实际部署时的工程化考量6.1 推理速度与模型压缩论文的模型在单张GPU上推理一对图像大约需要20-30毫秒这个速度对于AR应用来说勉强够用但还有优化空间。如果要在移动端部署需要做模型压缩。我试过几种方案通道剪枝把ResNet-34的通道数减少30%精度下降约5%速度提升约40%。知识蒸馏用大模型教小模型精度可以恢复到接近原始水平。量化INT8量化后模型大小减少75%速度提升约2倍但精度下降约10%。综合来看知识蒸馏加量化的组合比较平衡适合移动端部署。6.2 与SLAM系统的集成方式视觉重定位很少单独使用通常是作为SLAM系统的重定位模块。集成方式有两种一种是松耦合重定位模块独立运行输出位姿后直接覆盖SLAM的当前位姿。这种方式实现简单但重定位失败时会导致系统跳变。另一种是紧耦合重定位结果作为观测值融入SLAM的优化框架。这种方式更鲁棒但实现复杂。我的经验是如果重定位精度足够高平移误差小于5厘米松耦合就够了。如果精度不够紧耦合可以平滑掉一些误差但会增加系统复杂度。6.3 长期运行的漂移与重定位触发策略在实际部署中重定位不是每帧都需要的。如果每帧都做重定位计算量太大如果一直不做漂移会累积。合理的策略是当SLAM的跟踪置信度低于阈值时触发重定位。置信度可以用特征点匹配数量、重投影误差等指标来衡量。触发后用重定位结果校正SLAM的位姿然后继续跟踪。这个策略的关键是阈值设定。阈值太高重定位频繁触发计算量大阈值太低漂移累积到无法校正。建议根据实际场景做几次实验找到平衡点。7. 这篇论文的思路在今天还值得借鉴吗7.1 相对几何感知的延续与演变这篇论文发表于2019年当时相对位姿回归还是一个比较新颖的思路。后来这个方向演变出了很多变体比如基于Transformer的跨图像注意力机制、基于对比学习的特征匹配等。但核心思想——让网络学习图像之间的相对关系而不是绝对坐标——一直被沿用。今天的很多视觉重定位方案本质上还是在做相对几何关系的建模只是网络结构更复杂、特征表达能力更强了。所以理解这篇论文的思路对于理解后续工作很有帮助。7.2 适合借鉴的场景与不适合的场景如果你的应用场景满足以下条件这篇论文的思路值得借鉴场景尺度不大室内或桌面级有足够的图像对训练数据对实时性要求不是极端苛刻但如果你的场景是室外大尺度、光照变化剧烈、纹理重复严重单纯靠相对几何感知可能不够需要结合其他传感器或者更鲁棒的特征表示。7.3 我个人的复现体会最后分享几点个人体会。第一数据质量比模型结构更重要。我花在数据清洗和位姿优化上的时间远比调网络结构多。第二训练稳定性需要仔细调。梯度裁剪、四元数归一化、学习率预热这三件事一个都不能少。第三不要迷信论文指标。论文的指标是在特定条件下得到的实际场景中的表现可能会有很大差距。多做几组消融实验找到适合自己场景的配置比直接抄论文参数靠谱得多。这篇论文的代码没有官方开源但社区里有几个复现版本质量参差不齐。如果你要复现建议先从简单的骨干网络开始跑通流程后再逐步加入相对几何感知模块。一上来就怼完整模型很容易在调试上耗掉大量时间。

相关新闻

Simulink模型转PLC:PLC Coder生成SCL导入博图全攻略

Simulink模型转PLC:PLC Coder生成SCL导入博图全攻略

做控制的兄弟对这套流程应该不陌生:Simulink 里模型跑得飞起,曲线调得漂漂亮亮,到了要上 PLC 的那一步,就成了在博图(TIA Portal)里对着 SCL 硬啃。我见过同事手动翻译一套状态机算法,翻了两周&…

2026/10/14 12:31:38 阅读更多 →
ALBERT命名实体识别实战:从模型选型到部署优化

ALBERT命名实体识别实战:从模型选型到部署优化

1. 为什么命名实体识别值得单独拿出来讲命名实体识别(Named Entity Recognition,简称 NER)算是 NLP 里最"接地气"的任务之一。你平时用到的信息抽取、知识图谱构建、智能客服工单分类、简历解析、合同关键条款提取,底层…

2026/10/14 12:31:38 阅读更多 →
langgraph4j执行图原理:超级步调度、状态快照与条件路由实践

langgraph4j执行图原理:超级步调度、状态快照与条件路由实践

langgraph4j的执行图(ExecutionGraph)是整个Agent框架真正让图"动起来"的核心发动机。前两篇我们聊了StateGraph怎么把节点和边组织成一幅静态蓝图,也拆了状态通道和快照机制,这次我把编译后生成的那张执行图彻底翻一遍…

2026/10/14 12:31:38 阅读更多 →

最新新闻

Spring Boot 3.4 升级指南:结构化日志、RestClient 与可观测性实战

Spring Boot 3.4 升级指南:结构化日志、RestClient 与可观测性实战

前段时间,我把一个内部项目从 Spring Boot 3.2 升到了 3.4,整体耗时比预期短,但中间踩了几个不翻官方文档根本想不到的坑。这篇文章就基于这次的升级经历,把 Spring Boot 3.4 的“王炸级更新”拆开揉碎讲清楚:哪些新特…

2026/10/14 18:49:04 阅读更多 →
免费AI视频编辑工具全解析:从剪映到达芬奇的实战操作指南

免费AI视频编辑工具全解析:从剪映到达芬奇的实战操作指南

直接一篇干活的文章,不绕弯子。做视频内容这行,天天跟剪辑软件打交道。市面上的专业工具不少,但有个很现实的问题:要么订阅费一年几百上千,要么就是各种来路不明的“绿色版”“破解版”,用起来总觉得不踏实…

2026/10/14 18:49:04 阅读更多 →
Python提取PDF表格到Excel:三引擎协同的稳定方案

Python提取PDF表格到Excel:三引擎协同的稳定方案

简介:本资源是一套面向Python初学者与办公自动化需求者的PDF表格提取实战方案,聚焦解决财务、审计、行政等场景中从年报PDF批量抽取结构化数据并转存Excel的痛点问题。压缩包共14个文件,含3个真实上市公司年报PDF样本、3个对应生成的Excel结果…

2026/10/14 18:49:04 阅读更多 →
Floyd算法详解:从动态规划推导到C++高性能实现与避坑指南

Floyd算法详解:从动态规划推导到C++高性能实现与避坑指南

直接写,不用那些总结开头。Floyd算法,懂的都懂,多源最短路那个,O(n)的经典思想。但讲真,网上关于它的文章,九成是贴个伪代码就跑,要么就是拿个教科书模板让你背。真正到了生产环境,或…

2026/10/14 18:49:04 阅读更多 →
OpenLayers添加Marker完整指南:原理、样式与性能优化

OpenLayers添加Marker完整指南:原理、样式与性能优化

开篇先说个容易踩的坑:很多人把 marker 打成 maker,然后在社区里搜半天搜不到东西。OpenLayers 里的标记点标准写法是 marker,底层其实是一个 Feature,本质就是“在地图某个经纬度坐标上画一个点”。这个点可以是默认的蓝色圆点&a…

2026/10/14 18:49:04 阅读更多 →
Semantic Router 与 vLLM AIBrix 集成部署实战:在 Kubernetes 上搭建可扩展的语义路由推理网关

Semantic Router 与 vLLM AIBrix 集成部署实战:在 Kubernetes 上搭建可扩展的语义路由推理网关

后端API网关模型推理服务AI Agent 【免费下载链接】semantic-router An open, programmable decision layer for models and compute. 项目地址: https://gitcode.com/gh_mirrors/sem/semantic-router 点击查看 免费下载 本指南以 Semantic Router 官方文档中「使用…

2026/10/14 18:48:03 阅读更多 →

日新闻

AnyPS5通用适配层设计:兼容性与性能的工程取舍

AnyPS5通用适配层设计:兼容性与性能的工程取舍

1. 从"AnyPS5"这个名字说起:它到底想解决什么问题第一次看到"AnyPS5"这个标题,我脑子里冒出来的第一个念头是:这大概率是一个围绕"跨平台运行"或者"通用适配"做文章的项目。名字里的"Any"…

2026/10/14 0:00:41 阅读更多 →
Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

Flutter跨平台开发实战:二手交易应用与HarmonyOS适配

1. 项目概述:Flutter跨平台二手交易应用开发作为一名长期从事移动应用开发的工程师,我最近完成了一个基于Flutter框架的二手物品交易平台项目。这个项目最吸引我的地方在于它完美结合了Flutter的跨平台优势与HarmonyOS的生态特性,实现了"…

2026/10/14 0:00:41 阅读更多 →
DFS算法解决飞机降落调度问题实战

DFS算法解决飞机降落调度问题实战

1. 项目背景与核心思路飞机降落问题是一个经典的调度优化场景,也是算法竞赛和面试中的高频题目。这个题目要求我们合理安排多架飞机的降落顺序和时间,确保所有飞机都能安全着陆而不发生冲突。在实际航空管制中,这类问题直接关系到飞行安全和机…

2026/10/14 0:00:41 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/14 3:30:28 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/14 16:30:29 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/14 3:29:58 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 22:01:27 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 14:57:39 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/14 7:53:34 阅读更多 →