news 2026/9/5 12:03:09

Codex+tldraw+Three.js:AI草图生成3D地球应用开发实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Codex+tldraw+Three.js:AI草图生成3D地球应用开发实践

如果你还在用传统方式写 3D 应用,一行行敲 Three.js 代码,那么 Codex + tldraw 的组合可能会让你重新思考开发流程。最近,一个简单的技术演示在开发者社区引发关注:在 tldraw 画布上画个草图,用自然语言描述需求,Codex 就能生成完整的 3D 地球应用。这不仅仅是"又一个 AI 代码生成demo",而是展示了 AI 如何改变前端 3D 开发的交互范式。

传统 3D 开发需要掌握复杂的图形学概念和 API,而 Codex 理解自然语言指令后,直接生成可运行的代码。更关键的是,tldraw 作为交互媒介,让草图成为 AI 理解需求的视觉上下文。这种"草图+语言"的混合输入方式,比纯文本提示词更精准,特别适合空间和视觉类应用的快速原型开发。

本文将带你完整实现这个流程:从环境搭建到草图绘制,从自然语言指令到 3D 地球应用生成,最后深入分析这种开发模式的实际价值和使用边界。无论你是前端开发者想了解 AI 辅助编程,还是对 3D 可视化感兴趣,都能获得可直接复用的实践方案。

1. 为什么 Codex + tldraw 值得关注:重新定义 3D 应用原型开发

在讨论具体实现前,我们需要理解这个组合解决的真正痛点。3D 应用开发历来门槛较高,开发者需要同时掌握三维数学、图形 API、着色器编程等多领域知识。即使使用 Three.js 这类封装较好的库,创建一个简单的 3D 场景仍然需要大量样板代码。

Codex 的价值在于它理解编程上下文的能力。当你说"创建一个旋转的地球,有云层效果和星空背景",它能生成结构完整的 Three.js 代码,包括场景初始化、相机设置、光照配置、纹理加载和动画循环。这不仅仅是代码补全,而是从需求到实现的跨越。

tldraw 的作用则提供了视觉上下文。单纯靠文字描述 3D 场景容易产生歧义——"地球稍微倾斜"到底倾斜多少度?在画布上简单画个倾斜的椭圆,AI 就能理解你的视觉意图。这种多模态输入大大降低了沟通成本。

实际开发中,这种模式最适合两类场景:

  • 快速原型验证:产品经理或设计师用草图表达想法,开发者用自然语言补充细节,立即看到可交互的 3D 原型
  • 教育演示制作:教师需要创建物理现象、地理概念的 3D 演示,无需编码背景也能生成专业可视化

但需要注意,当前技术更适合原型阶段。复杂的光照模型、性能优化、跨浏览器兼容等工程问题,仍需要开发者介入处理。

2. 核心工具链解析:Codex、tldraw 与 Three.js 的协同原理

2.1 Codex:不只是代码生成器

Codex 基于 GPT 模型训练,专门针对编程任务优化。与通用聊天机器人不同,Codex 理解编程语言的语法结构、API 使用模式和项目上下文。当处理 3D 开发任务时,它能准确选择 Three.js 的合适组件,比如知道地球模型应该用SphereGeometry而不是BoxGeometry

更重要的是,Codex 具备一定的推理能力。当你说"添加围绕地球旋转的月亮",它能理解需要创建另一个球体,设置合适的轨道参数和父子关系。这种逻辑推理超越了简单的模板填充。

2.2 tldraw:从草图到结构化数据

tldraw 的核心价值在于将自由形式的草图转化为机器可理解的结构化数据。当你画一个地球草图时,tldraw 不仅记录像素点,还识别出基本几何属性:位置、大小、旋转角度、颜色填充等。

这些数据通过 JSON 格式传递给 Codex,成为生成代码的视觉约束。比如草图地球的倾斜角度直接转化为 Three.js 中模型的rotation.x值,实现了"所见即所得"的代码生成。

2.3 Three.js:3D 渲染的基石

Three.js 提供了完整的 WebGL 封装,让浏览器中的 3D 渲染变得可行。Codex 生成的代码通常包含以下核心组件:

  • 场景图管理:物体间的层级关系和变换
  • 材质系统:定义物体外观,包括颜色、纹理、反光特性
  • 光照模型:环境光、方向光、点光源的配置
  • 动画循环:使用requestAnimationFrame实现平滑动画

理解这三个工具的分工协作,是后续实现的基础。

3. 环境准备与工具配置

3.1 开发环境要求

确保你的系统满足以下条件:

  • Node.js 16.0 或更高版本
  • npm 或 yarn 包管理器
  • 现代浏览器(Chrome 90+、Firefox 88+、Safari 14+)
  • 稳定的网络连接(用于调用 Codex API)

3.2 项目初始化

创建新项目并安装依赖:

# 创建项目目录 mkdir codex-tldraw-3d cd codex-tldraw-3d # 初始化 package.json npm init -y # 安装核心依赖 npm install tldraw@2.0.0 three@0.150.0 npm install --save-dev vite@4.0.0 @types/three@0.150.0

3.3 Codex API 配置

要使用 Codex,你需要获取 OpenAI API 密钥:

  1. 访问 OpenAI 平台(https://platform.openai.com)
  2. 注册账号并完成验证
  3. 在 API Keys 页面生成新密钥
  4. 在项目中创建配置文件:
// config.js export const OPENAI_API_KEY = '你的API密钥'; export const OPENAI_API_URL = 'https://api.openai.com/v1/completions';

重要安全提醒:永远不要将 API 密钥提交到版本控制系统。使用环境变量或配置文件,并在.gitignore中排除敏感信息。

3.4 项目结构规划

建立清晰的项目结构有助于后续开发:

codex-tldraw-3d/ ├── index.html # 主页面 ├── src/ │ ├── main.js # 应用入口 │ ├── tldraw-wrapper.js # tldraw 封装 │ ├── codex-client.js # Codex API 客户端 │ ├── three-renderer.js # Three.js 渲染器 │ └── styles.css # 样式文件 ├── config.js # 配置文件 └── package.json

4. 核心实现流程拆解

4.1 tldraw 画布集成

首先创建基础的 tldraw 画布界面:

<!-- index.html --> <!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Codex + tldraw 3D 应用生成器</title> <link rel="stylesheet" href="./src/styles.css"> </head> <body> <div class="container"> <div class="control-panel"> <h1>3D 地球应用生成器</h1> <div class="input-group"> <textarea id="promptInput" placeholder="描述你想要的 3D 地球效果..."></textarea> <button id="generateBtn">生成 3D 应用</button> </div> </div> <div class="canvas-container"> <div id="tldraw-canvas"></div> </div> <div class="preview-container"> <div id="three-preview"></div> </div> </div> <script type="module" src="./src/main.js"></script> </body> </html>
// src/tldraw-wrapper.js import { createTLDraw } from 'tldraw'; export class TLDrawWrapper { constructor(containerId) { this.container = document.getElementById(containerId); this.app = null; this.init(); } init() { this.app = createTLDraw({ container: this.container, options: { tools: ['select', 'draw', 'erase', 'rectangle', 'ellipse'], grid: true, snapToGrid: true } }); } // 获取画布数据作为视觉上下文 getCanvasData() { if (!this.app) return null; const shapes = this.app.getShapes(); const viewport = this.app.getViewport(); return { shapes: shapes.map(shape => ({ type: shape.type, rotation: shape.rotation, point: shape.point, size: shape.size, style: shape.style })), viewport: { zoom: viewport.zoom, point: viewport.point } }; } // 清空画布 clearCanvas() { if (this.app) { this.app.clear(); } } }

4.2 Codex 客户端实现

创建与 OpenAI API 交互的客户端:

// src/codex-client.js import { OPENAI_API_KEY, OPENAI_API_URL } from '../config.js'; export class CodexClient { constructor() { this.apiKey = OPENAI_API_KEY; this.baseURL = OPENAI_API_URL; } async generateThreeJSCode(prompt, canvasData = null) { // 构建完整的提示词,包含画布上下文 const fullPrompt = this.buildPrompt(prompt, canvasData); const response = await fetch(this.baseURL, { method: 'POST', headers: { 'Content-Type': 'application/json', 'Authorization': `Bearer ${this.apiKey}` }, body: JSON.stringify({ model: 'code-davinci-002', prompt: fullPrompt, max_tokens: 1500, temperature: 0.7, stop: ['// 结束', '/* 结束 */'] }) }); if (!response.ok) { throw new Error(`API 请求失败: ${response.status}`); } const data = await response.json(); return data.choices[0].text.trim(); } buildPrompt(userPrompt, canvasData) { let prompt = `生成一个 Three.js 3D 地球应用,要求:${userPrompt}\n\n`; if (canvasData && canvasData.shapes.length > 0) { prompt += "画布上下文信息:\n"; canvasData.shapes.forEach((shape, index) => { prompt += `形状 ${index + 1}: 类型=${shape.type}, 旋转=${shape.rotation}, 位置=${JSON.stringify(shape.point)}\n`; }); } prompt += "\n生成完整的 HTML 文件,包含以下部分:\n"; prompt += "1. Three.js 场景初始化\n"; prompt += "2. 相机和渲染器设置\n"; prompt += "3. 地球几何体和材质\n"; prompt += "4. 光照设置\n"; prompt += "5. 动画循环\n"; prompt += "6. 响应式布局\n\n"; prompt += "代码:\n`; return prompt; } }

4.3 Three.js 渲染器封装

创建用于预览生成结果的渲染器:

// src/three-renderer.js import * as THREE from 'three'; export class ThreeRenderer { constructor(containerId) { this.container = document.getElementById(containerId); this.scene = null; this.camera = null; this.renderer = null; this.earth = null; this.animationId = null; this.init(); } init() { // 创建场景 this.scene = new THREE.Scene(); this.scene.background = new THREE.Color(0x000033); // 创建相机 this.camera = new THREE.PerspectiveCamera( 75, this.container.clientWidth / this.container.clientHeight, 0.1, 1000 ); this.camera.position.z = 5; // 创建渲染器 this.renderer = new THREE.WebGLRenderer({ antialias: true }); this.renderer.setSize( this.container.clientWidth, this.container.clientHeight ); this.renderer.shadowMap.enabled = true; this.renderer.shadowMap.type = THREE.PCFSoftShadowMap; this.container.appendChild(this.renderer.domElement); // 添加基础光照 this.setupBasicLighting(); // 处理窗口大小变化 window.addEventListener('resize', () => this.onWindowResize()); } setupBasicLighting() { // 环境光 const ambientLight = new THREE.AmbientLight(0x404040, 0.6); this.scene.add(ambientLight); // 方向光 const directionalLight = new THREE.DirectionalLight(0xffffff, 0.8); directionalLight.position.set(5, 3, 5); directionalLight.castShadow = true; this.scene.add(directionalLight); } // 执行生成的代码 executeGeneratedCode(code) { try { // 清空现有场景 this.clearScene(); // 创建执行环境 const context = { THREE: THREE, scene: this.scene, camera: this.camera, renderer: this.renderer, container: this.container, earth: null }; // 包装代码为函数 const wrappedCode = ` (function(THREE, scene, camera, renderer, container) { ${code} }) `; const codeFunction = eval(wrappedCode); codeFunction( context.THREE, context.scene, context.camera, context.renderer, context.container ); // 启动动画循环 this.startAnimation(); } catch (error) { console.error('代码执行错误:', error); throw new Error(`生成的代码存在错误: ${error.message}`); } } clearScene() { // 停止当前动画 if (this.animationId) { cancelAnimationFrame(this.animationId); } // 移除所有物体 while (this.scene.children.length > 0) { const child = this.scene.children[0]; if (child.geometry) child.geometry.dispose(); if (child.material) { if (Array.isArray(child.material)) { child.material.forEach(material => material.dispose()); } else { child.material.dispose(); } } this.scene.remove(child); } // 重新添加基础光照 this.setupBasicLighting(); } startAnimation() { const animate = () => { this.animationId = requestAnimationFrame(animate); this.renderer.render(this.scene, this.camera); }; animate(); } onWindowResize() { this.camera.aspect = this.container.clientWidth / this.container.clientHeight; this.camera.updateProjectionMatrix(); this.renderer.setSize( this.container.clientWidth, this.container.clientHeight ); } // 销毁资源 dispose() { this.clearScene(); if (this.renderer) { this.renderer.dispose(); } } }

4.4 主应用集成

将各个模块整合到主应用中:

// src/main.js import { TLDrawWrapper } from './tldraw-wrapper.js'; import { CodexClient } from './codex-client.js'; import { ThreeRenderer } from './three-renderer.js'; class App { constructor() { this.tldraw = null; this.codexClient = null; this.threeRenderer = null; this.isGenerating = false; this.init(); } init() { // 初始化组件 this.tldraw = new TLDrawWrapper('tldraw-canvas'); this.codexClient = new CodexClient(); this.threeRenderer = new ThreeRenderer('three-preview'); // 绑定事件 this.bindEvents(); console.log('应用初始化完成'); } bindEvents() { const generateBtn = document.getElementById('generateBtn'); const promptInput = document.getElementById('promptInput'); generateBtn.addEventListener('click', () => this.handleGenerate()); promptInput.addEventListener('keypress', (e) => { if (e.key === 'Enter' && e.ctrlKey) { this.handleGenerate(); } }); } async handleGenerate() { if (this.isGenerating) return; const promptInput = document.getElementById('promptInput'); const prompt = promptInput.value.trim(); if (!prompt) { alert('请输入描述信息'); return; } this.isGenerating = true; this.updateUIState('generating'); try { // 获取画布数据 const canvasData = this.tldraw.getCanvasData(); // 调用 Codex 生成代码 const generatedCode = await this.codexClient.generateThreeJSCode(prompt, canvasData); // 执行生成的代码 await this.threeRenderer.executeGeneratedCode(generatedCode); this.updateUIState('success'); } catch (error) { console.error('生成失败:', error); this.updateUIState('error', error.message); } finally { this.isGenerating = false; } } updateUIState(state, errorMessage = '') { const generateBtn = document.getElementById('generateBtn'); switch (state) { case 'generating': generateBtn.textContent = '生成中...'; generateBtn.disabled = true; break; case 'success': generateBtn.textContent = '生成成功!'; generateBtn.disabled = false; setTimeout(() => { generateBtn.textContent = '生成 3D 应用'; }, 2000); break; case 'error': generateBtn.textContent = '生成失败'; generateBtn.disabled = false; alert(`生成错误: ${errorMessage}`); setTimeout(() => { generateBtn.textContent = '生成 3D 应用'; }, 2000); break; } } } // 启动应用 new App();

5. 完整示例:从草图到 3D 地球应用

5.1 基础地球生成示例

让我们测试一个完整的流程。首先在 tldraw 画布上画一个简单的圆形代表地球,然后在文本框中输入:

创建一个美丽的 3D 地球,要有云层效果,在太空中缓慢旋转,添加星空背景

Codex 可能会生成类似以下的代码:

// 生成的 Three.js 代码示例 const scene = new THREE.Scene(); // 创建星空背景 const starGeometry = new THREE.BufferGeometry(); const starPositions = []; for (let i = 0; i < 10000; i++) { const x = (Math.random() - 0.5) * 2000; const y = (Math.random() - 0.5) * 2000; const z = (Math.random() - 0.5) * 2000; starPositions.push(x, y, z); } starGeometry.setAttribute('position', new THREE.Float32BufferAttribute(starPositions, 3)); const starMaterial = new THREE.PointsMaterial({ color: 0xffffff, size: 1 }); const stars = new THREE.Points(starGeometry, starMaterial); scene.add(stars); // 创建地球 const earthGeometry = new THREE.SphereGeometry(2, 32, 32); const earthTexture = new THREE.TextureLoader().load('https://example.com/earth.jpg'); const earthMaterial = new THREE.MeshPhongMaterial({ map: earthTexture }); const earth = new THREE.Mesh(earthGeometry, earthMaterial); scene.add(earth); // 创建云层 const cloudGeometry = new THREE.SphereGeometry(2.05, 32, 32); const cloudTexture = new THREE.TextureLoader().load('https://example.com/clouds.jpg'); const cloudMaterial = new THREE.MeshPhongMaterial({ map: cloudTexture, transparent: true, opacity: 0.4 }); const clouds = new THREE.Mesh(cloudGeometry, cloudMaterial); scene.add(clouds); // 动画循环 function animate() { requestAnimationFrame(animate); earth.rotation.y += 0.001; clouds.rotation.y += 0.0015; renderer.render(scene, camera); } animate();

5.2 高级特性:交互式地球

尝试更复杂的提示词:

创建一个交互式地球,可以用鼠标拖动旋转,滚轮缩放,点击国家显示名称。添加昼夜交替效果和天气动画。

生成的代码会增加交互控制和高级特效:

// 交互控制部分 const controls = new THREE.OrbitControls(camera, renderer.domElement); controls.enableDamping = true; controls.dampingFactor = 0.05; // 昼夜交替效果 const sunLight = new THREE.DirectionalLight(0xffffff, 1.5); sunLight.position.set(5, 3, 5); scene.add(sunLight); let timeOfDay = 0; function updateDayNightCycle() { timeOfDay += 0.001; const sunX = Math.cos(timeOfDay) * 10; const sunY = Math.sin(timeOfDay) * 5; const sunZ = Math.sin(timeOfDay) * 10; sunLight.position.set(sunX, sunY, sunZ); // 根据太阳位置调整环境光强度 const ambientIntensity = Math.max(0.1, Math.abs(Math.sin(timeOfDay)) * 0.4); scene.background = new THREE.Color(ambientIntensity * 0.1, ambientIntensity * 0.1, ambientIntensity * 0.3); }

6. 运行验证与效果测试

6.1 启动开发服务器

使用 Vite 启动开发服务器:

npm run dev

访问 http://localhost:3000 查看应用界面。

6.2 功能测试流程

按照以下步骤验证完整功能:

  1. 画布绘制测试:在 tldraw 画布上绘制各种形状,验证数据获取是否正确
  2. 基础生成测试:输入简单提示词(如"创建地球"),检查是否能生成基本 3D 场景
  3. 复杂需求测试:输入详细描述,验证生成代码的完整性和复杂性
  4. 交互功能测试:测试鼠标控制、动画效果等交互特性
  5. 性能测试:检查帧率是否稳定,内存使用是否合理

6.3 预期输出验证

成功运行时应该看到:

  • tldraw 画布响应绘制操作
  • 生成按钮点击后显示"生成中"状态
  • 3D 预览区域显示旋转的地球模型
  • 控制台无错误日志
  • 页面帧率保持在 60fps 左右

7. 常见问题与排查指南

问题现象可能原因排查方式解决方案
画布无法绘制tldraw 初始化失败检查浏览器控制台错误确认 tldraw 版本兼容性,检查容器元素是否存在
API 调用失败网络问题或密钥错误查看网络请求状态验证 API 密钥,检查网络连接,确认额度充足
3D 场景黑屏Three.js 初始化问题检查 WebGL 支持更新显卡驱动,尝试不同浏览器
生成代码语法错误Codex 输出格式问题查看生成代码内容调整提示词明确性,添加代码格式要求
动画卡顿性能问题监控帧率和内存使用优化几何体复杂度,减少实时阴影计算
纹理加载失败图片路径错误检查网络请求使用本地纹理或可靠 CDN 资源

7.1 详细排查步骤

问题:生成的代码无法执行

排查流程:

  1. 打开浏览器开发者工具(F12)
  2. 查看 Console 标签页的错误信息
  3. 检查错误发生的具体行数
  4. 查看生成的代码是否存在语法错误
  5. 验证 Three.js 对象和方法是否存在

问题:画布数据未正确传递

排查流程:

  1. getCanvasData()方法中添加日志输出
  2. 确认画布数据格式符合预期
  3. 检查数据序列化过程是否丢失信息
  4. 验证提示词构建逻辑是否正确使用画布数据

8. 最佳实践与工程建议

8.1 提示词工程优化

有效的提示词应该包含:

  • 明确的目标:具体描述想要的 3D 效果
  • 技术约束:指定使用的库和版本
  • 性能要求:说明目标平台和性能预期
  • 代码风格:要求清晰的注释和结构

好的提示词示例

使用 Three.js 0.150.0 创建一个性能优化的地球模型。 要求: - 使用 SphereGeometry 和纹理贴图 - 添加平滑的旋转动画 - 支持响应式布局 - 代码要有详细注释 - 避免使用已弃用的 API

8.2 性能优化策略

生成的 3D 应用应该考虑性能:

  • 几何体优化:使用合适的细分程度,避免过多顶点
  • 纹理压缩:使用适当分辨率的纹理,考虑压缩格式
  • 动画效率:使用requestAnimationFrame,避免频繁对象创建
  • 内存管理:及时销毁不再使用的几何体和材质

8.3 错误处理与回退机制

生产环境需要考虑健壮性:

// 安全的代码执行封装 async function safeExecuteCode(code, maxRetries = 3) { for (let attempt = 1; attempt <= maxRetries; attempt++) { try { return await executeGeneratedCode(code); } catch (error) { console.warn(`执行失败 (尝试 ${attempt}/${maxRetries}):`, error); if (attempt === maxRetries) { // 最后一次尝试失败,使用回退方案 return await loadFallbackScene(); } // 简单的代码修复尝试 code = attemptCodeFix(code, error); } } }

8.4 安全注意事项

  • API 密钥保护:永远不要在前端代码中硬编码密钥
  • 代码沙箱:考虑使用 Web Workers 或沙箱执行生成代码
  • 输入验证:对用户输入进行严格的验证和转义
  • 资源限制:限制生成代码的复杂度和执行时间

9. 实际应用场景与扩展方向

9.1 教育领域的应用

这种技术特别适合创建交互式教学材料:

  • 地理教育:动态展示地球构造、板块运动
  • 天文教学:模拟太阳系运行、星座变化
  • 物理实验:可视化力学原理、波动现象

9.2 产品设计与原型开发

设计师可以快速创建 3D 产品原型:

  • 建筑可视化:生成建筑模型和环境效果
  • 工业设计:创建产品 3D 展示和交互演示
  • 游戏原型:快速验证游戏场景和机制

9.3 技术扩展可能性

基于这个基础,可以进一步扩展:

  • 多模型支持:集成更多 3D 格式和渲染引擎
  • 实时协作:多人同时编辑画布和查看结果
  • 模板系统:预定义常用组件和效果模板
  • 版本管理:保存和对比不同版本的生成结果

这个项目展示了 AI 辅助编程在 3D 开发领域的巨大潜力。虽然当前技术还有局限,但已经能够显著降低 3D 应用开发的门槛。随着 AI 模型的不断进化,这种"描述即生成"的开发模式可能会成为前端开发的新标准。

建议在实际项目中从小范围开始试用,逐步积累使用经验。重点关注提示词优化、错误处理和性能调优,让 AI 真正成为提升开发效率的助力而非负担。

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

五合一代付系统源码解析:架构、技术与合规风险

简介&#xff1a;这是一套面向开发者与技术团队的五合一电商代付系统源码&#xff0c;专为美团外卖、京东、拼多多、携程及滴滴平台定制&#xff0c;解决多平台代付接口统一接入与前端品牌化展示需求&#xff0c;适用于有Node.js与React开发经验的技术人员进行二次开发或私有化…

作者头像 李华
网站建设 2026/9/5 11:55:43

Delphi图表控件TeeChart Pro源码解析:从安装到高级定制

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

作者头像 李华
网站建设 2026/9/5 11:54:40

医学影像AI实战:基于注意力机制的CT与超声多模态融合分类模型

简介&#xff1a;本资源是一项面向医学影像AI研究者与临床辅助诊断开发者的技术实践项目&#xff0c;聚焦卵巢癌CT与超声双模态影像的分类建模与融合策略验证&#xff0c;旨在探索最优深度学习架构以提升早期诊断准确率。资源包共73个文件&#xff0c;包含51张标注PNG/3张JPG医…

作者头像 李华
网站建设 2026/9/5 11:54:38

从高斯消元到LU分解:理解线性代数计算的工程核心

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

作者头像 李华
网站建设 2026/9/5 11:54:34

输电线路螺栓销钉缺失检测:专用数据集构建与YOLO模型实战指南

简介&#xff1a;本资源是面向电力行业智能巡检与计算机视觉算法工程师的输电线路螺栓销钉缺失检测专用图像数据集&#xff0c;聚焦于高危设施中细小部件异常状态的自动化识别问题&#xff0c;适用于目标检测模型训练、电力AI运维系统开发及高校电力AI交叉课题研究。数据包共20…

作者头像 李华
网站建设 2026/9/5 11:54:07

模型自动压缩实战:从量化剪枝到BERT优化部署全流程解析

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

作者头像 李华