Windows下PyTorch复现PointNet++点云分类实战

1. 为什么要在Windows上折腾PointNet++

搞点云深度学习的人,绕不开PointNet++这个经典网络。它2017年出来之后,几乎成了点云分类和分割任务的基线模型,后续的PointConv、DGCNN、RandLA-Net多多少少都受了它的影响。但真到自己动手复现的时候,你会发现一个很尴尬的现实:大部分开源实现都是跑在Linux上的,官方代码用的是TensorFlow 1.x,而网上能找到的PyTorch版本,要么依赖乱七八糟,要么在Windows上直接报一堆路径和编译错误。

我这次复现的动机很直接——手头只有一台Windows 10的机器,显卡是RTX 2060,想跑通点云分类任务,从ModelNet40数据集上做40类的形状分类。课程里白勇老师讲的是点云处理的整体框架,但具体到代码落地,还是得自己一步步踩坑。这篇文章就是把我从环境配置到训练出结果的全过程记录下来,包括那些让人抓狂的报错和最终的解决方案。

PointNet++的核心思想其实不复杂:它解决了PointNet无法捕捉局部结构的问题。PointNet直接把每个点独立处理再取全局最大值,相当于只看每个点自己,不看邻居。PointNet++引入了Set Abstraction层,通过采样、分组、特征提取三步,逐层扩大感受野,像CNN在图像上做的那样,在点云上构建层次化的特征。分类任务就是把这个层次化特征最后聚合成一个全局向量,再接全连接层输出类别概率。

适合谁来参考这篇内容?如果你有基本的PyTorch使用经验,了解点云的基本概念(比如点云就是一堆三维坐标的集合),想在Windows上快速跑通一个点云分类的demo,那这篇东西能帮你省掉至少两天的排查时间。如果你已经熟悉Linux下的流程,也可以看看Windows上那些特有的坑是怎么绕过去的。

2. 环境搭建与依赖版本选择

2.1 硬件与基础软件清单

先把我用的环境列清楚,避免版本不一致导致的各种玄学问题:

组件版本说明
操作系统Windows 10 专业版 21H264位
GPUNVIDIA RTX 2060 6GB驱动版本 511.23
CUDA11.3必须和PyTorch版本匹配
cuDNN8.2.1对应CUDA 11.3
Python3.8.103.9以上有些包兼容性差
PyTorch1.10.0+cu1131.x系列里比较稳定的版本
torchvision0.11.1+cu113和PyTorch配套
NumPy1.21.5不要用太新的,1.22以上有API变动
h5py3.6.0读取ModelNet40的h5文件

为什么选PyTorch 1.10而不是更新的2.x?因为PointNet++的一些自定义操作(比如最远点采样和球查询)在2.x上会有编译警告,而且很多网上能找到的复现代码都是基于1.7到1.10这个区间写的。1.10是1.x的最后一个稳定版本,CUDA 11.3的支持也很成熟,踩坑概率最低。

注意:CUDA版本、PyTorch版本、显卡驱动三者必须严格对应。我试过用CUDA 11.6配PyTorch 1.10,结果torch.cuda.is_available()返回False,折腾了半天才发现是版本不匹配。

2.2 创建虚拟环境与安装PyTorch

强烈建议用conda建一个独立环境,不要污染base环境。命令如下:

conda create -n pointnet2 python=3.8 conda activate pointnet2

然后安装PyTorch。这里有个关键点:不要用pip直接装,要去PyTorch官网找对应的conda命令。我用的命令是:

conda install pytorch==1.10.0 torchvision==0.11.1 torchaudio==0.10.0 cudatoolkit=11.3 -c pytorch -c conda-forge

装完之后验证一下:

import torch print(torch.__version__) print(torch.cuda.is_available()) print(torch.cuda.get_device_name(0))

如果输出是1.10.0、True和你的显卡型号,那就没问题。如果cuda.is_available()是False,先检查驱动版本,再检查CUDA和PyTorch的对应关系。

2.3 安装其他必要依赖

除了PyTorch,还需要装几个包:

pip install numpy==1.21.5 pip install h5py==3.6.0 pip install scikit-learn pip install matplotlib pip install tqdm

scikit-learn是用来做混淆矩阵和分类报告的,matplotlib用来画训练曲线,tqdm用来显示进度条。这些都是辅助工具,但少了它们调试起来会很痛苦。

实操心得:Windows上装h5py有时候会报错,说找不到hdf5.dll。解决办法是先用conda install h5py,conda会自动处理动态链接库的问题,比pip省心。

3. PointNet++分类网络的核心结构拆解

3.1 整体架构:从点云到类别标签

PointNet++分类网络的结构可以分成三大部分:编码器(Encoder)、特征聚合、分类头(Classification Head)。编码器由多个Set Abstraction层组成,每一层都在做三件事:采样、分组、特征提取。采样是用最远点采样(FPS)从当前点云中选出一定数量的中心点;分组是以每个中心点为圆心,在半径范围内找邻居点;特征提取是把每个组内的点通过一个小型PointNet(共享权重的MLP)映射成特征向量,再取最大值作为该组的特征。

分类任务通常用两层或三层SA层。以ModelNet40为例,输入是1024个点,每层SA的输出点数逐层减少:第一层输出512个点,第二层输出128个点,第三层输出全部点(或者直接做全局池化)。最后把所有点的特征做一次全局最大池化,得到一个固定长度的特征向量,再经过几层全连接层,输出40维的类别分数。

为什么用最大池化而不是平均池化?因为点云是无序的,最大池化对排列不变,而且能保留最显著的特征。平均池化会稀释掉那些只在少数点上出现的判别性特征。

3.2 最远点采样(FPS)的实现细节

FPS的目的是从N个点中选出M个点,使得这M个点尽可能均匀地覆盖整个点云。算法很简单:先随机选一个点作为起点,然后每次选离当前已选点集最远的那个点。时间复杂度是O(N*M),对于1024个点选512个,计算量还能接受。

在PyTorch里实现FPS有两种方式:一种是纯Python循环,速度慢但容易调试;另一种是用CUDA核函数写扩展,速度快但Windows上编译麻烦。我一开始用的是纯Python版本,训练一个epoch要将近3分钟,后来换成了用torch.cdist加速的向量化版本,降到了40秒左右。

向量化FPS的核心思路是用一个距离矩阵记录每个点到已选点集的最小距离,每次选距离最大的点,然后更新距离矩阵。代码大概长这样:

def farthest_point_sample(xyz, npoint): device = xyz.device B, N, C = xyz.shape centroids = torch.zeros(B, npoint, dtype=torch.long).to(device) distance = torch.ones(B, N).to(device) * 1e10 farthest = torch.randint(0, N, (B,), dtype=torch.long).to(device) batch_indices = torch.arange(B, dtype=torch.long).to(device) for i in range(npoint): centroids[:, i] = farthest centroid = xyz[batch_indices, farthest, :].view(B, 1, 3) dist = torch.sum((xyz - centroid) ** 2, -1) mask = dist < distance distance[mask] = dist[mask] farthest = torch.max(distance, -1)[1] return centroids

这段代码在Windows上跑没问题,但要注意torch.randint的返回值类型,老版本PyTorch可能会返回int32,需要显式转成long。

3.3 球查询(Ball Query)的半径选择

球查询是在每个中心点周围找一个半径R内的所有点,如果邻居数量不足K个,就重复采样或者补零。半径R的选择很关键:太小了,每个组内的点太少,学不到局部结构;太大了,组内混入了不同语义部分的点,特征会变得模糊。

在ModelNet40分类任务中,第一层SA通常设R=0.2,K=32;第二层R=0.4,K=64。这个设置是基于点云归一化到单位球面后的经验值。如果输入点云没有归一化,半径需要根据实际尺度调整。

注意:球查询在Windows上的PyTorch实现要注意内存占用。如果batch size设成32,每层SA的分组操作会产生一个(B, M, K, C)的张量,M是中心点数,K是邻居数。第一层M=512,K=32,C=3,这个张量是325123234字节,大约6MB,还能接受。但如果K设成128,内存会翻四倍,6GB显存的卡可能撑不住。

4. 数据准备与预处理

4.1 ModelNet40数据集的获取与格式转换

ModelNet40包含40个类别,每个类别有100个训练样本和20个测试样本,总共12311个CAD模型。官方提供的是OFF格式的网格文件,但PointNet++用的是采样后的点云数据,通常是H5格式。

网上能找到的H5文件一般包含两个键:data和label。data的形状是(N, 1024, 3),label的形状是(N,)。N是样本总数。我用的版本是9843个训练样本和2468个测试样本,这是标准划分。

如果你只有OFF文件,需要自己采样。采样方法是从网格表面均匀采点,可以用trimesh库:

import trimesh mesh = trimesh.load('model.off') points, _ = trimesh.sample.sample_surface(mesh, 1024)

采样后要做归一化:把点云平移到原点,再缩放到单位球面内。这一步很重要,否则不同模型的尺度差异会让网络难以收敛。

4.2 数据增强策略

点云分类的数据增强比图像简单,但效果很明显。我用了三种增强:

  • 随机旋转:绕Z轴旋转0到360度,模拟不同视角。
  • 随机缩放:缩放因子在0.8到1.2之间,增加尺度鲁棒性。
  • 随机抖动:每个点加上均值为0、标准差为0.02的高斯噪声,模拟传感器误差。

注意不要用绕X轴或Y轴的大角度旋转,因为ModelNet40的模型都是朝上的,过度旋转会破坏语义。

实操心得:数据增强在训练时做,测试时不做。我一开始忘了区分,测试集也加了旋转,结果准确率掉了5个百分点。后来在Dataset类里加了一个train标志,训练时才调用增强函数。

4.3 DataLoader的配置

Windows上PyTorch的DataLoader有个坑:num_workers设成大于0时,如果数据集类里有lambda函数或者本地函数,会报pickle错误。解决办法是把所有函数定义在模块顶层,或者直接设num_workers=0。我试过设成4,速度确实快一些,但偶尔会卡死,最后还是用了0,配合pin_memory=True,速度也能接受。

batch size设成24,这是6GB显存下比较稳妥的值。如果设成32,训练到第二层SA时会OOM。学习率用0.001,优化器选Adam,权重衰减1e-4。

5. 训练过程与关键参数调优

5.1 损失函数与优化器选择

分类任务用交叉熵损失就够了。PyTorch的nn.CrossEntropyLoss内部已经包含了softmax,所以网络最后一层不要加softmax。

优化器我对比了SGD和Adam。SGD需要手动调学习率衰减,收敛慢但最终精度可能略高;Adam收敛快,适合快速验证。我最后用了Adam,初始学习率0.001,每20个epoch衰减0.7倍。训练了200个epoch,最终在测试集上达到了91.2%的准确率。

学习率调度用StepLR:

scheduler = torch.optim.lr_scheduler.StepLR(optimizer, step_size=20, gamma=0.7)

5.2 训练循环的实现与监控

训练循环没什么特别的,就是标准的PyTorch流程。但有几个细节要注意:

  • 每个epoch结束后在测试集上评估,记录准确率。
  • 用tqdm显示进度条,方便观察loss变化。
  • 每10个epoch保存一次模型权重,防止训练中断。

我写了一个简单的训练日志,把每个epoch的loss、训练准确率、测试准确率都存到CSV文件里,方便后面画曲线。

for epoch in range(epochs): model.train() for batch in train_loader: points, labels = batch points, labels = points.cuda(), labels.cuda() optimizer.zero_grad() pred = model(points) loss = criterion(pred, labels) loss.backward() optimizer.step() scheduler.step() # 评估 model.eval() with torch.no_grad(): # 测试集评估 pass

5.3 训练曲线分析与调参经验

前50个epoch,训练loss从2.3降到0.5左右,测试准确率从10%升到85%。50到100个epoch,loss继续降到0.2,准确率升到89%。100个epoch之后,loss还在降,但测试准确率基本停滞,说明开始过拟合了。

这时候有几个选择:加dropout、加权重衰减、减少模型参数量。我在分类头里加了一个dropout层,p=0.5,测试准确率提升了1.5个百分点。另外把权重衰减从1e-4调到5e-4,也有帮助。

注意:不要盲目增加训练epoch。我试过训练500个epoch,测试准确率反而降到了88%,因为过拟合太严重了。早停(early stopping)是个好策略,但需要留一个验证集。我是从训练集里切了10%出来做验证。

6. 常见报错与排查实录

6.1 Windows特有的路径与编码问题

Windows上最容易出问题的是路径分隔符。Linux用/,Windows用\,但Python的os.path.join会自动处理。如果你在代码里硬编码了/,在Windows上也能跑,但反过来在Linux上跑Windows风格的路径就会报错。

另一个坑是文件编码。Windows默认用GBK,Linux用UTF-8。如果你用open()读文件时没指定encoding='utf-8',在Windows上读中文路径或者中文注释会报UnicodeDecodeError。解决办法是养成习惯,所有open()都加上encoding='utf-8'。

6.2 CUDA out of memory的解决方案

6GB显存跑PointNet++分类,batch size不能太大。我试过batch size=32,在第一层SA的球查询时OOM。降到24就能跑,但训练速度慢了一些。

如果显存实在不够,有两个办法:一是用梯度累积,把batch size=8的梯度累积4次,等效于batch size=32;二是把第一层SA的输出点数从512降到256,减少分组操作的内存占用。我用的是梯度累积,因为不想改网络结构。

accumulation_steps = 4 for i, batch in enumerate(train_loader): loss = model(batch) / accumulation_steps loss.backward() if (i+1) % accumulation_steps == 0: optimizer.step() optimizer.zero_grad()

6.3 常见报错速查表

报错信息原因解决方法
RuntimeError: CUDA out of memory显存不足减小batch size或用梯度累积
ModuleNotFoundError: No module named 'h5py'缺少依赖pip install h5py
UnicodeDecodeError: 'gbk' codec can't decode文件编码问题open(..., encoding='utf-8')
RuntimeError: Expected all tensors to be on the same device数据和模型不在同一设备检查.cuda()调用
ValueError: too many values to unpack数据加载器返回值数量不对检查Dataset的__getitem__
AssertionError: Torch not compiled with CUDA enabledPyTorch版本不对重装CUDA版本的PyTorch

实操心得:遇到报错先看最后一行,再看倒数第二行。PyTorch的报错信息通常会在最后一行给出具体原因,倒数第二行是出错的位置。不要被中间那一大堆调用栈吓到,真正有用的就那两行。

7. 模型评估与结果分析

7.1 测试集准确率与混淆矩阵

训练完成后,我在测试集上跑了评估,总体准确率91.2%。40个类别里,准确率最高的是“飞机”、“椅子”、“桌子”这些形状特征明显的类别,都在95%以上。准确率最低的是“花瓶”和“杯子”,只有78%左右,这两个类别在形状上确实容易混淆。

混淆矩阵显示,“花瓶”有15%的样本被误判为“杯子”,“杯子”有12%被误判为“花瓶”。这说明网络在区分细长容器和带把手容器时还有困难。如果要进一步提升,可以考虑加入法向量特征,或者用更深的网络。

7.2 可视化分析与错误案例

我用matplotlib画了训练曲线和混淆矩阵。训练曲线显示,训练准确率和测试准确率的差距在100个epoch后逐渐拉大,这是过拟合的典型表现。混淆矩阵的对角线很亮,说明大部分类别分得很好,非对角线上的亮点主要集中在几个形状相似的类别对。

错误案例里,有一个“书架”被分成了“桌子”,因为那个书架是横放的,点云形状和桌子很像。还有一个“吉他”被分成了“花瓶”,因为吉他的琴身是弧形的,和花瓶的轮廓有相似之处。这些错误说明网络学到的特征还是偏向全局形状,对局部细节的捕捉不够。

7.3 推理速度与部署考虑

在RTX 2060上,单次推理(一个1024点的样本)大约需要8毫秒,换算下来每秒能处理125个样本。这个速度对于离线分类任务足够了,但如果要做实时处理,还需要进一步优化,比如用TensorRT加速或者减小网络规模。

模型参数量大约是1.5M,权重文件只有6MB左右,部署到边缘设备上压力不大。但要注意,PointNet++的FPS和球查询操作在推理时也有计算量,如果部署到没有GPU的设备上,需要找CPU版本的实现或者用近似算法替代。

8. 后续改进与扩展方向

8.1 从分类到分割的迁移

分类网络跑通之后,迁移到分割任务其实不难。分割就是把编码器的特征通过上采样(最近邻插值)传回原始点数,再和编码器对应层的特征拼接,最后逐点输出类别。关键是要实现Feature Propagation层,这个在分类网络里没有。

8.2 换用更高效的点云算子

FPS和球查询是PointNet++的计算瓶颈。如果追求速度,可以换成随机采样和KNN查询,精度会掉一点,但速度快很多。另外,PointNet++的SA层可以用更高效的替代方案,比如PointConv或者KPConv,这些在后续的论文里都有开源实现。

8.3 在自定义数据集上的应用

如果你有自己的点云数据,比如激光扫描的室内场景或者深度相机采集的物体,可以直接用这个框架训练。需要注意的是,自定义数据的尺度、密度和噪声水平可能和ModelNet40差异很大,需要重新调整SA层的半径和邻居数。我的经验是先把点云可视化出来,看看点的大致间距,然后半径设成间距的3到5倍。

最后分享一个小技巧:训练的时候把随机种子固定住,这样每次跑的结果都可复现。我一般用torch.manual_seed(42)和np.random.seed(42),虽然不能保证完全一致(因为CUDA的某些操作有随机性),但至少能排除大部分随机因素。踩过几次坑之后,我养成了每个实验都记录完整配置的习惯,包括随机种子、学习率、batch size、数据增强参数,这样出了问题才能快速定位。

相关新闻

别只收藏skills清单:项目式拆解+刻意练习,30天做出作品

别只收藏skills清单:项目式拆解+刻意练习,30天做出作品

1. 先搞清楚一件事&#xff1a;你缺的真是一份“skills清单”吗这个标题其实特别有意思。单独扔过来一个“skills”&#xff0c;乍一看像是职场简历里的那个区块名&#xff0c;又像是一个待办事项列表——今天学Python&#xff0c;明天学剪辑&#xff0c;后天再补个AI绘画。但我…

2026/10/21 4:58:59 阅读更多 →
Windows 10下PyTorch 1.x复现PointNet++点云分类实战

Windows 10下PyTorch 1.x复现PointNet++点云分类实战

1. 点云分类任务的核心价值与复现思路1.1 为什么选择PointNet做点云分类点云分类这件事&#xff0c;放在三维视觉里算是入门级的任务&#xff0c;但真正动手做的人都知道&#xff0c;从数据加载到模型收敛&#xff0c;中间要踩的坑一点都不少。PointNet作为PointNet的升级版&am…

2026/10/21 4:58:59 阅读更多 →
JavaScript时间处理工具类:从时区错位到日期计算的实战指南

JavaScript时间处理工具类:从时区错位到日期计算的实战指南

1. 我先梳理了时间处理的四大痛点场景在动手写任何一行代码之前&#xff0c;我先做了一个动作&#xff1a;把最近几个项目里跟时间打交道的代码全部翻出来&#xff0c;统计了一下到底有多少地方出现过“时间相关bug”。统计结果把我自己都吓了一跳——光一个中等规模的项目里&a…

2026/10/21 4:58:59 阅读更多 →

最新新闻

Seedance2.0实战评测:AI视频生成从能看到能用的关键突破

Seedance2.0实战评测:AI视频生成从能看到能用的关键突破

1. 先说结论&#xff1a;为什么这个版本值得单独写一篇这段时间我一直在折腾AI视频生成相关的项目&#xff0c;从早期的模型试验到现在的落地流程&#xff0c;踩过不少坑。上个月某平台放出了新版本的视频生成模型&#xff0c;代号Seedance2.0&#xff0c;测试了几天之后我的感…

2026/10/21 5:33:12 阅读更多 →
鸿蒙适配Flutter地理空间建模:geotypes地图基座与坐标转换实践

鸿蒙适配Flutter地理空间建模:geotypes地图基座与坐标转换实践

这两年我一直在折腾跨平台地图应用&#xff0c;说实话&#xff0c;地图类 App 里最容易被低估的就是“坐标”本身。表面上看不就是一组经纬度 double 吗&#xff1f;实际上等真正把点线面撒到地图上&#xff0c;你会发现坐标系混用、模型层和渲染层耦合、海量坐标点卡 UI 线程&…

2026/10/21 5:33:12 阅读更多 →
GiveWP未授权PHP对象注入漏洞:从反序列化到WebShell植入

GiveWP未授权PHP对象注入漏洞:从反序列化到WebShell植入

前阵子帮一个做公益募捐的站点排查被挂马的问题&#xff0c;后台多了几个诡异文件&#xff0c;日志里全是陌生IP的请求&#xff0c;翻遍主题、插件都没发现可疑代码。折腾到后半夜&#xff0c;终于在一个捐赠插件 GiveWP 的请求参数里找到了入口&#xff0c;根因是未授权 PHP 对…

2026/10/21 5:33:12 阅读更多 →
千笔AI评测:从论文大纲到降重润色的全流程写作助手

千笔AI评测:从论文大纲到降重润色的全流程写作助手

每年到了论文季&#xff0c;电脑前坐到半夜两三点、屏幕里一排文献和空白文档面面相觑的画面&#xff0c;相信很多人都不陌生。写论文这件事&#xff0c;最大的痛点不是“不会写”&#xff0c;而是写到一半发现结构散了、论点撑不住、格式乱成一团&#xff0c;改起来比重新写还…

2026/10/21 5:33:12 阅读更多 →
用Docker部署百度贴吧自动签到:从BDUSS到定时任务的完整指南

用Docker部署百度贴吧自动签到:从BDUSS到定时任务的完整指南

1. 别再每天手动点签到了&#xff1a;云签到要解决的真实痛点如果你也有关注几十个贴吧、并且每天都会顺手签到的习惯&#xff0c;应该能理解那种"断签恐惧"。某个加班夜回来倒头就睡&#xff0c;第二天盯着贴吧里"已连续签到 47 天"突然变回"1 天&qu…

2026/10/21 5:33:12 阅读更多 →
Agent安全防护实战:ClawSec套件应对提示注入与数据泄露

Agent安全防护实战:ClawSec套件应对提示注入与数据泄露

上个月我去给一个智能客服项目做安全评估&#xff0c;测试环境里Agent被一条精心构造的对话绕过了系统约束&#xff0c;直接把后台提示词原样吐了出来。这种问题现在太常见了&#xff1a;提示注入、工具越权、敏感信息外带&#xff0c;正在成为所有Agent应用的集体焦虑。传统的…

2026/10/21 5:32:12 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事&#xff1a;AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里&#xff0c;按宣传口径&#xff0c;本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”&#xff0c;而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起&#xff1a;用户到底在追求什么“封号重开”这四个字&#xff0c;放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流&#xff0c;背后是大量的时间和精力成本。正常情况下&#xff0c;没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”&#xff0c;而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时&#xff0c;就意识到&#xff1a;单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型&#xff08;GMM&#xff09;的语音识别系统&#xff0c;很多人第一反应就是一堆数学公式&#xff0c;觉得门槛很高。但如果你真的在MATLAB里把它落地跑通&#xff0c;会发现核心其实就是三件事&#xff1a;把声音变成特征向量&#xff0c;用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人&#xff0c;但落到具体操作上&#xff0c;无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程&#xff1a;对图像做反白、改调色板、彩色转灰度&#xff0c;最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词&#xff0c;你会发现一个很有意思的现象&#xff1a;每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型&#xff0c;有人指的是运动控制系统&#xff0c;还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/21 4:27:17 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →