首页/新闻资讯/正文详情

RKNN上部署YOLOv8seg:模型转换与后处理全解析

发布时间:2026/9/25 4:44:19 来源:云帆数科 栏目:资讯中心
RKNN上部署YOLOv8seg:模型转换与后处理全解析
1. 为什么要在RKNN上跑YOLOv8seg1.1 边缘端实例分割的真实需求做边缘计算这几年我经手过不少把视觉模型往嵌入式板子上搬的项目。早期大家的需求很单纯就是目标检测画个框、报个类别任务就结束了。但这两年明显感觉到客户和产品经理的胃口变了——他们不再满足于“这里有个东西”而是想知道“这个东西的轮廓到底长什么样”。比如智能仓储里要算包裹的堆叠面积、工业质检里要抠出划痕的精确形状、农业场景里要估算果实被遮挡的比例这些需求光靠检测框根本做不了必须上实例分割。YOLOv8seg就是在这个背景下被大量使用的。它在YOLOv8检测头的基础上挂了一个分割分支输出每个实例的掩码mask既能定位又能抠形状精度和速度的平衡做得相当不错。问题是这类模型参数量动辄几百万上千万直接丢到算力有限的嵌入式NPU上跑帧率会难看到让人怀疑人生。这时候RKNN就登场了。RKNN是瑞芯微Rockchip为其NPU系列芯片提供的推理框架配套的RKNN-Toolkit2负责把训练好的模型转换成NPU能吃的.rknn格式。我手上常用的RK3588、RK3568、RK3566这几块板子NPU算力从0.8TOPS到6TOPS不等跑量化后的YOLOv8seg在640输入下做到十几到几十毫秒一帧是完全可行的。关键在于你得把“模型转换”和“后处理”这两件事做对否则要么转换失败要么推理结果全是乱的。1.2 这篇文章适合谁看如果你手上有训练好的YOLOv8seg权重.pt文件想把它部署到RK3588之类的板子上但卡在了ONNX导出、RKNN转换或者后处理对不上的环节那这篇内容就是写给你的。我会从模型导出开始一步步讲到RKNN转换、量化、板端推理最后重点拆解后处理——因为后处理是坑最多的地方官方demo给的那套代码直接套到YOLOv8seg上十有八九结果是不对的。零基础也能看但前提是你得会基本的Python知道什么是张量、什么是通道。至于NPU、量化、算子这些概念我会用生活化的方式解释清楚不需要你提前懂。1.3 整体技术路线先捋一遍在动手之前先把整条链路在脑子里过一遍这样后面每一步你都知道自己在干什么训练侧用Ultralytics的YOLOv8seg训练得到best.pt。导出侧把.pt导出成ONNX注意opset版本和输出节点。转换侧用RKNN-Toolkit2把ONNX转成.rknn中间做量化校准。推理侧板端用RKNN Runtime加载.rknn喂图、拿输出。后处理侧对NPU吐出来的原始张量做解码还原出框、类别、掩码。这五步里第2步和第5步是最容易翻车的。导出时如果输出节点选错后面后处理根本没法写后处理如果没搞懂YOLOv8seg的输出结构结果就是一堆乱码。下面我逐个拆。2. 模型导出与RKNN转换的关键细节2.1 从pt到ONNX输出节点怎么选Ultralytics的库用起来确实方便一行命令就能导出ONNXyolo export modelbest.pt formatonnx opset12 simplifyTrue但这里有个坑默认导出的ONNX输出是合并后的张量对于分割模型来说输出结构是output0和output1两个。output0是检测分支形状大概是[1, 116, 8400]116 4个框坐标 80个类别 32个掩码系数output1是掩码原型mask prototypes形状是[1, 32, 160, 160]。我建议在导出时显式指定opset12因为RKNN-Toolkit2对opset 11和12的支持最稳opset 13以上有些算子会转换失败。另外simplifyTrue一定要开它会把一些冗余的算子融合掉减少转换时的麻烦。导出完成后强烈建议用Netron打开ONNX看一眼确认输出节点名字和形状。我见过有人导出后输出节点叫output0和output1也有人因为版本差异叫别的名字后处理代码里写死了名字就会报错。所以第一步就是确认清楚。提示如果你的Ultralytics版本较老导出分割模型时可能不会自动带上掩码原型分支建议升级到8.0.100以上版本再导出。2.2 RKNN-Toolkit2环境搭建RKNN-Toolkit2是跑在PC上的转换工具不是板端的东西。官方推荐用Ubuntu 20.04或22.04Python 3.8到3.10。我实测下来Python 3.10 Ubuntu 22.04的组合最省心。安装方式有两种一种是pip直接装一种是下wheel包本地装。我建议用后者因为pip源上的版本有时候和板端Runtime对不上。去官方仓库下载对应版本的rknn_toolkit2-xxx.whl然后pip install rknn_toolkit2-1.6.0-cp310-cp310-linux_x86_64.whl装完之后验证一下from rknn.api import RKNN print(RKNN Toolkit2 loaded)能打印出来就说明环境OK。这里要注意RKNN-Toolkit2和板端的RKNN Runtime版本要匹配比如Toolkit是1.6.0板端librknnrt.so也最好是1.6.0附近差太多会出现加载模型失败的情况。2.3 转换脚本怎么写逐行拆解转换脚本是整个流程的核心我把它拆成几个部分讲。先看完整骨架from rknn.api import RKNN rknn RKNN(verboseTrue) # 1. 配置 rknn.config( mean_values[[0, 0, 0]], std_values[[255, 255, 255]], target_platformrk3588, quantized_dtypeasymmetric_quantized-8, optimization_level3 ) # 2. 加载ONNX ret rknn.load_onnx(modelbest.onnx) assert ret 0 # 3. 构建 ret rknn.build(do_quantizationTrue, datasetdataset.txt) assert ret 0 # 4. 导出 ret rknn.export_rknn(best.rknn) assert ret 0config里的mean_values和std_values是归一化参数。YOLOv8训练时输入是0到1之间的浮点数归一化方式是除以255。所以这里mean设0std设255等价于把输入从0到255映射到0到1。如果你在训练时用了别的归一化方式这里要对应改。target_platform填你的板子型号RK3588就填rk3588RK3568填rk3568。填错会导致生成的模型在板子上跑不了。quantized_dtype选asymmetric_quantized-8这是8位非对称量化精度和速度平衡最好。如果你对精度要求极高可以先用dynamic_fixed_point-16试试但速度会慢不少。optimization_level3是最高优化等级会做一些算子融合和内存优化建议开。2.4 量化数据集准备别随便找几张图糊弄build的时候如果开了do_quantizationTrue就需要一个dataset.txt里面每行是一张校准图片的路径。这个数据集的质量直接决定量化后的精度。我的经验是校准图片至少准备100到200张而且必须是从真实应用场景里采的图不能随便拿几张网图凑数。比如你做的是工业质检就用产线上拍的图做的是安防就用监控截图。图片的分布要和实际推理时一致否则量化误差会很大。dataset.txt的格式很简单就是纯文本每行一个路径./calib/001.jpg ./calib/002.jpg ./calib/003.jpg ...图片不需要标注只要原图就行。尺寸也不用统一RKNN会自动resize但建议和推理时的输入尺寸保持一致减少误差。注意校准图片里如果包含大量空白或者极端光照的图量化效果会变差。我一般会先人工筛一遍把明显异常的图剔掉。2.5 转换常见报错与解决转换过程中最常见的报错有这么几类报错信息原因解决办法Unsupported op: xxxONNX里有RKNN不支持的算子升级Toolkit版本或在导出ONNX时用simplify融合掉Quantize failed校准数据集有问题检查图片路径、格式增加图片数量Load model failed板端Runtime版本不匹配统一Toolkit和Runtime版本Input shape mismatch输入尺寸和配置不一致检查config里的输入尺寸设置我遇到最多的是Unsupported op尤其是分割模型里的Resize算子。解决办法是在导出ONNX时把opset设成12并且开simplify。如果还不行就得手动改ONNX图把不支持的算子替换掉这个就比较麻烦了需要用到onnx-simplifier或者onnxruntime的工具。3. 板端推理与后处理全解析3.1 板端Runtime加载模型板端的推理代码用C或者Python都行。Python版用rknnliteC版用librknnrt。我这里用Python举例因为调试方便实际产品里再换成C。from rknnlite.api import RKNNLite rknn RKNNLite() ret rknn.load_rknn(best.rknn) ret rknn.init_runtime(core_maskRKNNLite.NPU_CORE_0)core_mask是RK3588特有的它有三个NPU核心可以指定用哪个。如果要做多路推理可以把不同路分配到不同核心上提高吞吐。推理的时候import cv2 import numpy as np img cv2.imread(test.jpg) img cv2.cvtColor(img, cv2.COLOR_BGR2RGB) img cv2.resize(img, (640, 640)) img np.expand_dims(img, axis0) outputs rknn.inference(inputs[img])outputs是一个列表里面是NPU吐出来的原始张量。对于YOLOv8seg通常是两个输出检测分支和掩码原型。但要注意RKNN量化后的输出可能是int8类型需要反量化才能用。3.2 输出张量结构彻底搞懂这是后处理的核心必须搞懂每个数字代表什么。假设输入是640x640YOLOv8seg的输出检测分支形状[1, 116, 8400]。8400是预测框的数量80x80 40x40 20x20 6400 1600 400 8400。116 4框坐标xywh 80类别分数 32掩码系数。掩码原型形状[1, 32, 160, 160]。32是掩码的通道数160x160是掩码的空间分辨率。后处理要做的就是从检测分支里筛出置信度高的框然后用这些框对应的32个掩码系数去和掩码原型做矩阵乘法得到每个实例的掩码。这里有个关键点检测分支的输出是[1, 116, 8400]但实际用的时候要转置成[8400, 116]因为8400是样本维度116是特征维度。转置之后每一行是一个预测前4个是框中间80个是类别后32个是掩码系数。3.3 框解码从xywh到xyxyYOLOv8的输出框格式是xywh而且是相对于640x640输入的中心点坐标和宽高。解码的时候boxes outputs[0][0, :4, :].T # [8400, 4] scores outputs[0][0, 4:84, :].T # [8400, 80] mask_coeffs outputs[0][0, 84:, :].T # [8400, 32]然后对每个框x, y, w, h box x1 x - w / 2 y1 y - h / 2 x2 x w / 2 y2 y h / 2这些坐标是相对于640x640的最后要按比例映射回原图。3.4 置信度筛选与NMS先按类别分数筛取每个框的最大类别分数如果大于阈值一般0.25就保留。然后做NMS非极大值抑制把重叠的框去掉。NMS的IoU阈值一般设0.45。这里要注意YOLOv8seg的NMS是对框做的不是对掩码做的。筛完之后保留的框对应的掩码系数也一起保留。def nms(boxes, scores, iou_threshold0.45): # 标准NMS实现 ...我建议直接用OpenCV的cv2.dnn.NMSBoxes省得自己写。3.5 掩码生成矩阵乘法的细节这是YOLOv8seg后处理最精髓的地方。掩码原型是[32, 160, 160]每个实例有32个掩码系数。把系数和原型做矩阵乘法masks mask_coeffs mask_protos.reshape(32, -1) # [N, 160*160] masks masks.reshape(N, 160, 160)得到的是160x160的掩码然后要crop到框的范围内再resize回原图尺寸。这里有个细节掩码原型是160x160而输入是640x640所以掩码的分辨率是输入的1/4。crop的时候框坐标要先除以4映射到160x160的尺度上。# 框坐标映射到160x160 x1_m int(x1 / 4) y1_m int(y1 / 4) x2_m int(x2 / 4) y2_m int(y2 / 4) # crop掩码 mask masks[i, y1_m:y2_m, x1_m:x2_m]然后对掩码做二值化大于0.5的置1再resize回原图。3.6 反量化int8到float的转换RKNN量化后的输出是int8需要反量化。反量化的公式是float_value (int8_value - zero_point) * scalezero_point和scale可以从RKNN的输出属性里拿到。在Python里outputs rknn.inference(inputs[img]) # outputs[0]是int8需要反量化RKNNLite的inference默认会返回反量化后的float但有时候需要手动处理。如果你发现输出全是整数那就是没反量化需要手动做。提示RKNN-Toolkit2在转换时可以设置quantized_algorithm有normal和mmse两种。mmse精度更高但转换更慢我一般用normal够用了。4. 实操中踩过的坑与排查技巧4.1 掩码全黑或者全白这是最常见的问题。原因通常是掩码系数和掩码原型没对齐或者矩阵乘法做错了。检查步骤确认mask_coeffs的形状是[N, 32]mask_protos的形状是[32, 160, 160]。确认矩阵乘法的顺序是coeffs protos不是反过来。确认crop的时候坐标映射正确除以4这个步骤不能漏。我遇到过一次掩码全黑查了半天发现是mask_protos的通道顺序反了reshape的时候把[32, 160, 160]写成了[160, 160, 32]导致矩阵乘法维度对不上结果全是0。4.2 框的位置偏移框偏移一般是坐标映射的问题。YOLOv8的输出是相对于640x640的如果你直接拿这个坐标去原图上画肯定偏。正确的做法是scale_x orig_w / 640 scale_y orig_h / 640 x1 x1 * scale_x y1 y1 * scale_y但要注意如果原图是resize到640x640的而且保持了宽高比letterbox那还要减去padding的偏移。我一般用letterbox的方式预处理这样不会变形但后处理时要记得把padding去掉。4.3 量化后精度掉得厉害量化掉精度是正常的但掉太多就不正常了。排查方向校准数据集是不是太少或者分布不对增加到200张以上确保覆盖各种场景。量化算法换成mmse试试。检查mean_values和std_values是不是和训练时一致。如果还不行考虑混合量化把敏感层用16位其他用8位。我做过一个工业质检的项目量化后mAP掉了8个点后来把校准集从100张增加到300张并且确保包含了各种光照和角度的图mAP只掉了2个点完全可以接受。4.4 推理速度不达预期RK3588的NPU算力是6TOPS但实际推理速度受很多因素影响输入尺寸640x640比320x320慢4倍左右。NPU核心只用单核比用三核慢但三核有调度开销小模型不一定划算。内存带宽NPU和CPU共享内存如果内存带宽吃满速度会掉。后处理后处理在CPU上做如果NMS和掩码生成写得低效会成为瓶颈。我实测下来YOLOv8seg在RK3588上640输入单核推理大概30到40毫秒三核能到15到20毫秒。后处理如果优化好能控制在10毫秒以内。4.5 常见问题速查表现象可能原因排查方法模型加载失败Runtime版本不匹配检查librknnrt.so版本推理输出全0输入没归一化检查mean/std配置框位置偏移坐标映射错误检查letterbox和scale掩码全黑矩阵乘法维度错检查reshape和乘法顺序精度掉太多量化校准集问题增加校准图换mmse速度慢后处理瓶颈profile后处理耗时5. 性能优化与进阶技巧5.1 多核并行推理RK3588有三个NPU核心如果要做多路视频流推理可以把不同路分配到不同核心。用RKNNLite的时候初始化时指定core_maskrknn.init_runtime(core_maskRKNNLite.NPU_CORE_0) rknn2.init_runtime(core_maskRKNNLite.NPU_CORE_1) rknn3.init_runtime(core_maskRKNNLite.NPU_CORE_2)这样三路可以并行跑吞吐量提升接近3倍。但要注意每个核心都要加载一份模型内存占用会翻倍。5.2 后处理用C重写Python的后处理虽然方便但速度慢。如果对帧率要求高建议用C重写后处理尤其是NMS和掩码生成这两块。C版的后处理能比Python快5到10倍。我一般先用Python调通确认结果正确再把后处理逻辑翻译成C。翻译的时候注意矩阵乘法的实现可以用Eigen或者手写循环。5.3 输入尺寸的取舍640x640是YOLOv8的默认输入但实际部署时不一定非要用640。如果目标物体比较大320x320也能用速度能快4倍。如果目标很小可能需要960甚至1280但速度会慢很多。我的建议是先统计一下实际场景里目标物体的像素尺寸如果大部分目标在64x64以上320输入就够了如果在32x32左右640比较稳如果小于16x16那就得上大输入了。5.4 模型剪枝与蒸馏如果量化后精度还是不够可以考虑在训练侧做剪枝或者蒸馏。剪枝是把不重要的通道去掉减小模型体积蒸馏是用大模型教小模型提升小模型的精度。这两个都是训练侧的技术和RKNN转换不冲突剪枝后的模型照样能转RKNN。我做过一个项目原始YOLOv8seg量化后mAP只有0.65后来用蒸馏训练了一个小模型量化后mAP到了0.72速度还快了30%。5.5 动态输入的支持RKNN支持动态输入但需要转换时指定。动态输入的好处是可以用同一个模型处理不同尺寸的图坏处是推理速度会慢一些因为NPU没法做静态优化。如果场景里图片尺寸变化很大可以考虑动态输入如果尺寸固定还是用静态输入速度更快。6. 一个完整的后处理代码示例6.1 代码结构说明下面给一个完整的后处理示例基于Python和NumPy。这段代码我实际项目里用过改改就能用。import numpy as np import cv2 def postprocess(outputs, orig_img, conf_thres0.25, iou_thres0.45): # outputs[0]: [1, 116, 8400] # outputs[1]: [1, 32, 160, 160] det outputs[0][0].T # [8400, 116] protos outputs[1][0] # [32, 160, 160] boxes det[:, :4] scores det[:, 4:84] mask_coeffs det[:, 84:] # 最大类别分数 class_ids np.argmax(scores, axis1) confs scores[np.arange(len(scores)), class_ids] # 置信度筛选 keep confs conf_thres boxes boxes[keep] confs confs[keep] class_ids class_ids[keep] mask_coeffs mask_coeffs[keep] # xywh - xyxy xyxy np.zeros_like(boxes) xyxy[:, 0] boxes[:, 0] - boxes[:, 2] / 2 xyxy[:, 1] boxes[:, 1] - boxes[:, 3] / 2 xyxy[:, 2] boxes[:, 0] boxes[:, 2] / 2 xyxy[:, 3] boxes[:, 1] boxes[:, 3] / 2 # NMS indices cv2.dnn.NMSBoxes( xyxy.tolist(), confs.tolist(), conf_thres, iou_thres ) indices np.array(indices).flatten() xyxy xyxy[indices] confs confs[indices] class_ids class_ids[indices] mask_coeffs mask_coeffs[indices] # 生成掩码 masks mask_coeffs protos.reshape(32, -1) # [N, 25600] masks masks.reshape(-1, 160, 160) masks 1 / (1 np.exp(-masks)) # sigmoid # 映射回原图 orig_h, orig_w orig_img.shape[:2] scale_x orig_w / 640 scale_y orig_h / 640 results [] for i in range(len(xyxy)): box xyxy[i] # 映射到160x160 x1 int(box[0] / 4) y1 int(box[1] / 4) x2 int(box[2] / 4) y2 int(box[3] / 4) mask masks[i, y1:y2, x1:x2] mask (mask 0.5).astype(np.uint8) * 255 mask cv2.resize(mask, (orig_w, orig_h)) # 映射框回原图 box_orig box.copy() box_orig[0] * scale_x box_orig[1] * scale_y box_orig[2] * scale_x box_orig[3] * scale_y results.append({ box: box_orig, conf: confs[i], class_id: class_ids[i], mask: mask }) return results6.2 关键步骤注释这段代码里有几个地方容易出错我单独说一下。det outputs[0][0].T这一步outputs[0]的形状是[1, 116, 8400]取[0]之后变成[116, 8400]转置成[8400, 116]。这样每一行是一个预测。masks mask_coeffs protos.reshape(32, -1)这一步mask_coeffs是[N, 32]protos.reshape(32, -1)是[32, 25600]乘出来是[N, 25600]再reshape成[N, 160, 160]。sigmoid那一步不能漏因为掩码系数和原型乘出来的结果是logits要过sigmoid才是概率。crop的时候x1 int(box[0] / 4)这个4是640/160得来的。如果输入尺寸变了这个除数也要变。6.3 结果可视化可视化的时候把掩码叠加到原图上for r in results: mask r[mask] color np.random.randint(0, 255, 3) orig_img[mask 0] orig_img[mask 0] * 0.5 color * 0.5 cv2.rectangle(orig_img, (int(r[box][0]), int(r[box][1])), (int(r[box][2]), int(r[box][3])), color.tolist(), 2)这样就能看到每个实例的掩码和框了。7. 部署上线的几点经验7.1 内存管理RK3588的内存是共享的NPU和CPU用同一块内存。如果模型大、输入大内存占用会很高。我一般会监控内存使用确保不超过板子总内存的80%。加载模型的时候RKNNLite会分配内存如果加载多个模型内存会累加。所以多路推理的时候要么用同一个模型实例要么控制路数。7.2 温度与降频RK3588跑满NPU的时候发热不小如果散热不好会触发降频推理速度会掉。我一般会加散热片或者用风扇。实测下来不加散热的话连续跑10分钟速度会掉20%左右。7.3 模型版本管理实际项目里模型会迭代。每次迭代都要重新导出ONNX、转RKNN、更新板端模型文件。我建议用版本号管理比如best_v1.rknn、best_v2.rknn板端代码里读配置决定加载哪个版本。这样回滚也方便。7.4 日志与监控上线之后要记录每帧的推理耗时、后处理耗时、内存占用。这些数据能帮你快速定位问题。我一般会在代码里加个简单的计时器把数据写到日志文件里定期分析。8. 写在最后的一些个人体会这套流程我前前后后跑过不下十次每次都会遇到新问题。最深的体会是模型转换和后处理这两块官方文档给的信息太少了很多细节得自己试。比如量化校准集要多少张、掩码crop的坐标怎么算、反量化什么时候要做这些文档里都没写清楚只能靠踩坑积累。另一个体会是不要迷信量化后的精度。量化一定会掉点关键是掉多少你能接受。如果掉太多先别急着换方案先把校准集搞好往往能救回来一大半。最后后处理代码一定要自己写一遍不要直接抄网上的。因为每个人的输入尺寸、输出结构、预处理方式都不一样抄来的代码大概率跑不通。自己写一遍哪怕慢一点但心里有数出了问题也知道去哪查。

相关推荐

HP打印机导致Windows资源管理器崩溃的根因与修复
HP打印机导致Windows资源管理器崩溃的根因与修复

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

嵌入式Linux交叉编译v4l2-utils与摄像头采集验证实战
嵌入式Linux交叉编译v4l2-utils与摄像头采集验证实战

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

MLIR中文文档完全拆解:从方言到Pass管线的编译器学习路线
MLIR中文文档完全拆解:从方言到Pass管线的编译器学习路线

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

AI驱动代码审查:open-code-review命令行工具的设计与实践
AI驱动代码审查:open-code-review命令行工具的设计与实践

代码审查这件事,我在团队里正经推过两年,最后都败给了同一句话:“太忙了,没时间看。”不是工程师不重视质量,而是传统的 Code Review 流程门槛太高:要切换上下文、要维护审查清单、要消化一大段 diff&#… · 2026/9/25 5:53:55

广告联盟APP实战:反作弊与数据统计的完整落地指南
广告联盟APP实战:反作弊与数据统计的完整落地指南

广告联盟APP这个方向,我是从一张白纸开始做的。当时团队接到的任务很明确:做一个能同时对接多家广告源、把流量给到下游开发者、并且自己平台能抽成的联盟型APP。一开始以为重心肯定在“接SDK、写广告位、做UI”上,结果真正跑起来才发现&… · 2026/9/25 5:53:49

温州地区用户对炬峰科技的满意度怎么样
温州地区用户对炬峰科技的满意度怎么样

从温州阀门制造产业升级看炬峰智能的用户价值沉淀时光翻涌,中国制造业的产业升级浪潮已经走过数十个年头,作为国内燃气阀门、瓶阀产业的核心集聚区,浙东南地区的制造业生态早已发生了翻天覆地的变化。从家庭小作坊式的人工装配,到… · 2026/9/25 5:53:49

python-for-android 完整指南:将 Python 应用打包为 Android APK / AAB / AAR
python-for-android 完整指南:将 Python 应用打包为 Android APK / AAB / AAR

开发工具构建工具移动开发 【免费下载链接】python-for-android Turn your Python application into an Android APK 项目地址: https://gitcode.com/gh_mirrors/py/python-for-android 点击查看 免费下载 python-for-android(简称 p4a)是 K… · 2026/9/25 5:53:49

TypeDoc 展开标签深度解析:@expand、@expandType 与 @preventExpand 如何控制类型引用的文档展示
TypeDoc 展开标签深度解析:@expand、@expandType 与 @preventExpand 如何控制类型引用的文档展示

开发工具文档 【免费下载链接】typedoc Documentation generator for TypeScript projects. 项目地址: https://gitcode.com/gh_mirrors/ty/typedoc 点击查看 免费下载 TypeDoc 在渲染文档时,默认只会把类型别名或接口的引用显示为一个链接,… · 2026/9/25 5:53:43

Spinnaker Rosco halconfig 配置骨架解析:Halyard 拼接机制、弃用迁移与烘焙默认值配置指南
Spinnaker Rosco halconfig 配置骨架解析:Halyard 拼接机制、弃用迁移与烘焙默认值配置指南

后端DevOps云原生微服务 【免费下载链接】spinnaker Spinnaker is an open source, multi-cloud continuous delivery platform for releasing software changes with high velocity and confidence. 项目地址: https://gitcode.com/gh_mirrors/sp/spinnaker 点击查… · 2026/9/25 5:53:43

数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)
数值优化(Numerical Optimization)学习系列-03-共轭梯度方法(Conjugate Gradient)

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

创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战
创维E900V22D刷机全攻略:S905L3SB芯片兼容性解析与救砖实战

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

MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX
MQTT协议原理与Broker服务器搭建实战:从Mosquitto到EMQX

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

了解更多?预约专属演示

我们的顾问将为您一对一讲解产品与方案

企业微信二维码