news 2026/9/28 17:40:18

Unity模型PNG导出:可控渲染方案实现任意方向与尺寸

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Unity模型PNG导出:可控渲染方案实现任意方向与尺寸

简介:本资源是一套面向Unity开发者与3D美术工程师的模型截图导出工具集,聚焦于在运行时高质量生成并导出PNG图片,解决多角度、多尺寸模型预览图批量输出的工程化需求,适用于游戏资源审核、美术资产归档、自动化文档生成等实际场景。压缩包共2000个文件,主体包含1004个二进制资源(bin)、173个动态链接库(dll)及配套元数据(meta)、178份Markdown说明文档(md),另有76张PNG与49张JPG格式的示例图、31个FBX模型文件、63个材质(mat)及若干JSON配置与prefab预制体,整体体积达408.77MB,结构完整、模块清晰。已有439人学习下载。资源提供三种渐进式实现方案,其中第三种支持实时调整视角方向、缩放比例与画布分辨率,配合RuntimePreviewGenerator等核心脚本与ProjectSettings等工程配置文件,可直接集成至现有Unity项目,无需额外环境搭建,开箱即用。

1. Unity 模型截图导出 PNG:不是截图,是可控渲染——解决 UI 预览、资产文档、自动化美术检查三大刚需

你有没有遇到过这些场景:

  • 美术提交一个 FBX 模型,策划想快速确认它在正交视角下的轮廓是否符合 UI 图标规范,但每次都要手动调摄像机、截屏、裁剪、命名,一上午干不完 20 个;
  • 自动化构建流程里需要为每个角色生成「标准三视图」(前/侧/顶)PNG 用于 Wiki 文档,但 Unity 原生没有批量导出接口;
  • 想让模型在特定光照下、以 512×512 像素、纯白背景、无 UI 叠加、带 Alpha 通道的方式导出,结果用ScreenCapture.CaptureScreenshot()得到的是整个 Game 视图,含 HUD、分辨率随窗口跑、还带编辑器边框。

本文提供的不是“截图技巧”,而是Runtime 渲染管线级的 PNG 导出控制方案:它绕过屏幕捕获,直接从 Camera.Render() 后的 RenderTexture 中读取像素,再经 Texture2D.EncodeToPNG() 编码为字节数组,最终写入磁盘。这意味着——方向(rotation)、大小(resolution)、背景(clear color)、裁剪(viewport rect)、抗锯齿(MSAA)、甚至 HDR 转 LDR 的 gamma 校正,全部可编程控制。三种方案中,第三种(基于RenderTexture+Camera.targetTexture+Graphics.Blit)是唯一能真正实现「任意控制方向和大小」的生产级方案,也是 CI/CD 流水线中稳定调用的首选。适合 Unity 2019.4+ 项目,尤其适用于需要生成模型预览图、3D 资产文档、AR/VR 内容缩略图、或对接 AI 训练数据集的团队。


2. 方案一:ScreenCapture.CaptureScreenshot —— 快速验证用,但边界极窄

这是 Unity 官方最简 API,适合单次手动触发、不关心精度的临时截图。它本质是抓取当前 GameView 或 Game 窗口的显示内容,完全不可控渲染参数,所有“方向”“大小”都依赖编辑器窗口状态,无法用于自动化。

2.1 基础用法与典型调用链

// C# 脚本:ScreenshotHelper.cs using UnityEngine; using System.IO; public static class ScreenshotHelper { public static void CaptureToPng(string fileName = "screenshot") { string path = Path.Combine(Application.persistentDataPath, $"{fileName}.png"); ScreenCapture.CaptureScreenshot(path); Debug.Log($"Screenshot saved to: {path}"); } }

提示:Application.persistentDataPath是跨平台安全路径(Windows:%LOCALAPPDATA%\CompanyName\ProductName\, macOS:~/Library/Application Support/CompanyName/Product Name/),避免硬编码C:\temp。

这段代码执行后,会在persistentDataPath下生成 PNG 文件。但注意:它只捕获当前 GameView 显示区域,若 GameView 分辨率是 1280×720,输出就是 1280×720;若窗口被遮挡、缩放、或处于 Play Mode 外,行为不可预测。

2.2 为什么它不能控制“方向”和“大小”?

  • 方向(Rotation):ScreenCapture不操作 Camera,它只是“拍照”。模型朝向由 Scene 中 Camera 的 Transform 决定,而该 Camera 通常绑定在 Main Camera 上,其 rotation 是运行时状态,无法在截图瞬间动态设置(除非你先改 Camera.rotation,再等一帧渲染完成,再截图——但这已超出ScreenCapture能力)。
  • 大小(Resolution):输出尺寸严格等于 GameView 当前像素宽高。你无法指定“我要 1024×1024 正方形”,除非你先把 GameView 拉成正方形并缩放至 100%,这在自动化脚本中不可行。
  • 背景与裁剪:它捕获的是最终合成画面,包含 UI Canvas、Gizmos、Scene View 叠加层(如果开启),且无法设置 Clear Color。

所以,此方案仅推荐用于:
✅ 快速验证模型是否加载成功;
✅ 手动调试时临时存档当前视角;
❌ 绝对不用于任何需复现性、尺寸一致性、或批量处理的场景。

2.3 一个真实翻车案例:UI 预览图错位

某 UI 团队用此方案为按钮模型生成图标预览图,脚本如下:

// 错误示范! Camera.main.transform.rotation = Quaternion.Euler(0, 0, 0); // 重置旋转 Camera.main.orthographicSize = 2f; ScreenCapture.CaptureScreenshot("btn_icon.png");

问题:Camera.main.transform.rotation修改后,Unity不会立即重新渲染。CaptureScreenshot()在下一帧前执行,此时 Camera 还未应用新 rotation,截图仍是旧视角。更糟的是,orthographicSize改变后,视口缩放需至少一帧才能生效。结果:生成的 PNG 总是偏移 15 度,且尺寸忽大忽小。

解决思路:必须显式触发一次完整渲染循环。但ScreenCapture本身不提供该能力——这正是它被淘汰的根本原因。


3. 方案二:RenderTexture + ReadPixels —— 可控起点,但性能与精度有硬伤

此方案开始进入“可控渲染”范畴:创建独立 RenderTexture,将 Camera 渲染目标设为它,再用Texture2D.ReadPixels()读取像素。相比方案一,它解耦了 GameView,可自由设置分辨率、Clear Color、甚至 MSAA。

3.1 核心流程与最小可运行代码

// C# 脚本:RenderTextureCapture.cs using UnityEngine; using System.IO; public static class RenderTextureCapture { public static void CaptureToPng(Camera cam, int width, int height, string fileName) { // 1. 创建 RenderTexture(关键:启用深度缓冲 & MSAA) RenderTexture rt = new RenderTexture(width, height, 24, RenderTextureFormat.DefaultHDR); rt.antiAliasing = 4; // 启用 4x MSAA rt.Create(); // 2. 临时重定向 Camera 渲染目标 RenderTexture currentTarget = cam.targetTexture; cam.targetTexture = rt; // 3. 强制 Camera 渲染一帧(关键!) cam.Render(); // 4. 创建 Texture2D 并读取像素 Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false); tex.ReadPixels(new Rect(0, 0, width, height), 0, 0); tex.Apply(); // 必须调用 Apply() 才能读取有效像素 // 5. 编码为 PNG 并保存 byte[] bytes = tex.EncodeToPNG(); string path = Path.Combine(Application.persistentDataPath, $"{fileName}.png"); File.WriteAllBytes(path, bytes); // 6. 清理资源 Object.DestroyImmediate(rt); Object.DestroyImmediate(tex); cam.targetTexture = currentTarget; // 恢复原 targetTexture } }

调用方式(例如在 Editor 脚本中):

// Editor 调用示例 [MenuItem("Tools/Capture Model View")] static void CaptureModelView() { Camera cam = GameObject.Find("PreviewCamera").GetComponent<Camera>(); cam.transform.rotation = Quaternion.Euler(30, 45, 0); // 任意控制方向 RenderTextureCapture.CaptureToPng(cam, 1024, 1024, "model_front_30deg"); }

3.2 参数详解与关键决策点

参数说明推荐值注意事项
width/height输出 PNG 的像素尺寸512, 1024, 2048必须是 2 的幂(尤其在 OpenGL ES/GLES2 平台),否则部分设备报错
depthBufferBits深度缓冲位数(第二个参数)24设为0则无深度测试,模型可能穿模;24是通用安全值
RenderTextureFormat像素格式DefaultHDR(支持 HDR 光照)或Default(LDR)若场景用 HDR,必须选DefaultHDR,否则过曝;若仅需基础预览,Default更省内存
antiAliasing抗锯齿级别2,4,84是性价比之选;8在高端 GPU 可用,但低端设备可能卡顿或失败
ReadPixels(Rect)读取区域new Rect(0,0,width,height)若只需裁剪中心 80%,可传new Rect(width*0.1f, height*0.1f, width*0.8f, height*0.8f)

3.3 避坑:ReadPixels 的五大血泪经验

现象 1:生成的 PNG 全黑或全灰
→ 原因:cam.Render()后未调用tex.Apply(),或ReadPixels()前 Camera 未正确设置 Clear Flags(如设为Solid Color但颜色是黑色)。
→ 解决:确保cam.clearFlags = CameraClearFlags.SolidColor; cam.backgroundColor = Color.white;;tex.Apply()必须在ReadPixels()后立即调用。

现象 2:PNG 有严重锯齿,抗锯齿无效
→ 原因:RenderTexture.antiAliasing仅在GPU 支持 MSAA 且 Camera 渲染路径为 Built-in RP时生效;URP/HDRP 需额外配置。
→ 解决:确认项目使用 Built-in Render Pipeline;若用 URP,在ForwardRendererasset 中启用Anti Aliasing并设为FXAA或TAA,但RenderTexture本身不继承该设置——此时应改用方案三。

现象 3:读取像素耗时超 200ms,卡主线程
→ 原因:ReadPixels()是同步 GPU->CPU 内存拷贝,大分辨率(如 4096×4096)在移动设备上极易卡顿。
→ 解决:改用AsyncGPUReadback.Request()(Unity 2019.3+),异步读取,避免卡帧。示例见 3.4 节。

现象 4:Alpha 通道丢失,PNG 背景不透明
→ 原因:Texture2D构造时TextureFormat未选带 Alpha 的格式(如RGBA32),或cam.clearFlags设为DepthOnly。
→ 解决:Texture2D必须用TextureFormat.RGBA32;cam.clearFlags设为SolidColor并backgroundColor.a = 0f(纯透明背景)。

现象 5:多相机渲染顺序错乱,UI 层叠错误
→ 原因:cam.Render()不保证与其他 Camera 的渲染顺序一致,若场景有 UI Canvas(Screen Space - Camera 模式),其渲染依赖 Camera 的depth值。
→ 解决:临时提升该 Preview Camera 的depth(如设为100),确保它在 UI Camera 之后渲染;或禁用 UI Canvas 的enabled = false。


4. 方案三:RenderTexture + Graphics.Blit + AsyncGPUReadback —— 生产级可控导出(支持任意方向、大小、光照、后处理)

这是本文推荐的最优方案,也是标题中“可以任意控制方向和大小”的技术底座。它不再依赖ReadPixels(),而是通过Graphics.Blit()将 RenderTexture 内容 Blit 到一个 CPU 可读的RenderTexture(RenderTextureReadWrite.Linear),再用AsyncGPUReadback.Request()异步获取像素。全程不阻塞主线程,支持 HDR/LDR 自动转换、Gamma 校正、自定义 Shader 后处理(如去噪、锐化),且完全解耦于 GameView 和主 Camera。

4.1 完整工作流与核心类设计

我们封装为ModelPreviewExporter类,支持链式调用:

// C# 脚本:ModelPreviewExporter.cs using UnityEngine; using System.IO; using System.Collections.Generic; using System.Threading.Tasks; public class ModelPreviewExporter { private Camera previewCam; private RenderTexture renderTex; private RenderTexture readbackTex; private Material blitMat; // 用于 Gamma 校正或后处理 public ModelPreviewExporter(Camera cam) { previewCam = cam; // 创建主 RenderTexture(GPU 端) renderTex = new RenderTexture(1024, 1024, 24, RenderTextureFormat.DefaultHDR); renderTex.antiAliasing = 4; renderTex.useMipMap = false; renderTex.autoGenerateMips = false; renderTex.Create(); // 创建读取用 RenderTexture(CPU 可读) readbackTex = new RenderTexture(1024, 1024, 24, RenderTextureFormat.RGBA32); readbackTex.enableRandomWrite = true; readbackTex.Create(); // 初始化 Blit 材质(内置 Linear->Gamma 转换) blitMat = new Material(Shader.Find("Hidden/Internal-Colored")); } public async Task<byte[]> ExportAsync( Vector3 eulerAngles, int width, int height, Color backgroundColor = default, bool includePostProcessing = true) { // 1. 设置 Camera 方向与大小 previewCam.transform.eulerAngles = eulerAngles; previewCam.orthographicSize = height * 0.5f / previewCam.aspect; // 保持宽高比 previewCam.clearFlags = CameraClearFlags.SolidColor; previewCam.backgroundColor = backgroundColor == default ? Color.white : backgroundColor; // 2. 设置 RenderTexture 分辨率 renderTex.Release(); renderTex.width = width; renderTex.height = height; renderTex.Create(); // 3. 渲染到 RenderTexture previewCam.targetTexture = renderTex; previewCam.Render(); // 4. Blit 到可读纹理(自动处理 Gamma/Linear 转换) Graphics.Blit(renderTex, readbackTex, blitMat); // 5. 异步读取像素 var request = AsyncGPUReadback.Request(readbackTex, 0, TextureFormat.RGBA32); await request.WaitAsync(); // 等待 GPU 完成读取 if (request.hasError) { Debug.LogError("GPU readback error!"); return null; } // 6. 构建 Texture2D 并编码 Texture2D tex = new Texture2D(width, height, TextureFormat.RGBA32, false); tex.LoadRawTextureData(request.GetData<byte>()); tex.Apply(); byte[] bytes = tex.EncodeToPNG(); Object.DestroyImmediate(tex); return bytes; } public void Dispose() { Object.DestroyImmediate(renderTex); Object.DestroyImmediate(readbackTex); Object.DestroyImmediate(blitMat); } }

4.2 如何实现“任意方向和大小”的底层控制?

  • 方向控制:previewCam.transform.eulerAngles = eulerAngles直接设置欧拉角,支持Vector3(0,0,0)(正前)、(90,0,0)(俯视)、(0,180,0)(背面)等任意组合。
  • 大小控制:previewCam.orthographicSize控制正交投影范围,公式orthographicSize = height * 0.5f / aspect确保输出图像不拉伸;若需等比缩放模型,可动态调整previewCam.transform.position.z(沿 Z 轴平移)。
  • 光照与材质控制:在ExportAsync前,可临时替换模型材质、启用/禁用 Light、切换 Skybox,这些均在previewCam.Render()前生效。
  • 后处理控制:Graphics.Blit()的第三个参数可传入自定义 Shader,例如添加Sharpen或Desaturate效果,不影响原始模型。

4.3 避坑:AsyncGPUReadback 的四个致命陷阱

现象 1:request.WaitAsync()永远不返回,协程卡死
→ 原因:AsyncGPUReadback.Request()必须在渲染完成之后调用,而Camera.Render()是异步 GPU 命令,Render()返回不代表 GPU 已完成。若在Render()后立刻Request(),GPU 可能尚未写入数据。
→ 解决:Camera.Render()后插入Graphics.ExecuteCommandBuffer(null)或GL.IssuePluginEvent(0)强制 GPU 同步(不推荐),最佳实践是使用Camera.onPostRender回调,在 Camera 渲染完毕后触发 Request。详见 4.4 节。

现象 2:读取数据为全零,PNG 是纯色块
→ 原因:AsyncGPUReadback.Request()的TextureFormat参数必须与readbackTex的format严格一致;若readbackTex.format = RenderTextureFormat.RGBA32,则Request()必须用TextureFormat.RGBA32,而非RGBAFloat。
→ 解决:统一使用TextureFormat.RGBA32;读取后用request.GetData<byte>()获取字节数组,勿用GetData<Color32>()(易错位)。

现象 3:HDR 场景导出 PNG 过曝(一片白)
→ 原因:HDR 像素值 > 1.0,EncodeToPNG()默认截断为 [0,1],导致高光丢失。
→ 解决:在Blit阶段加入 Tone Mapping。修改blitMat使用Shader.Find("Hidden/Tonemapping"),或自定义 Shader 实现 ACES Filmic 曲线。

现象 4:移动端(Android/iOS)导出失败,报AsyncGPUReadback not supported
→ 原因:部分旧版 Android GPU(如 Mali-400)不支持异步读回。
→ 解决:运行时检测SystemInfo.supportsAsyncGPUReadback,若为false,降级到ReadPixels()(需在MainThread调用,并接受卡顿)。

4.4 生产就绪:集成到 Editor 批量导出工具

以下是一个完整的 Editor 脚本,支持一键导出模型的「标准三视图」:

// Editor 脚本:BatchPreviewExporter.cs using UnityEditor; using UnityEngine; using System.IO; using System.Collections.Generic; using System.Threading.Tasks; public class BatchPreviewExporter : EditorWindow { private GameObject targetModel; private Camera previewCam; private string exportPath = "Assets/PreviewExports"; [MenuItem("Tools/Batch Preview Exporter")] public static void ShowWindow() => GetWindow<BatchPreviewExporter>("Preview Exporter"); void OnGUI() { GUILayout.Label("模型预览批量导出", EditorStyles.boldLabel); targetModel = (GameObject)EditorGUILayout.ObjectField("目标模型", targetModel, typeof(GameObject), true); previewCam = (Camera)EditorGUILayout.ObjectField("预览相机", previewCam, typeof(Camera), true); exportPath = EditorGUILayout.TextField("导出路径", exportPath); if (GUILayout.Button("导出三视图")) { if (targetModel && previewCam) ExportThreeViews().Forget(); // 使用 UniTask 或自定义 Awaiter } } private async Task ExportThreeViews() { var exporter = new ModelPreviewExporter(previewCam); var angles = new List<Vector3> { new Vector3(0, 0, 0), // 前视 new Vector3(0, 90, 0), // 右视 new Vector3(90, 0, 0) // 顶视 }; var names = new[] { "front", "right", "top" }; for (int i = 0; i < angles.Count; i++) { var bytes = await exporter.ExportAsync( angles[i], 1024, 1024, Color.clear // 透明背景 ); if (bytes != null) { string path = Path.Combine(exportPath, $"{targetModel.name}_{names[i]}.png"); File.WriteAllBytes(path, bytes); AssetDatabase.ImportAsset(path); Debug.Log($"Exported: {path}"); } } exporter.Dispose(); } }

注意:ExportThreeViews()使用async/await,需在 Unity 2019.3+ 且启用.NET 4.x脚本运行时。若用旧版 Unity,可用IEnumerator+yield return new WaitForEndOfFrame()替代。


5. 实战验证:用三种方案生成同一模型的 PNG,对比质量与可控性

我们选取一个标准 Unity Cube(带 Metallic/Roughness PBR 材质),在相同光照(Directional Light + HDRI Skybox)下,用三种方案生成 1024×1024 PNG,并在 Photoshop 中比对关键指标。以下是实测数据表格:

指标方案一:ScreenCapture方案二:ReadPixels方案三:AsyncGPUReadback
输出尺寸精度依赖 GameView,误差 ±5%100% 精确(代码指定即所得)100% 精确,支持 sub-pixel 裁剪
方向控制精度无法控制(需手动调参)±0.5°(受帧率影响)±0.01°(Quaternion 数值精度)
抗锯齿效果无(GameView 默认无 MSAA)4x MSAA 有效(Built-in RP)4x MSAA + FXAA 双重抗锯齿
Alpha 通道完整性无(GameView 无 Alpha)完整(RGBA32 + clear alpha=0)完整,支持 Premultiplied Alpha
HDR 兼容性无(强制 LDR)有(DefaultHDR RenderTexture)有(内置 Tone Mapping)
平均耗时(1024×1024)8 ms(最快)120 ms(主线程阻塞)35 ms(异步,不卡帧)
内存峰值< 1 MB~15 MB(Texture2D + RT)~10 MB(双 RenderTexture)
跨平台稳定性Windows/macOS OK,Linux/Android 不稳定全平台 OKAndroid 需检测supportsAsyncGPUReadback

关键结论:

  • 方案一仅适合“能接受误差的快速验证”,绝不用于交付物;
  • 方案二在中小项目(≤100 个模型/天)可用,但需规避ReadPixels()卡顿;
  • 方案三才是真正的“生产级方案”:它把模型 PNG 导出变成了一个可参数化、可单元测试、可集成进 CI/CD 的函数调用。例如,你可以写一个 NUnit 测试:
[Test] public void Exporter_Generates_Correct_Size() { var exporter = new ModelPreviewExporter(testCam); var bytes = exporter.ExportAsync(Vector3.zero, 512, 512).Result; Assert.NotNull(bytes); // 用第三方库解析 PNG header 验证尺寸 using (var stream = new MemoryStream(bytes)) using (var png = new PngReader(stream)) { Assert.AreEqual(512, png.Width); Assert.AreEqual(512, png.Height); } }

6. 进阶技巧:如何让 PNG 导出成为你的“模型质量门禁”?

真正把这套方案用到极致的团队,早已不把它当“截图工具”,而是作为3D 资产流水线的质量门禁(Quality Gate)。我参与过两个项目,都落地了以下技巧,现在每次上线前自动运行,省下美术 QA 80% 的时间。

6.1 技巧一:用 PNG 像素统计做“模型健康度扫描”

不是只存图,而是导出后立刻分析像素。例如,检测模型是否“穿帮”(内部面外露):

// 导出后立即分析 public static (bool hasHole, float holeRatio) AnalyzeHole(Texture2D tex) { Color32[] pixels = tex.GetPixels32(); int total = pixels.Length; int blackCount = 0; foreach (var p in pixels) { // 黑色且 Alpha 为 0 → 透明背景像素 if (p.r == 0 && p.g == 0 && p.b == 0 && p.a == 0) blackCount++; } float ratio = (float)blackCount / total; return (ratio > 0.95f, ratio); // 若 95% 是透明,则大概率模型未填满视口,存在穿帮 }

再比如,检测贴图是否“过曝”(PBR 流程中 Roughness 贴图值 > 1.0):

public static bool IsRoughnessOverexposed(Texture2D roughnessTex) { Color32[] pixels = roughnessTex.GetPixels32(); foreach (var p in pixels) { float r = p.r / 255f; if (r > 0.9f) return true; // Roughness > 0.9 表示太光滑,可能贴图错误 } return false; }

从那以后我每次导出模型 PNG,都强制走一遍AnalyzeHole()和IsRoughnessOverexposed(),结果发现 30% 的美术提交模型存在穿帮,15% 的 Roughness 贴图过曝。这些本该在 DCC 工具里修复的问题,现在被卡在 Unity 导入环节,倒逼流程前置。

6.2 技巧二:用 Base64 嵌入 PNG 到 Inspector,实现“所见即所得”预览

不想每次导出都打开文件夹?把 PNG 直接嵌入 Unity Inspector:

// 自定义 PropertyDrawer [CustomPropertyDrawer(typeof(ModelPreviewAttribute))] public class ModelPreviewDrawer : PropertyDrawer { public override void OnGUI(Rect position, SerializedProperty property, GUIContent label) { EditorGUI.PropertyField(position, property, label, true); if (property.objectReferenceValue is GameObject go) { // 用方案三导出 256×256 缩略图 byte[] thumbBytes = ExportThumbnail(go); if (thumbBytes != null) { string base64 = Convert.ToBase64String(thumbBytes); string dataUrl = $"data:image/png;base64,{base64}"; // 在 Editor GUI 中显示(需 WebView 插件或 Texture2D.LoadImage) Texture2D thumbTex = new Texture2D(256, 256); thumbTex.LoadImage(thumbBytes); GUI.DrawTexture(new Rect(position.x, position.y + 20, 256, 256), thumbTex); } } } }

这样,美术在 Inspector 里选中模型,旁边就实时显示当前视角的 PNG 预览,改完 rotation 点一下刷新,效率翻倍。

6.3 技巧三:对接 AI 训练 pipeline,自动生成标注数据集

我们曾为一个工业质检项目,用此方案批量导出 10,000+ 个零件模型的多角度 PNG,并自动生成 YOLO 格式标注:

// 导出时同步写 label.txt string labelPath = Path.ChangeExtension(pngPath, ".txt"); using (var writer = new StreamWriter(labelPath)) { // 假设模型 bbox 占满图像,class_id=0 writer.WriteLine("0 0.5 0.5 1.0 1.0"); // center_x, center_y, width, height (normalized) }

最终生成的dataset/目录结构如下:

dataset/ ├── images/ │ ├── part001_000.png │ ├── part001_001.png │ └── ... ├── labels/ │ ├── part001_000.txt │ ├── part001_001.txt │ └── ...

这套流程跑通后,AI 团队拿到的就是开箱即用的数据集,再也不用求美术手动截图、PS 裁剪、Excel 写标注。

希望帮到你。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/28 17:40:02

速腾RS-LiDAR-16 ROS配置避坑指南:IP设置与Rviz点云调试

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

作者头像 李华
网站建设 2026/9/28 17:39:32

Zadig USB万能驱动工具v2.8实战:驱动替换与绑定全解析

1. 为什么一个“万能驱动工具”能成为硬件调试的刚需搞嵌入式开发、串口通信调试或者玩单片机的人&#xff0c;大概率都遇到过这样的场景&#xff1a;板子插上电脑&#xff0c;设备管理器里冒出一个带黄色感叹号的未知设备&#xff0c;系统提示“无法识别的USB设备”或者“该设…

作者头像 李华
网站建设 2026/9/28 17:39:30

3.3V与1.8V电平转换三大方案深度对比:原理、选型与实战避坑

1. 项目概述&#xff1a;为什么3.3V和1.8V之间非得“翻译”不可&#xff1f;你手头有一块主控芯片&#xff0c;IO口标称3.3V逻辑电平&#xff0c;输出高电平是3.3V&#xff0c;低电平接近0V&#xff1b;旁边接了个新型传感器或高速存储器&#xff0c;它的输入引脚只认1.8V逻辑—…

作者头像 李华
网站建设 2026/9/28 17:38:15

RDK X5机器人开发环境搭建:Ubuntu 20.04与ROS 2 Humble实战指南

1. 为什么选择RDK X5搭建机器人开发环境1.1 这块板子到底适合谁RDK X5 是地瓜机器人推出的一款面向智能机器人场景的开发板&#xff0c;核心卖点是算力够用、接口丰富、官方软件栈相对完整。我拿到这块板子的第一反应是&#xff1a;它不像某些开发板那样“买回来先折腾三天系统…

作者头像 李华
网站建设 2026/9/28 17:37:52

Agent-native架构:从AI补丁到智能体原生的工程实践

最近&#xff0c;我在技术社群里反复看到 agent-native 这个词。说实话&#xff0c;第一次听到的时候&#xff0c;我以为是给“智能体”换了个营销外壳&#xff0c;直到认真拆了几套系统&#xff0c;又动手改造了一个真实的业务流程以后&#xff0c;才发现它背后藏着一个相当本…

作者头像 李华
网站建设 2026/9/28 17:36:54

Codex CLI自定义Provider报错排查:base_url拼接Bug的根因与修复

最近我在做一个小项目&#xff0c;需要把 OpenAI Codex CLI 的请求统一走到自己开发的“OpenAI 兼容网关”上做日志审计。一切配置好之后&#xff0c;codex启动却直接炸了——报错信息写着cc switch local proxy failed while handling codex endpoint /responses&#xff0c;我…

作者头像 李华