2026年2月

JWT编码/解码 在线工具分享

哈喽大家好,今天给大家安利一个我最近用 Vue 手搓的在线工具——JWT编码/解码器

做开发的同学应该都知道 JWT(JSON Web Token),现在前后端分离项目里用得特别多。但有时候调试接口、排查问题,手里没个顺手的工具,解析个 Token 还得去找在线网站,挺麻烦的。

所以我就想,干脆自己做一个网页版的,打开就能用,还不用安装。

在线工具网址:https://see-tool.com/jwt-encryptor
工具截图:

这个工具有啥特别的?

1. 一眼看懂 Token 结构

JWT 是由三部分组成的,用点号隔开。这个工具会自动把 Header、Payload、Signature 分开显示,还用不同颜色标出来,一眼就能看明白哪个部分是啥。

2. 支持多种算法

不止是最常用的 HS256,像 RS256、PS256、ES256 这些非对称加密算法也都支持。不管你用的是对称密钥还是 RSA/ECDSA 密钥对,都能帮你编码和验证签名。

3. 签名验证超方便

想确认 Token 是不是被篡改过?只要勾选"验证签名",输入密钥,立马就能告诉你签名是否有效。再也不用写代码去验证了,调试效率翻倍。

4. 示例一键加载

刚上手不知道怎么用?没关系,我准备了现成的示例,点一下"加载示例"按钮,立马给你填好一个完整的 Token 和密钥,跟着看一遍就会了。

碎碎念

这个小工具是我用 Vue 3 做的,核心的 JWT 处理逻辑是自己手写的,还用到了 Web Crypto API 来做 RSA 和 ECDSA 的签名验证。所有操作都在你的浏览器里完成,密钥不会上传到服务器,安全又放心。

虽然它可能没有那些专业工具那么多功能,但胜在轻便、干净。

如果你平时开发调试刚好缺这么一个顺手的小工具,欢迎来试试看!要是觉得好用,或者有什么想吐槽的,也欢迎随时告诉我哈~

二刷《花束般的恋爱》读懂了一些细节和伏笔:

  • 剧情开始时,有一对情侣在用同一副耳机的左右耳听歌,主人公想上去纠正。剧中也解答了即使是同一首歌,左右耳听到的东西也是完全不同的。我觉得这部分暗示同处一段恋爱中的两个人就像一首歌的左右声道,有着不一样的感受,不一样的体验。
  • 标题《花束般的恋爱》我觉得这个中文译名特别好,他暗示了剧中两个人的关系,由最开始的鲜艳灿烂到后面的干枯凋落,犹如花束一般。
  • 剧中男主一直在追求更好的未来,没有经营好当下。我觉得这个是我们每个人都有幻觉,觉得现在苦苦没关系,未来一片光明,可惜很多人的生活没能“活到”未来。
  • 或许“门当户对”真的是一种智慧,至少门不当户不对的时候应该对齐一下价值观。
  • 有什么很重要但不好说的事情,暗示一次就行了,没懂就挑明了说。剧中女主总是暗示男主自己很不开心,但是从来没有和男主开门见山说过。

tips:

以上是个人观后的一些拙见,《花束般的恋爱》真的是一部很好看,细节满满的电影,强烈推荐各位去看看!

新的一年即将开始,愿有情人终成眷属,愿各位按时吃饭,平安喜乐。

Model Context Protocol 是一个开放标准,它的目标是给 LLM 一种干净、统一的方式去发现和调用外部工具。不用再写自定义解析、不用再维护脆弱的胶水代码,就是一个好用的协议。

大多数 MCP 教程上来就讲 JSON-RPC 规范、传输层协议,搞得很复杂。其实用 MCP 不需要理解协议内部构造就像写 Web 应用不需要去读 HTTP 规范一样。

真正需要掌握的东西就三个概念,花 15 分钟就够了。

三个核心概念

MCP 的核心就三样东西:

Server:对外暴露工具的服务端,本质上是一个 Python 脚本,声明"这些函数可以被 LLM 调用",跑起来之后就在监听请求。

Tool:希望 LLM 使用的函数,可以是任何东西:查天气、查数据库、发邮件。这跟写普通 Python 函数没什么区别,加个装饰器剩下的交给 MCP。

Client:连接 Server 并调用工具的客户端。生产环境里一般就是 LLM 应用本身。测试阶段可以用 FastMCP 自带的客户端,开箱即用。

Server 暴露工具,Client 调用工具。就这么简单。

传输方式、JSON-RPC、能力协商这些都是实现细节,上生产之前不用管。

步骤 1:安装 FastMCP

FastMCP 是让 MCP 用起来简单的 Python 框架。装一下就行,不需要任何配置。

 pip install fastmcp

本教程不需要虚拟环境,生产环境建议还是用一个。

步骤 2:创建 Server

新建一个

my_server.py

文件:

 from fastmcp import FastMCP  

# Initialize the server with a name  
mcp = FastMCP("my-first-server")  

# Define a tool using the @mcp.tool decorator  
@mcp.tool  
def get_weather(city: str) -> dict:  
    """Get the current weather for a city."""  
    # In production, you'd call a real weather API  
    # For now, we'll return mock data  
    weather_data = {  
        "new york": {"temp": 72, "condition": "sunny"},  
        "london": {"temp": 59, "condition": "cloudy"},  
        "tokyo": {"temp": 68, "condition": "rainy"},  
    }  
      
    city_lower = city.lower()  
    if city_lower in weather_data:  
        return {"city": city, **weather_data[city_lower]}  
    else:  
        return {"city": city, "temp": 70, "condition": "unknown"}  

# Run the server  
if __name__ == "__main__":  
     mcp.run(transport="stdio")
FastMCP("my-first-server")

创建一个带名称的服务器实例。

@mcp.tool

装饰器把普通函数注册为 MCP 工具。函数的 docstring 会变成工具描述——LLM 靠这个来判断什么时候该调用它。类型提示(

city: str

-> dict

)告诉 MCP 输入输出的类型。

transport="stdio"

表示通过标准输入输出通信,本地测试够用了。

整个 Server 就这些,实际代码 15 行。

步骤 3:写个 Client 测试一下

新建

test_client.py

 import asyncio  
from fastmcp import Client  

async def main():  
    # Point the client at your server file  
    client = Client("my_server.py")  
      
    # Connect to the server  
    async with client:  
        # List available tools  
        tools = await client.list_tools()  
        print("Available tools:")  
        for tool in tools:  
            print(f"  - {tool.name}: {tool.description}")  
          
        print("\n" + "="*50 + "\n")  
          
        # Call the weather tool  
        result = await client.call_tool(  
            "get_weather",   
            {"city": "Tokyo"}  
        )  
        print(f"Weather result: {result}")  

if __name__ == "__main__":  
     asyncio.run(main())
Client("my_server.py")

指定要连接的 Server 文件;

async with client:

自动管理连接生命周期;

list_tools()

负责动态发现可用工具,这是 MCP 的核心能力之一;

call_tool("get_weather", {"city": "Tokyo"})

带参数调用具体工具。

步骤 4:跑起来

终端里执行:

 python test_client.py

输出应该是这样的:

 Available tools:  
   - get_weather: Get the current weather for a city.
 ==================================================Weather result: {'city': 'Tokyo', 'temp': 68, 'condition': 'rainy'}

到这里就完成了。一个 MCP Server 搭好了Client 也成功调用了它。

步骤 5:增加更多工具

MCP 真正好用的地方在于扩展成本极低,再往 Server 里再加两个工具:

 from fastmcp import FastMCP  
from datetime import datetime  

mcp = FastMCP("my-first-server")  

@mcp.tool  
def get_weather(city: str) -> dict:  
    """Get the current weather for a city."""  
    weather_data = {  
        "new york": {"temp": 72, "condition": "sunny"},  
        "london": {"temp": 59, "condition": "cloudy"},  
        "tokyo": {"temp": 68, "condition": "rainy"},  
    }  
    city_lower = city.lower()  
    if city_lower in weather_data:  
        return {"city": city, **weather_data[city_lower]}  
    return {"city": city, "temp": 70, "condition": "unknown"}  

@mcp.tool  
def get_time(timezone: str = "UTC") -> str:  
    """Get the current time in a specified timezone."""  
    # Simplified - in production use pytz or zoneinfo  
    return f"Current time ({timezone}): {datetime.now().strftime('%H:%M:%S')}"  

@mcp.tool  
def calculate(expression: str) -> dict:  
    """Safely evaluate a mathematical expression."""  
    try:  
        # Only allow safe math operations  
        allowed_chars = set("0123456789+-*/.() ")  
        if not all(c in allowed_chars for c in expression):  
            return {"error": "Invalid characters in expression"}  
          
        result = eval(expression)  # Safe because we validated input  
        return {"expression": expression, "result": result}  
    except Exception as e:  
        return {"error": str(e)}  
if __name__ == "__main__":  
     mcp.run(transport="stdio")

再跑一次测试客户端,三个工具全部自动发现:

 Available tools:  
   - get_weather: Get the current weather for a city.  
   - get_time: Get the current time in a specified timezone.  
   - calculate: Safely evaluate a mathematical expression.

不需要改配置,不需要写路由。加了工具就直接可用。

最后:接入 LLM

前面写的 Client 是测试用的。生产环境里,LLM 框架本身充当 Client 角色。概念上大概是这样:

How MCP connects your LLM to external tools: the framework calls the client, which discovers and invokes tools from your server.

Server 端的代码完全不用动,这正是 MCP 的价值所在——工具写一次,任何兼容 MCP 的客户端都能用。

生产部署时需要把传输方式从

stdio

换成

http

 if__name__=="__main__":  
     mcp.run(transport="http", host="0.0.0.0", port=8000)

这样 MCP Server 就以 HTTP 端点的形式对外暴露,远程客户端可以直接连接。

总结

现在你手头已经有一个能跑的 MCP Server 了,前后也就 15 分钟。下一步就是把它接到实际的 LLM 上,做点真正有用的东西出来。

https://avoid.overfit.cn/post/c9314c34543a4ed1a1bb15b92d1c6ca2

by Paolo Perrone

安装的破解版,公司电脑不给装

说是只要公司电脑安装就算商用,没有购买授权,有侵权风险

一安装,安全部门的人就监控到然后要求删除

想问下,有没有类似 Navicat 的软件,用起来感觉挺顺手的,可以管理多种数据库

和对象是学校认识的,目前现在大概 5 年左右,预计今年结婚。
今年过年在对象家过,对象有一个弟弟(自己开店,目前自负盈亏,大概一年 10w 左右吧)
已经订婚(彩礼 18.8+3 金) 24 年订婚,因为对象比较强势(所以彩礼基本都是转给对象这里)-(但是这里有一点不愉快,对象母亲想拿着彩礼,但是对象强势还是拿回来了)
但是对象弟弟在 25 年结婚,我理解是因为如果对象和我结婚基本就不会补贴家里,所以就要弟弟先结婚了;在这里对象家里也有一些小变化吧(陆陆续续,借加给 大概 15w 左右吧),这里我也没什么意见( op 本身家庭也刚刚过贫穷吧,目前稍微好点吧,年包大概 40 )
我和对象的钱目前同居状态,所以工资大部分到账就转给对象一起存着了。
但是今年过年去她家,遇到一件事,就是对象母亲做生意和别人合伙,一共有 3 个合伙人,其中一个合伙人把钱挪用了,导致年底没有办法给员工发工资;然后其中一合伙人找对象母亲找我对象来借钱,大概 5w 左右,这点让我有点不高兴,让我感觉到对象母亲根本就没有不在意对象,有点自私;这让我觉得我和对象本身是想在一线安家的,但是本身我们的家庭没有办法托举,也不至于拖累吧。
我和对象本身没有什么矛盾,但是我们在要孩子的问题上有一点点分歧,我是想要的,但是对象说没有钱生什么孩子,我的态度是如果孩子不要了,那买房子干什么呢(对象对买房子有很强的意愿)
我们两没有共同的兴趣爱好,她爱看 dy ,我比较看 b 站;她需要宅,而我更喜欢探索;她急性子,我性格温和(可能和本身从小家庭有关,和母亲生活)。
可能我们两个分开都能找到更好的,但是因为很久了,都不想分开吧;我能感受到她对我是不满意的,目前也只是相对高工资维持的,一旦维持不了,就算结婚也会离吧(自我感觉)。
并且在争吵中,也说过我家 qiong (这点我不否认),不想和我结婚,想找个有钱的,很喜欢用钱来衡量。
所以 op 该如何选择呢?

有的人使用 Code Agent 提效 30%,有的人提效 300% 甚至更多。

区别不仅在于模型的选择,或是 Prompt 写得有多好,更重要的是工作流程。

提升 30% 是工具的辅助,提升 300% 则是生产关系的变革。如果只看到 30%,那用不用 Code Agent,差别好像不那么大,而如果有的人用了 Code Agent 实现了自身几倍效率的提升,对于不使用 Code Agent 的人来说,就是降维打击了。

串行开发

传统的开发流程中,所有工作都必须由人完成,所以只能串行开发,即使负责多个项目,也是在多个项目中切换,同时只能处理一个项目。

Code Agent 已经可以完成大部分编码工作,如果还是按照传统的工作流程,只是把编码的工作交给 Code Agent ,这时效率提升仅仅来自代码生成速度的加快,提升有限。

和 AI 的交流也是需要学习和适应的,知道 AI 能做什么,不能做什么,擅长什么,不擅长什么,需要在不断的尝试中探索。

有限的效率提升加上与 AI 的沟通成本,这也是很多人拒绝使用 AI 的原因。

当掌握了和 AI 的沟通方法后,就能将自己从编码工作中解放出来,获得很多看着 AI 干活的空闲时间。

并行开发

如果把 Code Agent 带来的空闲时间也利用起来,就能进一步提升效率,这就需要切换到并行开发流程。

并行开发可以按项目和分支维度分为多项目单分支,单项目多分支,多项目多分支。

多项目单分支

这是并行开发最好上手的方式,只需要在多个项目中开启 Code Agent,自己不断给 Code Agent 描述需求,确认方案,由 Code Agent 来实施。

哪个 Code Agent 完成了或者需要确认了,程序员再介入。

单项目多分支

相对多项目的需求,更常碰到的情况是单个项目中有多个需求,它们可能是互相依赖的,也可能是互相独立的。

平时我们在一个项目中可以切换分支,但同时只能使用一个分支,无法并行开发。这时就需要 git worktree 命令。git worktree 可以管理工作区,多个工作区彼此独立,在每个工作区都可以开一个 Code Agent。

常用的几个命令:

  • git worktree add:添加一个工作区,比如 project-a,要开发一个 feature-a,就可以使用 git worktree add -b feature-a ../project-a-feature-a master,从 master 签出一个 feature-a 分支,工作目录是 ../project-a-feature-a。
  • git worktree list:查看工作区列表。
  • git worktree remove:移除工作区。

在实际开发中,如果要开发一个新的功能,就添加一个使用新功能分支的工作区,在工作区进行开发,直到相应分支代码合并到主线分支,再移除工作区。

如果功能互相独立,就从主线分支签出,如果互相依赖,则从具体的功能分支签出。

因为会有集成测试的需求,我会再添加一个用于集成测试的工作区,并添加一个脚本用于将各个功能分支合并到集成测试分支,每次有新的功能分支或对功能分支做了新的提交,就重新执行一次脚本进行合并。

cd ../project-a-integration  
git checkout integration  
git reset --hard master  
git merge feature-a --no-ff --no-edit  
git merge feature-b --no-ff --no-edit  
git merge feature-c --no-ff --no-edit  
...
git push -f

注意这个脚本不要放在集成测试分支的工作区,不然会被 reset。

有了多项目单分支和单项目多分支的基础,多项目多分支也没什么难度了。

效率卡点

AI 生成代码的速度很快,并行开发时,程序员往往成为卡点。

要找到自己的卡点,才能进一步提升效率。我目前发现卡点主要来自两部分,一是 review 代码,二是功能验证。

这两部分都需要人来操作,如果操作时间过长,很多 Code Agent 都等待人来确认下一步,这时就又回到了串行流程。

关键在于如何减少这两部分所花费的时间。

对于代码 review,如果是一个比较大的功能点,尽量先和 AI 确认好实现方式,不要让 AI 自由发挥,或者将大功能拆成多个小功能,分步实现,这样每次 review 的工作量不会太大,自己看完一部分代码后,可以先提交,然后不断往之前的提交中追加内容,这样也更容易区分每次的改动。

对于功能验证,如果需要启动服务,构造数据进行验证,往往花的时间最多。比较好的办法是让 AI 自己验证,比如先让它写好单元测试,或者给它一个验证方式,而不要一直等着人去验证。

写在最后

Code Agent 出现之前,程序员之间的差别可能不那么明显,即使再厉害的程序员,要实现一个功能,也有很多时间要花在编码上,而编码的速度是有一个上限的。

而有了 Code Agent 之后,程序员之间的差别将成倍拉大,当有的人满足于使用 Code Agent 从编码工作中解放出来,多了一些空闲时间,有的人则同时开发多个功能,将自己的效率提升好几倍。

如果只把 Code Agent 当做一个更快的代码生成器,只是有了更好的辅助工具。而如果使用了并行开发流程,一个人能干之前好几个人的事情。从一个人只能做一件事,到一个人同时推进多件事,生产关系有了变革,这才是 Code Agent 真正的价值。

这个小软件只有一个功能,就是把 win11 任务栏变回小图标,从 win95 一直用过来,还是习惯小图标的任务栏,只可惜微软在 win11 里砍掉了这个原生功能,苦于找不到合适的解决方案。

StartAllBack 能用,但是右下角只能显示时间,显示不了日期。
Windhawk 可以,右下角日期时间也都有,但是软件太臃肿,为了一个小功能搞一个 800 多兆的臃肿庞大的软件划不来。

所以花了几天时间 vibe coding 一个,一行代码都没写也不懂什么 C++,对代码一窍不通,这事放到一年前,想要做一个这样的软件简直是天方夜谭,现在有了 AI ,居然可以把想法变成现实了。感觉我现在强的可怕,感觉没有我做不出来的软件了,嚯哈哈哈哈。

另外又用 AI 做了个 pdbtools 用于下载微软的 pdb 文件并把偏移量保存到 taskbar_symbols.ini 符号偏移表里,不保证适配大部分版本,因为每个版本都不一样,所以如果你打开软件以后,跳出控制台下载文件,说明 ini 里没有适配到你的 win11 版本的偏移量,软件会自动从微软服务器下载两个 pdb 文件并放在当前目录里,下载完后,软件会自动找到对应的偏移量并保存到 ini 文件里,应用成功以后软件会自动删除两个文件。

首先把软件解压到任何你喜欢的目录,比如 D:\Tools\Taskbar\ 或者 C:\Program Files\TaskbarTweaker\ 然后运行
如果没效果,试试以管理员权限运行。
如果软件成功运行,并且成功应用到任务栏,软件会自动被加载到 任务计划程序 里,跟随开机自动启动
如果你想停用它,可以带参数 -u 来运行它,使用这个命令 taskbar_tweaker -u
如果遇到任何问题,请积极反馈。

https://github.com/metalbug/win11-taskbar-small-icon

【免费开源】stm32串行驱动LCD12864显示正弦函数 波形可视化神器完整项目分享

一、项目概述

本项目是一个基于STM32微控制器的LCD12864液晶显示屏驱动程序,通过串行通信方式控制LCD12864显示屏,实现正弦函数波形的实时显示。这个项目将数学函数可视化,让抽象的数学概念变得直观可见,是学习STM32嵌入式开发和图形显示技术的绝佳实践项目。

LCD12864是一款128×64点阵的图形型液晶显示模块,具有体积小、功耗低、显示内容丰富等特点,广泛应用于各种嵌入式系统中。本项目采用串行接口方式驱动LCD12864,相比并行接口方式,可以节省更多的IO引脚资源,非常适合引脚资源有限的STM32微控制器使用。

正弦函数是数学中最基础的周期函数之一,在信号处理、通信系统、音频处理等领域有着广泛的应用。通过在LCD12864上实时显示正弦波形,不仅能够直观地展示正弦函数的周期性特征,还能帮助理解数字信号处理的基本原理。

本项目的核心功能包括:LCD12864的初始化配置、串行通信接口的实现、正弦函数数据的计算与存储、波形绘制算法的实现等。通过这个项目,读者可以深入学习STM32的GPIO、SPI通信、定时器等外设的使用方法,掌握图形显示的基本原理和编程技巧。

源码分享

直接放到之前写的文章里了,免费开源,下载学习即可。

https://blog.csdn.net/weixin_52908342/article/details/158101046

二、系统设计流程图

flowchart TD
    A[系统启动] --> B[STM32初始化]
    B --> C[GPIO时钟配置]
    C --> D[SPI接口配置]
    D --> E[LCD12864初始化]
    E --> F[清屏操作]
    F --> G[正弦函数数据计算]
    G --> H[波形绘制]
    H --> I{是否继续显示}
    I -->|是| G
    I -->|否| J[结束]
    
    style A fill:#e1f5ff
    style B fill:#fff4e1
    style C fill:#fff4e1
    style D fill:#fff4e1
    style E fill:#e1ffe1
    style F fill:#e1ffe1
    style G fill:#ffe1f5
    style H fill:#ffe1f5
    style I fill:#f5ffe1
    style J fill:#ffcccc

三、硬件设计

3.1 STM32微控制器选型

本项目采用STM32F103系列微控制器作为主控芯片,该系列基于ARM Cortex-M3内核,具有丰富的外设资源和良好的性价比。STM32F103C8T6是最常用的型号,具有64KB Flash存储器、20KB SRAM、48个GPIO引脚,完全满足本项目的需求。

STM32F103的主要特性包括:

  • 72MHz系统时钟频率
  • 3个SPI接口
  • 2个I2C接口
  • 5个USART/UART接口
  • 3个12位ADC
  • 多个定时器
  • 丰富的GPIO配置选项

在这里插入图片描述

3.2 LCD12864液晶显示屏

LCD12864是一款128×64点阵的图形型液晶显示模块,内置ST7920控制器,支持串行和并行两种通信方式。主要技术参数如下:

  • 分辨率:128×64点阵
  • 显示颜色:黄绿底黑字或蓝底白字
  • 工作电压:5V
  • 工作电流:约2-3mA
  • 视角:6点钟方向
  • 控制器:ST7920
  • 内置字库:8192个中文汉字(16×16点阵)
  • 内置ROM:128个字符(8×16点阵)

3.3 硬件连接方案

采用串行接口方式连接STM32和LCD12864,需要以下连接:

  • LCD12864的VSS引脚连接GND
  • LCD12864的VDD引脚连接5V电源
  • LCD12864的V0引脚连接电位器用于对比度调节
  • LCD12864的RS(CS)引脚连接STM32的PA0
  • LCD12864的RW(SID)引脚连接STM32的PA1
  • LCD12864的E(SCLK)引脚连接STM32的PA2
  • LCD12864的PSB引脚连接GND(选择串行模式)
  • LCD12864的RST引脚连接STM32的PA3
  • LCD12864的BLA引脚连接5V(背光正极)
  • LCD12864的BLK引脚连接GND(背光负极)

四、软件设计

4.1 系统架构设计

软件系统采用模块化设计,主要包含以下模块:

  1. 系统初始化模块:负责STM32系统时钟、GPIO、SPI等外设的初始化配置
  2. LCD12864驱动模块:实现LCD12864的底层驱动函数,包括写命令、写数据、清屏等操作
  3. 图形绘制模块:实现基本的图形绘制功能,如画点、画线、画矩形等
  4. 波形显示模块:实现正弦函数波形的计算和显示
  5. 主控模块:协调各模块的工作,实现系统的整体功能

4.2 LCD12864驱动程序

LCD12864的串行通信协议采用三线制(CS、SID、SCLK),数据传输时序严格遵循ST7920控制器的规范。以下是LCD12864初始化的核心代码:

#include "stm32f10x.h"

#define LCD_CS_PIN    GPIO_Pin_0
#define LCD_SID_PIN   GPIO_Pin_1
#define LCD_SCLK_PIN  GPIO_Pin_2
#define LCD_RST_PIN   GPIO_Pin_3
#define LCD_PORT      GPIOA

void LCD_GPIO_Init(void)
{
    GPIO_InitTypeDef GPIO_InitStructure;
    
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
    
    GPIO_InitStructure.GPIO_Pin = LCD_CS_PIN | LCD_SID_PIN | LCD_SCLK_PIN | LCD_RST_PIN;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(LCD_PORT, &GPIO_InitStructure);
    
    GPIO_SetBits(LCD_PORT, LCD_CS_PIN);
    GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
    GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    GPIO_SetBits(LCD_PORT, LCD_RST_PIN);
}

void LCD_WriteByte(uint8_t data, uint8_t rs)
{
    uint8_t i;
    uint8_t temp;
    
    GPIO_ResetBits(LCD_PORT, LCD_CS_PIN);
    
    for(i = 0; i < 5; i++) {
        GPIO_ResetBits(LCD_PORT, LCD_SCLK_PIN);
        GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
        GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    }
    
    GPIO_ResetBits(LCD_PORT, LCD_SCLK_PIN);
    if(rs) GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
    else GPIO_ResetBits(LCD_PORT, LCD_SID_PIN);
    GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    
    GPIO_ResetBits(LCD_PORT, LCD_SCLK_PIN);
    GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
    GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    
    for(i = 0; i < 4; i++) {
        temp = data;
        temp = temp << i;
        temp = temp & 0x80;
        
        GPIO_ResetBits(LCD_PORT, LCD_SCLK_PIN);
        if(temp) GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
        else GPIO_ResetBits(LCD_PORT, LCD_SID_PIN);
        GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    }
    
    for(i = 4; i < 8; i++) {
        temp = data;
        temp = temp << i;
        temp = temp & 0x80;
        
        GPIO_ResetBits(LCD_PORT, LCD_SCLK_PIN);
        if(temp) GPIO_SetBits(LCD_PORT, LCD_SID_PIN);
        else GPIO_ResetBits(LCD_PORT, LCD_SID_PIN);
        GPIO_SetBits(LCD_PORT, LCD_SCLK_PIN);
    }
    
    GPIO_SetBits(LCD_PORT, LCD_CS_PIN);
}

void LCD_WriteCommand(uint8_t cmd)
{
    LCD_WriteByte(0xf8, 0);
    LCD_WriteByte(cmd & 0xf0, 1);
    LCD_WriteByte((cmd << 4) & 0xf0, 1);
}

void LCD_WriteData(uint8_t data)
{
    LCD_WriteByte(0xfa, 0);
    LCD_WriteByte(data & 0xf0, 1);
    LCD_WriteByte((data << 4) & 0xf0, 1);
}

void LCD_Init(void)
{
    LCD_GPIO_Init();
    
    GPIO_ResetBits(LCD_PORT, LCD_RST_PIN);
    Delay_ms(10);
    GPIO_SetBits(LCD_PORT, LCD_RST_PIN);
    Delay_ms(10);
    
    LCD_WriteCommand(0x30);
    Delay_ms(5);
    LCD_WriteCommand(0x30);
    Delay_ms(5);
    LCD_WriteCommand(0x0c);
    Delay_ms(5);
    LCD_WriteCommand(0x01);
    Delay_ms(5);
    LCD_WriteCommand(0x06);
    Delay_ms(5);
}

void LCD_Clear(void)
{
    LCD_WriteCommand(0x30);
    LCD_WriteCommand(0x01);
    Delay_ms(10);
}

4.3 正弦函数波形绘制

正弦函数波形的绘制需要将数学上的连续函数转换为离散的点阵显示。LCD12864的分辨率为128×64,我们需要在这个有限的像素空间内绘制出平滑的正弦波形。

正弦函数的基本公式为:y = A × sin(ωx + φ) + k

其中:

  • A:振幅,决定波形的高度
  • ω:角频率,决定波形的周期
  • φ:初相位,决定波形的起始位置
  • k:直流偏置,决定波形的垂直位置

以下是正弦波形绘制的核心代码:

#include <math.h>

#define PI 3.14159265358979323846
#define LCD_WIDTH  128
#define LCD_HEIGHT 64

void LCD_DrawPoint(uint8_t x, uint8_t y)
{
    uint8_t x_addr, y_addr;
    uint8_t bit_data;
    
    if(x >= LCD_WIDTH || y >= LCD_HEIGHT) return;
    
    y_addr = y / 8;
    bit_data = 0x01 << (y % 8);
    
    LCD_WriteCommand(0x80 | y_addr);
    LCD_WriteCommand(0x80 | x);
    LCD_WriteData(bit_data);
}

void LCD_DrawLine(uint8_t x1, uint8_t y1, uint8_t x2, uint8_t y2)
{
    int dx, dy, sx, sy, err, e2;
    
    dx = abs(x2 - x1);
    dy = abs(y2 - y1);
    
    if(x1 < x2) sx = 1;
    else sx = -1;
    
    if(y1 < y2) sy = 1;
    else sy = -1;
    
    err = dx - dy;
    
    while(1) {
        LCD_DrawPoint(x1, y1);
        
        if(x1 == x2 && y1 == y2) break;
        
        e2 = 2 * err;
        
        if(e2 > -dy) {
            err -= dy;
            x1 += sx;
        }
        
        if(e2 < dx) {
            err += dx;
            y1 += sy;
        }
    }
}

void LCD_DrawSineWave(void)
{
    uint8_t x, y;
    float angle;
    float amplitude = 25.0;
    float frequency = 2.0;
    float offset = 32.0;
    
    LCD_Clear();
    
    LCD_WriteCommand(0x34);
    LCD_WriteCommand(0x36);
    
    for(x = 0; x < LCD_WIDTH; x++) {
        angle = (float)x * frequency * 2.0 * PI / LCD_WIDTH;
        y = (uint8_t)(offset + amplitude * sin(angle));
        
        LCD_DrawPoint(x, y);
        
        if(x > 0) {
            uint8_t prev_x = x - 1;
            float prev_angle = (float)prev_x * frequency * 2.0 * PI / LCD_WIDTH;
            uint8_t prev_y = (uint8_t)(offset + amplitude * sin(prev_angle));
            LCD_DrawLine(prev_x, prev_y, x, y);
        }
    }
    
    LCD_WriteCommand(0x30);
}

void LCD_DisplayText(uint8_t x, uint8_t y, char *str)
{
    LCD_WriteCommand(0x80 | y);
    LCD_WriteCommand(0x80 | x);
    
    while(*str != '\0') {
        LCD_WriteData(*str);
        str++;
    }
}

4.4 主程序设计

主程序负责系统的初始化和功能协调,通过定时器实现波形的动态刷新,或者通过按键实现不同参数波形的切换。

int main(void)
{
    SystemInit();
    
    LCD_Init();
    LCD_Clear();
    
    LCD_DisplayText(0, 0, "Sine Wave Demo");
    Delay_ms(1000);
    
    LCD_DrawSineWave();
    
    LCD_DisplayText(0, 2, "y=A*sin(wx+phi)+k");
    LCD_DisplayText(0, 4, "A=25, w=2, phi=0");
    LCD_DisplayText(0, 6, "k=32");
    
    while(1) {
        Delay_ms(1000);
    }
}

void Delay_ms(uint32_t ms)
{
    uint32_t i, j;
    for(i = 0; i < ms; i++)
        for(j = 0; j < 9000; j++);
}

五、关键技术点分析

5.1 串行通信时序

LCD12864的串行通信采用SPI时序,但与标准SPI有所不同。ST7920控制器定义了特殊的通信协议,每个字节传输需要先发送5个同步字节,然后发送RS位和数据位。这种设计虽然增加了通信开销,但提高了通信的可靠性。

5.2 图形绘制算法

在点阵显示屏上绘制平滑曲线需要采用适当的算法。本项目使用Bresenham直线算法来连接离散的正弦函数点,这种方法计算效率高,适合在资源有限的嵌入式系统中使用。

5.3 浮点数运算优化

STM32F103具有硬件浮点运算单元,但为了提高运算效率,在实际应用中可以考虑使用定点数运算代替浮点数运算,或者使用查表法预先计算正弦函数值。

5.4 显示缓冲区管理

为了提高显示效率,可以建立显示缓冲区,先在内存中完成图形绘制,然后一次性更新到LCD显示屏。这种方法可以减少LCD的访问次数,提高显示速度。

六、项目扩展与应用

6.1 功能扩展

  1. 多波形显示:扩展支持余弦函数、方波、三角波等多种波形
  2. 参数调节:通过按键或电位器实时调节波形的振幅、频率、相位等参数
  3. 动态显示:实现波形的滚动显示,模拟示波器功能
  4. 数据存储:将波形数据存储到SD卡,实现数据记录功能

6.2 应用场景

  1. 教学演示:用于数学和物理教学,直观展示周期函数的特征
  2. 信号发生器:配合DAC芯片,实现可调参数的信号发生功能
  3. 仪器显示:作为各种测量仪器的显示界面
  4. 工业控制:用于工业自动化设备的参数显示和监控

七、总结

本项目通过STM32驱动LCD12864显示正弦函数波形,展示了嵌入式系统图形显示的基本原理和实现方法。项目涵盖了硬件设计、软件编程、算法实现等多个方面的知识,是学习STM32嵌入式开发的综合性实践项目。

通过本项目的学习,读者可以掌握STM32的GPIO配置、串行通信、定时器使用等基本技能,理解图形显示的原理和方法,为后续更复杂的项目开发打下坚实的基础。项目的代码结构清晰,功能模块化,便于学习和扩展。

项目采用开源方式发布,欢迎广大爱好者学习交流,共同进步。希望这个项目能够帮助更多人了解嵌入式开发的魅力,激发对电子技术的兴趣和热情。

八、参考资料

  1. ST7920 LCD控制器数据手册
  2. STM32F103参考手册
  3. LCD12864液晶显示屏技术规格书
  4. 嵌入式系统设计与应用
  5. 数字信号处理基础
    在这里插入图片描述

大概一个月前,门牙一颗开始渐渐碎裂,一点一点的碎片掉下来还是很让人心慌的, 牙签往里捅一捅能感觉有个坑,一捅一疼,门牙最后出现了大概一毫米能卡进指甲的缝,



老实说不好看是次要的,担心进一步恶化才是想处理的主要原因,

12 号放假了想看看牙,离家最近的口腔门诊关门了,走到远一些的门诊看了个价目表,补一颗大概三百块总费用,医保定点,但只能走个人账户,不走统筹,



网上搜了下最吸睛的是个连锁的某某菲尔,在医疗保障局网站( https://wjw.sz.gov.cn/bmfw/wycx/fwyl/yycx/ )能查到总院是二级营利性口腔医院,但不清楚这代表什么,

官网有在线客服我想问问是否支持社保和统筹,但这客服好像只会说套话,一点有用信息都没有,先让我加微信拍照看看牙,然后说牙缝补不了用不了医保,要考虑贴面或者牙冠,我质疑,他又说可以约个免费检查,说医生不是神仙不能在网上就确认方案, 合着照片是白看的,这套话说的我很没安全感,决定上大医院检查了,

龙华区人民医院,要提前预约,牙体牙髓病科,看了下 18 号初二一大堆医生有空,其他基本没时间,最后在医院自己网站预约到年前唯一一个医师唯一一个有号的时间,今天 15 号去看,

提前预约, 去医院当天付挂号费( 25-15 ),到口腔门诊楼层机器上取不到号,找人工就能取到号,搞不懂,给我的感觉机器似乎是和 160 合作的,不在 160 预约的号就取不了,包括医院自己的公众号进入自家的网站预约的也是二等公民的感觉,

取号后看医生,先说了我的目的,就是补一个门牙,顺便整体检查一下所有牙齿,于是医生先给我开了个牙片,扫码付费( 50-27.5 ),然后到对门拍牙片,



站正了,戴个挺重的帽子,咬住一个套着一次性套的塑料片,脸旁两个 45°弧形的什么东西绕着我转大概一分钟就好了,



完事只让我用手机拍电脑上的牙片就能回去看医生了,没有纸质的牙片给我,



回去医生在给别人处理, 等了大概半个小时到我,躺了五分钟医生才来开始,

过程手机开了录音和转文字,共 37 分钟,但是听不太清楚,转文字记录了很多细微的其他医生闲聊的声音,



开始先检查一下,主要就是说我后牙磨损严重,说也不是说那么严重,但我还年轻就磨损成这样,问我有没有睡觉磨牙,应该没有,没人说过我磨牙,不过也可能是打呼噜严重盖过了,

后牙侧面有洞有蛀有隐裂纹,不能咬太硬的东西,不然裂成两半可能要拔牙,

左下右下各一颗建议补,右上一颗问题比较小,想补的话一次性都能补掉,

没提到牙片上的一颗横智齿,

然后就开始处理门牙,

全程有个棉花状的东西挡住上嘴唇,还有个支架咬住防止闭嘴,

全程好像是两个人,一个拿着管子专门在吸水,

先磨掉蛀牙再补,磨了几十下。每一下都有神经痛的感觉,刺刺的。很吓人,

管子在嘴里一直吸口水和偶尔喷的水,但偶尔还是忍不住咽一点。

磨完开始补,补牙过程有一次什么东西塞进牙缝怼到牙龈的肉疼感,不是很疼但忍不住发声,医生马上就说是有点疼正常的,

补完之后又磨了十几下,不疼,应该是在磨树脂假牙。但最后磨的一下又突然疼了一下,像是磨到旁边的门牙了,但看感觉没什么问题。

补后修完有两次让我咬一咬动一动看有没有挡住,

完事后边上放了杯温水给我漱口,

医生交代最近别吃太冷太烫的,万一发炎了可能要做根管,要是没什么感觉补好就行,

补的牙不能嗑瓜子这种硬的,保护好能用很久的,要注意刷牙,用牙线,不然可能还会蛀,没说具体能用多久,留了个联系方式,说是 3 个月内掉了的话免费处理。超过了时间有问题也可以直接联系。

结束之后才开单让我缴费( 392.9-215.16 ),分好多项目总和,最贵的一项 200 ,事前只有提一嘴补一颗大概三百多一半统筹一半个人一点点自费,



补完表面有点坑坑洼洼的看不出来但是舌头舔一舔很明显不光滑,



问了下磨了多少好牙,说是蛀的范围挺大的。磨掉挺多的,事前外表看上去就一条缝大概一毫米,可牙签刮一刮确实感觉里面有个坑。

牙片明显有颗智齿横了,但医生没主动提起,明明一开始就说是想整体检查才拍片的,但医生似乎没怎么看牙片,

因此我主动问了下这个智齿,医生这才仔细看牙片,说看起来可能长在了牙神经上,拔掉风险可能比较大,但也不一定,可能是错位的,需要做 CT 确认一下。如果伤到牙神经的话无法恢复,会一直有麻药没过的感觉,但不会面瘫,别人看不出来,

另外门牙缝上方挨着牙龈的位置有个很小的洞漏气卡脏东西,一直是这样的,怀疑蛀牙也是这里清洁不干净导致的, 补牙后这个洞还在,原以为会被填上,

修好了闭嘴吸一吸,还有一点点凉凉的磨牙时的神经痛的感觉。

背着包去的,完全没用上,全程只用到了手机。连身份证都没用,甚至没有什么单子要给我带走。
带了瓶东方树叶放包里,回家了才发现忘了喝。

完事一个半小时后吃饭, 饭后大概一个小时内牙齿比刚补完更敏感一些,饭后四个小时后基本上没有感觉了,

加上来回公交费,总费用,一档医保,

(25+50+392.9) − (15+27.5+215.16) +3*2= 216.24 元,

一人 1k 合适么?另外还会带点白酒。
另外,老婆的爷爷奶奶也要红包么?多少合适?她的爷爷奶奶是老婆自己给,还是我也得分开给?

这年头,谁家里还没个“小爱同学”?

但说实话,用久了你一定也发现了:

问点复杂的,她就开始装傻——
“哎呀,这个问题难倒我了”;
想让她写个周报、出个方案、分析点东西?
除了放歌、设闹钟,基本属于智商掉线状态。

如果我告诉你:只要 5 分钟,就能让家里这个“只会听指令的小爱”,直接升级成能写代码、能做方案、能陪你聊天的 AI 大神,你愿不愿意折腾一下?

今天这篇文章,就是一个真正能照着做、不踩坑的保姆级教程
我们用一个叫 Lerio AI Speaker 的工具,
给小爱同学来一次“原地飞升”


一、为什么要折腾这一出?

一句话总结:

👉 给小爱同学换个“更聪明的大脑”。

升级前的小爱:

  • 只能执行固定指令
  • 对话生硬,经常答非所问
  • 稍微复杂一点的问题就“我还没学会”

升级后的小爱:

  • 接入主流大模型(通义千问 / 智谱 AI / DeepSeek / 小米自研等)
  • 能理解上下文,正常聊天
  • 能写方案、改文案、写代码
  • 甚至可以当孩子的学习助手、你的情绪垃圾桶

最关键的一点:不用买新硬件。
你家现在那个小爱音箱,直接就能用。


二、准备工作(3样东西就够)

在开始之前,先确认你有下面这些:

1️⃣ 小米账号(已经绑定小爱音箱)
2️⃣ Lerio AI Speaker 账号(音箱和大模型之间的“中转站”)
3️⃣ Xiaomi MiMo API 开放平台账号(用小米账号就能登录)

没什么技术门槛,全程网页操作。


三、手把手教程(一步一步来)

1️⃣ 登录 Lerio 控制台

打开:
👉 https://mi.lerio.cn/dashboard

注册并登录后,你会看到一个非常清爽的后台界面。


2️⃣ 授权你的小米账号(关键步骤)

在后台找到 「我的账号」 → 立即配置

这里需要填写:

  • 小米 ID
  • 登录用的 passToken

这一步的作用:
👉 让 Lerio 拿到控制你音箱的权限,否则后面没法通信。

# passToken 获取方法
1. 使用 Chrome 浏览器访问小米账号官网并登录
2. 按 F12 打开开发者工具
3. 切换到 Application(应用)
4. 左侧 Cookies → https://account.xiaomi.com
5. 找到 passToken,复制它

注意:不要主动退出小米账号,否则 passToken 会失效

PixPin_2026-02-12_16-09-42.png

这一块很多人会紧张,其实就是读取 Cookie,用完随时可以解绑。

3️⃣ 创建使用卡槽

  • 新注册账号会送 3 天试用插槽
  • 高峰期可能会有点拥挤
  • 如果想长期稳定用,可以开通付费(价格还能接受)

PixPin_2026-02-12_16-16-26.png


4️⃣ 创建 AI 角色(最好玩的地方)

这里可以给小爱定一个“人设”。

比如:

  • 毒舌但专业的翻译官
  • 耐心讲解的老教授
  • 给孩子讲故事的百科老师

你写什么,它就按什么性格跟你说话。

PixPin_2026-02-12_16-21-19.png


5️⃣ 添加你的小爱音箱

绑定小米账号后:
👉 系统会自动拉取你名下所有的小爱设备。

选中你要用的那个即可。

PixPin_2026-02-12_16-25-12.png


6️⃣ 申请大模型 API Key

这里我们用 小米 Xiaomi MiMo 模型 举例:
👉 https://platform.xiaomimimo.com/#/console/api-keys

创建并复制你的 API Key。

PixPin_2026-02-12_16-31-07.png


7️⃣ 关联大模型(装上灵魂)

进入设备 → AI 服务配置

  • 选择你要用的模型
  • 填入刚才申请的 API Key

PixPin_2026-02-12_16-43-52.png


8️⃣ 启动服务,开始对话

使用方式很简单:

👉 先唤醒小爱 → 再说「请问 + 你的问题」

可以用你刚才设定的 AI 角色关键词,测试是否生效。

PixPin_2026-02-12_16-49-02.png

PixPin_2026-02-12_16-57-59.png


四、升级后的小爱,能干啥?

场景一:深夜情绪救援

  • 以前:

    “我可以为你播放一首伤感的歌”
  • 现在:

    “听得出来你很难受,要不要慢慢说给我听?”

场景二:办公摸鱼神器

  • 写周报
  • 出方案
  • 改文案
  • 想脚本

一句话,全都能接住。


场景三:孩子的十万个为什么

不用再照本宣科,
它能用孩子听得懂的话,把复杂问题讲清楚。


五、一些实用小提醒

1️⃣ 延迟是正常的
云端大模型需要 1~2 秒思考时间。

2️⃣ 随时可解绑
不想用了,后台一键关闭,小爱立刻恢复原样。


写在最后

当那个原本只会报天气的小音箱,
突然开始跟你聊人生、讲逻辑、写方案,
你会发现:

👉 这 5 分钟,真的值。

如果你在配置过程中遇到问题,
或者想接入更强的模型,
欢迎在评论区留言,我会一步步帮你搞定。

关注我,后面继续分享更多智能家居和 AI 的“野路子玩法”。

原文链接:https://www.nocobase.com/cn/blog/nocobase-2-0-officially-released

NocoBase 2.0 是一次面向 复杂应用构建与规模化部署 的重要升级。本次版本在 AI 能力、应用架构、数据编辑体验以及前端事件流等方面进行了系统性增强,同时全面推进 V2 页面与核心能力的适配。

新特性

AI 员工

AI 能力正式下沉至内核,成为 NocoBase 的一等公民,支持通过插件体系持续扩展:

  • 将 AI 移至内核,提供插件化扩展能力
  • 升级并优化 LangChain 相关依赖,提升稳定性与可扩展性
  • 简化 AI 员工的交互流程,降低配置与使用门槛

20260214075059

参考文档:

应用监管器

应用监管器插件用于 统一发现、调度与管理多个 NocoBase 应用实例,适用于多应用与多环境部署场景。

  • 支持应用自动发现与集中管理
  • 通过共享内存机制提升实例间协作效率
  • 支持多环境混合部署,满足复杂交付需求

共享内存
20260214075803

多环境混合部署
20260214075815

参考文档:

工作流画布编排能力增强

支持拖拽节点调整顺序

image-8ajlez.png

支持复制粘贴节点

image-nskgho.png

子表格(行内编辑 / 弹窗编辑)

为满足不同复杂度的关联数据编辑需求,NocoBase 提供两种子表格编辑模式,可按场景灵活选择:

  • 子表格(行内编辑):直接在表格中编辑关联数据,操作高效,适合快速录入与批量修改
  • 子表格(弹窗编辑):通过弹窗表单编辑数据,支持更复杂的字段类型与校验逻辑,适用于高复杂度场景

子表格(行内编辑)
20260214080224

子表格(弹窗编辑)
20260214080233

参考文档:

字段赋值(新版)

全新的字段赋值对表单数据的 初始化与写入逻辑 进行了统一与强化,显著提升可理解性与一致性:

  • 提供 统一的字段赋值配置入口,减少分散配置带来的理解成本
  • 字段赋值逻辑 不再依赖字段组件类型,数据行为更加稳定、可预测
  • 支持 关系字段的字段级赋值配置,满足复杂关联建模需求
  • 同时支持 默认值固定值 两种赋值方式,覆盖初始化与强制写入场景
  • 旧版「字段默认值」已废弃,请使用新版字段赋值

20260214080932

参考文档:

  • 字段赋值(文档即将上线)

事件流触发时机

事件流在执行时,严格按照 Event → Flow → Step 的层级顺序运行,并在各层级的执行前后触发对应 Hook,便于精细化控制与扩展。

event:
  before:
    - track_event_start
  flows:
    - name: flow1
      before:
        - track_flow_start
      steps:
        - name: step1
          before: [track_step_start]
          run: do_something
          after: [track_step_done]
      after:
        - track_flow_end
    - name: flow2
      ...
    - name: flow3
      ...
  after:
    - track_event_end

20260214081527

参考文档:

新增 2.0 适配

批量编辑

20260214083041

参考文档:

复制

20260214083146

参考文档:

区块高度

20260214083319

参考文档:

表格行拖拽排序

20260214085152

数据加载方式

20260214083433

参考文档:

表单支持展示关系字段的字段

20260214083517

参考文档:

页面(V2)本地化支持

V2 页面已全面支持本地化,覆盖 页面、区块、操作、字段 等多个层级。

启用本地化插件后,系统将自动收集缺失翻译词条,并集中展示于本地化管理列表,便于统一维护。

在 JS 区块中,可通过 ctx.t() 获取本地化文案,并支持变量插值:

const label = ctx.t('Your name is {{name}}', {
  name: await ctx.getVar('ctx.user.nickname')
});
ctx.render(label);

审批 2.0

新创建的审批工作流均以 2.0 的区块编排界面。1.x 已配置的仍支持继续使用,如 1.x 已配置的审批希望使用 2.0 的界面编排,需要选择 v2 版本重新配置界面,且配置后不能再还原到 1.x。

配置发起人的界面

image-ba3ann.png

配置审批人的界面

image-dl448q.png

抄送 2.0

新创建的抄送节点,被抄送人的查看界面均以 2.0 的区块编排,1.x 已配置的仍支持继续使用,如 1.x 已配置的抄送希望使用 2.0 的界面编排,需要选择 v2 版本重新配置界面,且配置后不能再还原到 1.x。

image-z26oib.png

尚未适配的功能

以下功能模块尚未在 2.0 中完成适配,将在后续版本中逐步升级:

功能模块当前替代方案
自定义请求工作流请求节点
浏览器打印JS 操作
分步表单JS 区块
树筛选区块JS 区块
日历区块JS 区块
自定义变量事件流
甘特图区块JS 区块
看板区块JS 区块
文本复制事件流
表格列设置JS 操作
样式联动规则事件流
复制文本快捷键事件流
二维码字段JS 字段
扫码录入事件流
嵌入 NocoBase
中国行政区字段
编码字段
公开表单
工作流人工节点待办
提交成功后事件流
表单数据模板事件流

OpenClaw 作为一款功能强大的自主 AI 助手,具备代码执行、工具调用、全平台消息集成等核心能力,能够自主完成各类复杂任务。搜索功能作为其获取实时信息、拓展知识边界的关键模块,合理配置搜索工具可大幅提升其使用体验。本文将详细讲解如何在 OpenClaw 中部署 SearXNG(自建)、DuckDuckGo 和 Tavily 三种主流搜索工具,对比各方案优劣并提供精准选型建议,助力不同需求的用户快速完成配置、高效使用。

一、搜索方案对比与选型指南

三种搜索工具在成本、配置难度、适用场景上各有侧重,结合自身需求选择合适方案,可实现效率与体验的双重提升。以下是详细对比:

| 搜索方案 | 成本投入 | 配置难度 | 推荐场景 | 关键备注 |

| SearXNG(自建) | 完全免费 | 高 | 对数据隐私有极高要求、需要完全掌控搜索流程、追求高可用性的用户,如隐私敏感型开发、企业内部搜索场景 | 需自行部署服务器,支持 q(搜索词)和 format=json(返回格式)参数,可通过 Docker 快速部署 |

| DuckDuckGo | 完全免费 | 低 | 个人学习、功能测试、快速获取即时答案,无需复杂配置,追求便捷性的场景 | 无需注册账号、无需 API Key,可直接调用公开 API,但搜索质量相较于 Tavily 略逊一筹 |

| Tavily | 免费额度+付费升级 | 中 | 商业项目开发、需要高质量、结构化实时数据,对搜索结果准确性要求较高的场景 | 免费计划每月提供 1000 次搜索额度,无需信用卡验证,国内网络环境下访问友好 |

💡 选型核心建议:若追求零成本、零配置,仅用于个人测试和即时查询,首选 DuckDuckGo;若需要高质量、结构化搜索结果,兼顾便捷性与实用性,优先选择 Tavily;若对隐私保护和定制化有极致需求,且具备服务器部署能力,可选择自建 SearXNG 实例。

二、详细配置步骤(按配置难度从低到高)

2.1 配置 DuckDuckGo(Instant Answer API)

DuckDuckGo 的 Instant Answer API 为公开接口,无需注册和 API Key,是 OpenClaw 最易配置的默认搜索工具,适合所有新手用户快速上手。

2.1.1 获取 API 地址与参数

DuckDuckGo 的 API 地址固定不变,支持多种参数自定义搜索结果,核心参数如下:

  • API 基础地址:https://api.duckduckgo.com/
  • 核心请求参数:q=搜索词&format=json&no_html=1&skip_disambig=1
  • 参数说明:q 用于指定搜索内容,format=json 表示返回 JSON 格式数据(便于 OpenClaw 解析),no_html=1 屏蔽 HTML 标签,skip_disambig=1 跳过歧义提示,提升搜索效率。

2.1.2 在 OpenClaw 中配置(两种方法)

可根据自身需求选择配置方式,修改配置文件为推荐方案,适合长期使用;web_fetch 工具调用适合临时测试,无需修改全局配置。

方法一:修改配置文件(推荐,全局生效)

OpenClaw 的配置文件通常位于两个路径之一,可根据自身系统查找:~/.openclaw/openclaw.json 或 ~/.claude/settings.json。编辑该文件,添加如下配置,将搜索提供者指向 DuckDuckGo:


{

  "tools": {

    "web": {

      "search": {

        "provider": "duckduckgo",

        "apiKey": "", // DuckDuckGo 无需 API Key,留空即可

        "maxResults": 5, // 最多返回 5 条搜索结果,可按需调整

        "timeoutSeconds": 30 // 超时时间 30 秒,避免请求卡顿

      }

    }

  }

}

方法二:使用 web_fetch 工具(临时调用,无需修改配置)

若无需全局启用 DuckDuckGo,可直接在 OpenClaw 对话中通过 web_fetch 工具调用 API,示例如下(搜索“Python 编程”):


# 示例:搜索 "Python 编程",调用 DuckDuckGo API

url = 'https://api.duckduckgo.com/?q=Python%20%E7%BC%96%E7%A8%8B&format=json&no_html=1&skip_disambig=1'

print(web_fetch(url=url))

2.1.3 配置验证

配置完成后,重启 OpenClaw 生效。重启后尝试提问:“今天有什么新闻?”,若 OpenClaw 能返回带有 DuckDuckGo 来源的搜索结果,且格式清晰、内容可正常解析,说明配置成功。

避坑提示:若未返回结果,可检查网络连接,或确认 API 参数是否完整(重点核对 format=json 参数),公共 API 存在频率限制,可适当延长请求间隔或使用代理提升稳定性。

2.2 配置 Tavily(Research Skill)

Tavily 是专为 AI Agent 设计的搜索工具,搜索结果质量高、结构化强,且提供免费额度,兼顾实用性与专业性,适合日常办公、商业项目等对搜索质量有要求的场景,国内用户可顺畅使用。

2.2.1 获取 Tavily API Key

  1. 访问 Tavily 官方网站,完成账号注册(流程简单,无需信用卡验证);
  2. 登录后进入 Dashboard(控制台),即可获取个人 API Key,格式通常为 tvly-xxxxxxxxxxxxxxxxx(注意妥善保存,避免泄露);
  3. 注意事项:免费计划每月仅提供 1000 次搜索额度,建议合理分配使用,超出额度后可选择付费升级或等待下月重置。

2.2.2 安装 Tavily Research Skill

Tavily 需通过 OpenClaw 的技能市场安装对应插件,方可在 OpenClaw 中调用,打开 OpenClaw 终端,执行以下任一命令即可完成安装:


# 方法一:使用 ClawHub(OpenClaw 官方技能市场)安装

npx clawhub@latest install tavily-search

# 方法二:使用 Skills 命令直接添加

npx skills add tavily-ai/skills@research

安装完成后,终端会提示“安装成功”,若出现安装失败,可检查网络连接或更新 OpenClaw 至最新版本。

2.2.3 配置 API Key(设置环境变量)

安装技能后,需将获取的 Tavily API Key 设置为系统环境变量,确保 OpenClaw 能正常调用,不同操作系统的设置方法如下:

  • Linux / macOS 系统(终端执行):

    export TAVILY_API_KEY="tvly-your-api-key-here" # 替换为你的实际 API Key

  • Windows 系统(PowerShell 执行):

    $env:TAVILY_API_KEY="tvly-your-api-key-here" # 替换为你的实际 API Key

提示:环境变量仅临时生效,若需长期使用,可将上述命令添加至系统配置文件(如 Linux 的 ~/.bashrc、macOS 的 ~/.zshrc)。

2.2.4 配置验证

重启 OpenClaw 后,尝试提问:“帮我搜索最新的 AI 技术趋势”,若 OpenClaw 能够返回带有明确来源、结构化的搜索结果(如包含标题、链接、摘要),且无报错提示,说明配置成功。

2.3 配置 SearXNG(自建实例)

SearXNG 是一款开源、去中心化的元搜索引擎,可聚合多个搜索服务的结果,且能保证用户隐私不被追踪分析。自建 SearXNG 实例可完全掌控数据流向,但配置难度较高,需具备服务器部署基础,适合对隐私保护和定制化有极致需求的用户。

2.3.1 前提条件

在配置 OpenClaw 集成前,需先完成 SearXNG 实例的自建部署,确保满足以下条件:

  • 已成功部署 SearXNG 实例(推荐使用 Docker 部署,流程更简洁),部署后可正常访问;
  • 已在 SearXNG 配置文件(settings.yml)中启用 JSON 输出格式,确保支持 format=json 参数(核心配置:formats: - html - json);
  • 已获取 SearXNG 实例的访问地址,格式通常为 http://your-searxng-server:8080(your-searxng-server 替换为服务器 IP 或域名)。

补充:SearXNG Docker 快速部署命令(参考):


# 拉取 SearXNG 镜像

docker pull searxng/searxng

# 启动容器,映射 8080 端口(可按需修改)

docker run -d -p 8080:8080 --name searxng searxng/searxng

2.3.2 在 OpenClaw 中配置(两种方法)

由于 SearXNG 是自定义实例,OpenClaw 无内置 Provider,需通过自定义工具或修改配置文件的方式集成,推荐新手使用 web_fetch 工具,操作更简单。

方法一:使用 web_fetch 工具(最直接,适合新手)

无需修改全局配置,直接在 OpenClaw 对话中调用 web_fetch 工具,访问自建的 SearXNG 实例 API,示例如下(搜索“OpenAI”):


# 示例:搜索 "OpenAI",调用自建 SearXNG 实例

url = 'http://your-searxng-server:8080/search?q=OpenAI&format=json' # 替换为你的实例地址

print(web_fetch(url=url))

方法二:修改配置文件(高级,全局生效,需开发基础)

编辑 OpenClaw 配置文件,添加自定义搜索工具,配置如下(需自行编写对应函数实现搜索逻辑):


{

  "tools": {

    "custom_search": {

      "type": "function",

 "function": {

        "name": "custom_search",

        "description": "Search the web using a custom SearXNG instance(通过自定义 SearXNG 实例搜索网络)",

        "parameters": {

          "type": "object",

          "properties": {

            "query": {

              "type": "string",

              "description": "The search query(搜索关键词)"

            }

          },

          "required": ["query"] // 必传参数:搜索关键词

        }

      }

    }

  }

}

注:此方法需要具备一定的开发能力,需编写 custom_search 函数的具体实现,实现与 SearXNG 实例的交互、结果解析等逻辑,适合有开发基础的用户。

2.3.3 配置验证

使用 web_fetch 工具执行上述示例代码,若能成功返回 SearXNG 实例的 JSON 格式搜索结果,且结果可正常解析,说明 OpenClaw 与 SearXNG 实例集成成功。若未返回结果,可检查 SearXNG 实例是否正常运行、实例地址是否正确,或确认 JSON 输出格式是否已启用。

三、总结与常见问题解答

3.1 核心总结

本文详细讲解了三种主流搜索工具在 OpenClaw 中的配置流程,结合各方案的核心优势,再次梳理选型与使用要点,帮助用户快速落地:

  • DuckDuckGo:零成本、零配置,上手最快,适合个人测试、即时查询,核心优势是便捷性,短板是搜索质量一般;
  • Tavily:配置简单、搜索质量高,有免费额度,国内访问友好,适合日常办公、商业项目,兼顾便捷性与专业性;
  • SearXNG(自建):完全免费、隐私性极强,可定制化,适合隐私敏感场景、有服务器部署能力的用户,短板是配置复杂、需维护服务器。

3.2 常见问题解答(FAQ)

  • Q:配置 DuckDuckGo 后,无法返回搜索结果?
    A:检查网络连接是否正常,确认 API 参数是否完整(重点核对 format=json),若频繁请求失败,可添加代理提升稳定性,避免触发公共 API 频率限制。
  • Q:Tavily 提示“API Key 无效”?
    A:确认 API Key 输入正确(注意 tvly-前缀不可遗漏),检查环境变量是否设置成功,重启 OpenClaw 后再次尝试。
  • Q:自建 SearXNG 实例后,OpenClaw 无法调用?
    A:检查 SearXNG 实例是否正常运行,确认配置文件中已启用 JSON 输出格式,实例地址是否正确(避免端口冲突),可直接在浏览器访问实例地址,验证是否能正常返回搜索结果。
  • Q:三种搜索工具能否同时配置?
    A:可以,OpenClaw 支持多搜索工具并存,可根据不同场景在对话中手动指定使用哪种工具,或通过配置文件设置默认工具。

通过本文的配置指南,相信你能快速完成 OpenClaw 搜索功能的部署与优化。根据自身需求选择合适的搜索方案,让 OpenClaw 更好地为你获取实时信息、提升工作与学习效率。若在配置过程中遇到其他问题,可参考 OpenClaw 官方文档或 SearXNG、Tavily 官方教程进一步排查。

本文由mdnice多平台发布

背景

我每天启动 Claude Code 大约 30 次。在不同项目之间切换,每次都要执行同样的流程:

cd ~/Projects/my-app
claude "fix the login bug"

换个项目,再来一遍:

cd ~/Projects/api-server
claude "add rate limiting"

一天 30 次,4 步操作 × 20 秒 = 每天浪费 10 分钟。一年就是 60 小时。

问题不在 Claude Code 本身——它很好用。问题在于启动它的工作流太笨了。所以我做了 GroAsk,一个 macOS 菜单栏的 AI 启动器,用全局快捷键 ⌥Space 一步到位。

一键启动的实现

用户视角

传统方式:
  打开终端 → cd ~/Projects/my-app → claude "fix the login bug" → 等

GroAsk:
  ⌥Space → 输入 "fix the login bug" → 回车

⌥Space(可自定义),弹出输入框。选 Claude Code 通道,写 prompt,回车。终端自动打开,cd 到正确目录,带着 prompt 直接启动 Agent。

关键点:不是打开终端让你输入,而是终端打开时 Claude Code 已经带着你的指令在跑了。

工作目录检测

路径来源有三个优先级:

  1. Finder 联动 — 自动读取当前 Finder 窗口目录
  2. 别名系统/app fix bug 展开为 cd ~/Projects/my-app && claude "fix bug"
  3. 默认目录 — 兜底的工作路径

四种终端的自动化差异

这是项目里最有技术含量的部分。macOS 上四种主流终端,每一种的自动化实现完全不同。

Terminal.app — AppleScript do script

tell application "Terminal"
    activate
    do script "cd ~/Projects/my-app && claude \"fix the login bug\""
end tell

最标准的实现。AppleScript 字典完整,可以控制窗口、Tab、执行任意命令。

iTerm2 — AppleScript create window with profile

tell application "iTerm"
    activate
    create window with profile "Default" command "cd ~/Projects/my-app && claude \"fix the login bug\""
end tell

和 Terminal.app 类似,但 API 更现代。Profile 支持让你可以指定特定的终端配置。

Ghostty — -e 参数 + login shell 包装

Ghostty 是 Mitchell Hashimoto 做的新终端,性能很好但没有 AppleScript 支持。用 -e 参数启动:

open -na Ghostty --args -e bash -l -c 'cd ~/Projects/my-app && claude "fix the login bug"'

踩坑点-e 是替换 shell 而不是在 shell 里执行,.zshrc 不会加载,PATH 不完整。所以必须包一层 bash -l -c 来加载完整的 shell profile。

Warp — YAML Launch Config + URI scheme

Warp 是最棘手的。没有 AppleScript,没有 -e 参数,没有任何编程接口。

唯一能用的是 Launch Configuration 机制:

# ~/.warp/launch_configurations/groask_session.yaml
---
name: groask_session
windows:
  - tabs:
      - layout:
          cwd: ~/Projects/my-app
          command: claude "fix the login bug"

然后通过 URI scheme 触发:

open "warp://action/launch?config=groask_session"

GroAsk 每次启动时动态生成这个 YAML 文件,写入 Warp 配置目录,再触发 URI scheme。多了一步文件 I/O,但用户体验和其他终端一致。

为什么不统一抽象?

因为没法统一。四种终端的能力边界完全不同:

终端AppleScript-e 参数配置文件触发窗口控制
Terminal.app完整--完整
iTerm2完整--完整
Ghostty有(替换 shell)-
Warp

只能逐个适配,做四套实现。

一键安装 CLI 工具

依赖链自动处理

不同 CLI AI 工具的安装路径差异很大:

有 curl 安装器的工具(Claude Code、Kimi Code):

# 一行搞定
curl -fsSL https://cli.example.com/install.sh | bash
# 自动追加 PATH 到 .zshrc
echo 'export PATH="$HOME/.local/bin:$PATH"' >> ~/.zshrc

依赖 npm 的工具(Gemini CLI、Codex)需要处理依赖链:

检测 npm → 有就直接装
         → 没有,检测 fnm → 有就用 fnm 装 Node.js 再装 CLI
                          → 没有 → 装 fnm → 装 Node.js → 装 CLI

全程不需要 sudo、Homebrew、Xcode Command Line Tools。

安装状态轮询

安装触发后,后台每 2 秒执行一次检测:

bash -l -c 'command -v claude'

bash -l 加载完整 shell 环境,确保能发现 fnm 刚安装的工具。检测到就立刻刷新 UI。设了 3 分钟超时保护。

PATH 问题的解决

macOS GUI 应用不加载 shell profile,PATH 和终端里不一样。GroAsk 的做法:

bash -l -c 'printf MARKER%s "$PATH"'

MARKER 前缀隔离 conda/pyenv 等工具在 shell 初始化时输出到 stdout 的噪声。

再加上文件系统扫描兜底——扫描 ~/.local/bin~/.cargo/bin、Homebrew 路径、nvm/fnm/Volta/mise 的安装路径,覆盖所有安装方式。

不只是 Claude Code

GroAsk 支持 6 个 CLI AI + 4 个 Web AI:

  • CLI:Claude Code、Gemini CLI、Codex、CodeBuddy、Kimi Code、Qwen Code
  • Web:ChatGPT、Claude、Gemini、Monica(自动注入 prompt 到输入框)

同一个 ⌥Space 输入框,Tab 切换不同 AI。还支持划词即问——选中文本,按快捷键,自动填入输入框发给 AI。

竞品对比

| 能力 | Claude Code Now | Raycast 插件 | GroAsk |
|------|:-:|:-:|:-:|
| 启动方式 | Dock 图标 | Raycast 搜索 | ⌥Space 全局快捷键 |
| 带 prompt 启动 | 不支持 | 不支持 | 支持 |
| 多终端 | 仅 Terminal.app | Terminal/Alacritty/Ghostty/Warp | Terminal/iTerm2/Ghostty/Warp |
| 图形化安装 | 不支持 | 不支持 | 支持,依赖链全自动 |
| 多 AI 切换 | 仅 Claude Code | 仅 Claude Code | 6 CLI + 4 Web AI |
| 划词即问 | 不支持 | 不支持 | 支持 |

用 Claude Code 做了一个 Claude Code 启动器

GroAsk 本身就是 Claude Code 协作的产物:

  • 190 次提交,49% 由 Claude Code 协作完成
  • 14 天从零到上线
  • 5,600 行 Swift(纯 AppKit)+ 1,200 行 Server(Cloudflare Workers)
  • 内存占用 < 30MB

每个模块——AppleScript 终端控制、WebKit 注入脚本、PATH 环境检测、Cloudflare Workers 后端——都是我定方向、Claude Code 写实现、我审代码的循环。


GroAsk 免费,macOS 原生,100% 本地桥接,不存数据。

欢迎 Star,有问题到 GitHub Discussions 聊。

道路表面多类型缺陷的图像识别数据集分享(适用于目标检测任务)

数据集分享

如需下载该数据集,可通过以下方式获取:

引言

随着城市化与交通运输业的快速发展,道路基础设施的健康状况直接关系到出行安全与城市运行效率。据统计,全球每年因道路缺陷引发的交通事故造成数十万人死亡,经济损失高达数千亿美元。长期高强度的使用、气候变化以及施工质量差异,都会导致道路表面出现裂缝、坑洼、井盖下沉及修补不良等缺陷。这些问题不仅影响驾驶舒适度,还可能引发交通事故,增加道路养护成本。

传统的道路巡检方式主要依靠人工目测或简单的仪器检测,存在效率低、准确性不足、主观性强等局限。例如,人工巡检需要大量的人力物力,检测速度慢,难以实现对大面积道路的快速覆盖;检测结果依赖于巡检人员的经验和责任心,容易出现漏检、误检等情况。

近年来,随着深度学习与计算机视觉技术的飞速发展,利用图像识别算法实现道路缺陷的自动化检测与分类成为研究热点。这种方法通过训练深度学习模型,从道路图像中自动识别缺陷类型和位置,具有高效、准确、可扩展性强等优点。然而,要开发出准确、可靠的道路缺陷检测模型,高质量、多样化且已标注的数据集是关键基础。

为满足这一需求,我们构建了一个涵盖多类缺陷的道路表面缺陷数据集,共计6000张高分辨率图片,涵盖了常见的裂缝、井盖、坑洼、修补区域等多种复杂场景。该数据集采用YOLO项目标准格式,并已完成train、val、test划分与标注,可直接用于深度学习模型的训练与验证。本文将对该数据集进行详细介绍,包括数据集背景、概述、结构、特点、适用场景等内容,旨在为相关研究和应用提供参考。

数据集背景

道路是城市基础设施的重要组成部分,其质量直接影响到交通运行效率和交通安全。据交通运输部统计,我国公路总里程已超过530万公里,其中高速公路总里程超过16万公里,居世界第一。随着公路里程的不断增加和交通量的持续增长,道路养护任务日益繁重。

道路表面缺陷是道路养护中的常见问题,主要包括以下几种类型:

  1. 裂缝:由于路面材料老化、温度变化、荷载作用等原因导致的路面开裂,是最常见的道路缺陷之一。裂缝如果不及时处理,会逐渐扩大,导致路面结构损坏。
  2. 坑洼:由于路面材料松散、水损害、重载车辆碾压等原因导致的路面局部下沉,形成坑洞。坑洼会影响车辆行驶稳定性,增加燃油消耗,甚至引发交通事故。
  3. 井盖:道路上的井盖如果安装不规范或长期受到车辆碾压,会出现下沉、凸起、破损等问题,影响道路平整度和行车安全。
  4. 修补区域:道路修补后形成的区域,如果修补质量不佳,会出现修补材料脱落、与原路面结合不良等问题,影响道路美观和使用寿命。

传统的道路缺陷检测方法主要包括以下几种:

  1. 人工巡检:巡检人员通过肉眼观察或简单工具检测道路缺陷,记录缺陷位置和类型。这种方法效率低,劳动强度大,容易受到人为因素影响。
  2. 车载检测设备:使用安装在车辆上的激光测距仪、摄像头等设备,采集道路表面数据,然后通过人工分析或简单的算法处理识别缺陷。这种方法效率较高,但设备成本昂贵,数据处理复杂。
  3. 地面激光扫描:使用地面激光扫描仪采集道路表面三维数据,通过分析数据识别缺陷。这种方法精度高,但操作复杂,成本高昂,难以实现大面积检测。

基于深度学习的图像识别技术为道路缺陷检测提供了新的解决方案。这种方法通过训练深度学习模型,从道路图像中自动识别缺陷类型和位置,具有以下优势:

  1. 高效快速:可以在车辆行驶过程中实时采集和分析道路图像,大大提高检测效率。
  2. 客观准确:不受操作人员经验和主观因素的影响,检测结果更加客观可靠。
  3. 成本低廉:只需要普通的摄像头和计算设备,成本远低于传统的检测设备。
  4. 可扩展性强:可以通过增加训练数据和优化模型,不断提高检测精度和覆盖范围。

然而,要开发出准确、可靠的道路缺陷检测模型,高质量、多样化且已标注的数据集是关键基础。目前,公开可用的道路缺陷图像数据集存在以下问题:

  1. 样本数量不足:许多数据集样本数量较少,难以支持深度学习模型的充分训练。
  2. 类别覆盖有限:部分数据集只覆盖少数几种道路缺陷类型,难以满足实际检测需求。
  3. 场景单一:许多数据集的图像拍摄场景较为单一,难以适应实际应用中的复杂场景。
  4. 标注质量参差不齐:一些数据集的标注不够准确或不一致,影响模型训练效果。

为应对这些挑战,我们构建了本数据集,旨在为道路缺陷检测算法的研究与落地提供高质量的数据支持。

数据集概述

本数据集专注于道路表面缺陷检测与识别,共计6000张高分辨率图片,涵盖了常见的裂缝、井盖、坑洼、修补区域等多种复杂场景。所有图片均经过精心筛选与标注,确保数据的准确性与代表性。

基本信息

  • 图片总数:6000张
  • 图像格式:JPG
  • 标注格式:YOLO格式(每张图片对应一个txt标注文件)
  • 类别数量:8类
  • 类别定义

    1. Crack —— 道路裂缝
    2. Manhole —— 井盖
    3. Net —— 网状裂缝
    4. Pothole —— 坑洼
    5. Patch-Crack —— 修补裂缝
    6. Patch-Net —— 修补网状裂缝
    7. Patch-Pothole —— 修补坑洼
    8. Other —— 其他异常
  • 数据划分

    • 训练集(train):70%(约4200张)
    • 验证集(val):20%(约1200张)
    • 测试集(test):10%(约600张)
  • 图像特征

    • 分辨率统一为高清规格,适合深度学习训练
    • 涵盖白天、夜间、阴影、雨后等复杂环境,增强鲁棒性
    • 不同路段(高速、城市道路、乡村道路)均有采样,保证多样性

文件结构

本数据集采用标准的文件夹结构进行组织,具体如下:

dataset/
├── train/
│   ├── images/
│   └── labels/
├── val/
│   ├── images/
│   └── labels/
└── test/
    ├── images/
    └── labels/

其中,images文件夹存放不同划分的图像文件,labels文件夹存放对应的YOLO格式标注文件。

标注格式

本数据集采用YOLO标准格式进行标注,每个标注文件对应一张图像,文件名与图像文件名相同,后缀为.txt。标注文件的每一行表示一个目标,格式如下:

<class_id> <x_center> <y_center> <width> <height>

其中,class_id为类别编号,x_centery_center为目标中心点的归一化坐标,widthheight为目标的归一化宽高。坐标值和宽高均为相对于图像宽度和高度的归一化值,范围在0到1之间。

数据集详情

数据采集与处理

本数据集的图像来源于多个城市的道路巡检,涵盖了不同类型、不同等级的道路。为确保数据集的质量和多样性,我们在数据采集过程中遵循了以下原则:

  1. 多场景覆盖:采集不同城市、不同路段、不同天气条件下的道路图像,确保数据集能够覆盖各种实际场景。
  2. 多缺陷类型:采集包含裂缝、井盖、坑洼、修补区域等多种缺陷类型的图像,确保数据集的类别多样性。
  3. 高质量图像:使用高分辨率摄像头采集图像,确保图像清晰,缺陷特征明显。
  4. 标注准确性:由专业人员对图像中的缺陷进行手动标注,确保标注的准确性和一致性。

在数据处理过程中,我们对图像进行了以下处理:

  1. 图像预处理:对采集到的图像进行去噪、增强等处理,提高图像质量和缺陷的可见性。
  2. 目标标注:由专业人员使用标注工具对图像中的缺陷进行手动标注,绘制边界框并标记类别。
  3. 格式转换:将标注结果转换为YOLO标准格式,生成对应的.txt标注文件。
  4. 数据划分:按照70:20:10的比例将数据划分为训练集、验证集和测试集,确保数据划分的合理性。
  5. 质量检查:对处理后的数据进行质量检查,确保标注的准确性和一致性,去除质量不佳的图像。

类别分布

本数据集包含8类道路表面缺陷,各类别的样本数量分布如下:

类别编号类别名称样本数量(约)说明
0Crack1500+道路表面的线性裂缝
1Manhole1200+道路上的井盖及其周围区域
2Net800+道路表面的网状裂缝
3Pothole1000+道路表面的坑洼
4Patch-Crack500+修补后的裂缝区域
5Patch-Net300+修补后的网状裂缝区域
6Patch-Pothole400+修补后的坑洼区域
7Other300+其他道路表面异常

注:样本数量为估计值,实际样本数量可能因数据采集和处理过程而有所差异。

场景多样性

本数据集的图像涵盖了多种实际场景,包括:

  1. 不同道路类型:高速公路、城市主干道、次干道、乡村道路等。
  2. 不同天气条件:晴天、阴天、雨天、雪天等。
  3. 不同光照条件:白天、黄昏、夜间、阴影等。
  4. 不同季节:春季、夏季、秋季、冬季。
  5. 不同路面材料:沥青路面、水泥路面、砖石路面等。

这种场景多样性使得数据集能够更好地模拟实际道路环境,提高模型的泛化能力。

image-20250819151030455

image-20250819150906330

image-20250819150951721

image-20250819151005920

数据处理流程

为确保数据集的质量和可用性,我们在构建过程中遵循了严格的数据处理流程,具体步骤如下:

flowchart TD
    A[数据采集] --> B[图像预处理]
    B --> C[质量评估]
    C --> D[目标标注]
    D --> E[标注验证]
    E --> F[格式转换]
    F --> G[数据划分]
    G --> H[质量检查]
    H --> I[数据集发布]
  1. 数据采集:使用高分辨率摄像头在不同场景下采集道路表面图像
  2. 图像预处理:对采集到的图像进行去噪、增强等处理,提高图像质量
  3. 质量评估:对预处理后的图像进行质量评估,筛选出清晰、具有代表性的图像
  4. 目标标注:由专业人员对图像中的缺陷进行手动标注,绘制边界框并标记类别
  5. 标注验证:对标注结果进行验证,确保标注的准确性和一致性
  6. 格式转换:将标注结果转换为YOLO标准格式,生成对应的.txt标注文件
  7. 数据划分:按照70:20:10的比例将数据划分为训练集、验证集和测试集
  8. 质量检查:对处理后的数据进行最终质量检查,确保数据的完整性和一致性
  9. 数据集发布:打包发布数据集,提供下载链接

数据集特点

本数据集具有以下显著特点:

1. 样本数量充足

共计6000张高分辨率图片,涵盖了8类道路表面缺陷,每个类别均有足够的样本量,确保模型训练的充分性。与其他同类数据集相比,本数据集的样本数量更多,类别覆盖更全面。

2. 场景多样性强

数据集涵盖了不同城市、不同道路类型、不同天气条件、不同光照条件下的道路图像,场景多样性强。这种多样性使得模型在训练过程中能够学习到不同场景下的缺陷特征,提高模型的泛化能力。

3. 标注质量高

所有图像均由专业人员进行手动标注,标注准确、一致。标注过程中严格遵循统一的标注规范,确保边界框的准确性和类别的一致性。高质量的标注为模型训练提供了可靠的基础。

4. 格式标准统一

数据集采用YOLO标准格式进行标注,已按照训练集、验证集和测试集进行了合理划分,可直接用于主流目标检测框架的训练和验证。用户无需进行格式转换或数据划分,开箱即用,提高了数据集的易用性。

5. 应用价值广泛

数据集涵盖了道路表面常见的多种缺陷类型,应用价值广泛。可用于道路缺陷检测、智能交通系统、自动驾驶感知等多个领域,为相关研究和应用提供数据支持。

6. 贴近实际场景

数据集的图像均来自实际道路巡检,贴近实际应用场景。包含了各种复杂情况,如不同光照、不同天气、不同路面材料等,使得模型在实际应用中能够更好地适应各种情况。

7. 分辨率高

数据集的图像分辨率统一为高清规格,缺陷特征清晰可见。高分辨率图像有助于模型学习到更多的细节特征,提高检测精度。

适用场景

本数据集可广泛应用于以下研究与工程应用场景:

1. 道路表面缺陷检测

可直接用于训练YOLOv5、YOLOv8等目标检测模型,实现对道路表面缺陷的自动检测和分类。通过在本数据集上训练模型,可以提高道路缺陷检测的准确率和效率,为道路养护提供技术支持。

2. 智能交通系统(ITS)

可作为智能交通系统的感知层数据支撑,用于城市道路养护、交通安全监测等。例如,可以集成到城市交通管理系统中,实时监测道路状况,及时发现和处理道路缺陷,提高道路养护效率和交通安全水平。

3. 自动驾驶感知模块

在自动驾驶系统中,道路表面信息是重要的环境感知因素。本数据集可用于训练自动驾驶系统的感知模块,提高车辆对道路表面状况的识别能力,为路径规划和驾驶决策提供依据。

4. 深度学习算法研究

可作为目标检测、分割、异常检测等领域的benchmark,用于验证新模型的有效性。例如,可以用于比较不同目标检测算法在道路缺陷检测任务上的性能,或者用于研究新的目标检测方法和技术。

5. 实际工程落地

适用于道路养护部门开发的AI道路巡检机器人或无人机检测系统,帮助减少人力巡检成本,提高检测效率。例如,可以部署在巡检车辆或无人机上,实现对道路的自动巡检和缺陷检测。

6. 道路养护决策支持

可用于构建道路养护决策支持系统,基于检测结果评估道路状况,制定合理的养护计划。例如,可以根据缺陷的类型、严重程度和分布情况,预测道路的使用寿命,优化养护资源分配。

7. 城市管理系统

可集成到城市管理系统中,作为智慧城市建设的一部分。例如,可以与地理信息系统(GIS)结合,实现道路缺陷的空间分布分析,为城市规划和建设提供参考。

模型训练建议

针对本数据集的特点,我们提出以下模型训练建议:

1. 模型选择

对于道路缺陷检测任务,建议使用以下模型:

  • YOLOv8:性能均衡,适合大多数应用场景,特别是需要实时检测的场景
  • YOLOv11:最新版本,精度和速度都有提升,适合对性能要求较高的场景
  • Faster R-CNN:精度较高,适合对精度要求高、对速度要求不高的场景
  • EfficientDet:效率较高,适合资源受限的场景

2. 数据增强

由于道路缺陷检测任务的特殊性,建议使用以下数据增强技术:

  • 随机翻转:水平翻转和垂直翻转,增加数据多样性
  • 随机旋转:随机旋转图像,增强模型对缺陷不同角度的适应能力
  • 亮度和对比度调整:随机调整图像的亮度和对比度,增强模型对不同光照条件的适应能力
  • 随机裁剪:随机裁剪图像的一部分,增强模型对缺陷不同大小的适应能力
  • 马赛克增强:将多张图像拼接成一张,增加小目标的数量
  • 高斯噪声:添加适量的高斯噪声,增强模型对噪声的鲁棒性

3. 训练策略

  • 批量大小:根据硬件资源选择合适的批量大小,建议使用8-32
  • 学习率:初始学习率设置为0.001,使用余弦退火策略调整学习率
  • 优化器:使用AdamW优化器,权重衰减设置为0.0005
  • 训练轮数:建议训练100-300轮,根据验证集性能动态调整
  • 早停策略:当验证集性能连续多个轮次没有提升时,停止训练
  • 迁移学习:可以使用在COCO数据集上预训练的模型权重,加速模型收敛

4. 评估指标

使用以下指标评估模型性能:

  • mAP@0.5:IoU阈值为0.5时的平均精度
  • mAP@0.5:0.95:IoU阈值从0.5到0.95,步长为0.05时的平均精度
  • 精确率:正确预测的正样本占总预测正样本的比例
  • 召回率:正确预测的正样本占总实际正样本的比例
  • F1-score:精确率和召回率的调和平均值
  • 推理速度:模型的推理时间,用于评估实时性能

5. 模型优化

  • 模型剪枝:去除冗余的神经元和连接,减少模型大小
  • 模型量化:将模型权重从32位浮点数量化为8位整数,减少模型大小和计算复杂度
  • 知识蒸馏:利用大模型的知识指导小模型的训练,提高小模型的性能
  • 部署优化:针对不同部署平台进行优化,如TensorRT、ONNX Runtime等

应用案例

案例一:智能道路巡检系统

基于本数据集训练的YOLOv8模型,开发了一款智能道路巡检系统。该系统通过安装在巡检车辆上的摄像头实时采集道路图像,然后利用训练好的模型自动识别图像中的道路缺陷。系统会生成巡检报告,标记出缺陷位置、类型和严重程度,并提供养护建议。该系统已在多个城市的道路养护部门试用,巡检效率提高了70%以上,缺陷检测准确率达到90%以上。

案例二:城市道路养护管理系统

将训练好的模型集成到城市道路养护管理系统中,实现对城市道路状况的实时监测和管理。系统通过分析巡检车辆采集的图像,自动识别道路缺陷,生成缺陷分布图和养护优先级报告。养护部门可以根据这些信息制定合理的养护计划,优化养护资源分配。该系统已在某省会城市部署,道路养护效率提高了50%以上,养护成本降低了30%以上。

案例三:自动驾驶感知系统

利用本数据集训练的模型,开发了一款自动驾驶感知系统的道路表面状况检测模块。该模块通过车载摄像头采集道路图像,实时识别道路表面的缺陷,如裂缝、坑洼、井盖等,并将这些信息传递给自动驾驶决策系统。决策系统会根据道路状况调整行驶策略,如减速、绕避等,提高自动驾驶的安全性和舒适性。该模块已在某自动驾驶测试车辆上试用,车辆对道路缺陷的识别准确率达到95%以上,能够及时调整行驶策略,避免因道路缺陷引发的安全问题。

案例四:无人机道路巡检系统

将训练好的轻量化模型部署到无人机上,开发了一款无人机道路巡检系统。该系统通过无人机航拍获取道路图像,然后利用训练好的模型自动识别图像中的道路缺陷。无人机可以快速覆盖大面积道路,特别适合交通繁忙的高速公路和难以到达的偏远地区。该系统已在某高速公路管理局试用,巡检速度提高了10倍以上,能够及时发现和处理道路缺陷,提高高速公路的安全性和畅通性。

技术挑战与解决方案

在构建和使用本数据集的过程中,我们遇到了以下技术挑战,并提出了相应的解决方案:

1. 缺陷多样性和复杂性

挑战:道路缺陷类型多样,形态各异,不同类型的缺陷特征差异较大,同一类型的缺陷在不同场景下也有很大差异。
解决方案

  • 收集多样化的缺陷样本,确保数据集能够覆盖各种类型和形态的缺陷
  • 采用数据增强技术,增加模型对不同形态缺陷的适应能力
  • 设计鲁棒的特征提取网络,能够学习到缺陷的本质特征

2. 光照和天气条件变化

挑战:不同光照和天气条件下,道路缺陷的外观差异很大,模型在一种条件下训练的效果可能在另一种条件下表现不佳。
解决方案

  • 收集不同光照和天气条件下的缺陷样本,确保数据集的多样性
  • 采用数据增强技术,模拟不同光照和天气条件下的图像
  • 设计光照不变的特征提取方法,减少光照对检测结果的影响

3. 小目标检测困难

挑战:一些道路缺陷(如细小裂缝)在图像中占比较小,属于小目标,传统的目标检测模型难以有效检测。
解决方案

  • 使用专门的小目标检测优化策略,如FPN、PAN等特征融合方法
  • 调整模型的锚框设置,使其更适合小目标的检测
  • 采用马赛克增强等数据增强技术,增加小目标的比例

4. 模型部署资源受限

挑战:在实际应用中,如嵌入式设备、移动设备等资源受限的平台上部署模型,需要考虑模型大小和计算复杂度。
解决方案

  • 采用模型压缩和量化技术,减少模型大小和计算复杂度
  • 开发轻量级模型,适合在资源受限的平台上运行
  • 利用边缘计算技术,将部分计算任务放在边缘设备上进行

5. 标注工作量大

挑战:手动标注道路缺陷工作量大,效率低,成本高。
解决方案

  • 开发半自动化标注工具,提高标注效率
  • 采用多人标注和交叉验证的方式,确保标注的准确性
  • 对标注人员进行培训,提高标注的一致性和准确性

数据集扩展与未来规划

本数据集是我们在道路缺陷检测领域的初步尝试,未来我们计划从以下几个方面对数据集进行扩展和完善:

  1. 增加样本数量:进一步扩大数据集规模,增加更多的图像样本,提高数据集的多样性和代表性。特别是增加来自不同地区、不同气候条件的道路缺陷样本,确保数据集能够覆盖更多的实际场景。
  2. 扩展类别覆盖:增加更多的道路缺陷类型,如路面沉降、车辙、泛油等,构建一个更全面的道路缺陷检测数据集。
  3. 添加多模态数据:结合激光雷达、惯性导航系统(INS)等多模态数据,构建多模态道路缺陷数据集。多模态数据可以提供更多的信息,如道路表面的三维信息、车辆的位置和姿态信息等,提高缺陷检测的准确性和可靠性。
  4. 引入时序信息:添加同一道路在不同时间的图像,捕捉道路缺陷的发展变化过程,支持时序分析和缺陷预测。
  5. 提供预训练模型:基于扩展后的数据集,训练并发布预训练模型,方便用户直接使用。预训练模型可以大大减少用户的训练时间和计算资源需求。
  6. 建立社区平台:建立道路缺陷检测数据集社区平台,鼓励用户贡献数据和标注,共同完善数据集。社区平台可以促进数据共享和技术交流,推动道路缺陷检测技术的发展。
  7. 开发标注工具:开发专门的道路缺陷标注工具,提高标注效率和准确性。标注工具可以自动检测和标注一些明显的缺陷,减少人工标注的工作量。
  8. 构建基准测试:基于数据集构建道路缺陷检测的基准测试,为不同算法的性能比较提供标准平台。基准测试可以促进算法创新和技术进步,推动道路缺陷检测技术的发展。

结语

道路是城市的动脉,其质量直接关系到城市的运行效率和居民的生活质量。随着城市化进程的加快和交通量的持续增长,道路养护任务日益繁重,传统的人工巡检方式已经难以适应现代城市发展的需求。

基于深度学习的道路缺陷检测技术为道路养护提供了新的解决方案,能够实现对道路缺陷的自动检测和分类,提高巡检效率和准确性。而高质量、多样化的数据集是推动这一技术发展的关键基础。

本数据集通过系统性地收集、整理和标注道路表面缺陷图像,为道路缺陷检测算法的研究与落地提供了有力支持。数据集共计6000张高分辨率图片,涵盖了8类道路表面缺陷,场景多样性强,标注质量高,格式标准统一,应用价值广泛。

我们希望通过本数据集的发布,能够促进道路缺陷检测技术的发展,推动智能交通系统和智慧城市建设的进步。我们诚邀学术界与工业界的研究者在此基础上深入探索,共同推动道路缺陷检测技术的创新和应用,为提高道路养护效率、保障交通安全、建设智慧城市做出贡献。

总结

本次发布的《道路表面多类型缺陷的图像识别数据集》为道路养护、智能交通、自动驾驶等领域提供了一个高质量、结构规范的图像识别基准数据集。数据集共包含6000张已标注图像,涵盖了8类道路表面常见缺陷,采用标准YOLO格式,已按训练、验证、测试集划分完毕,可直接应用于YOLOv5、YOLOv8等主流目标检测框架。

该数据集具有样本数量充足、场景多样性强、标注质量高、格式标准统一、应用价值广泛、贴近实际场景、分辨率高等特点,不仅适合用于常规的目标检测任务,也适合开展小目标检测、多模态融合、模型压缩与部署等前沿研究,特别契合道路缺陷检测、智能交通系统、自动驾驶感知等实际应用需求。

通过本数据集的使用和相关技术的应用,我们相信道路缺陷检测技术将会取得更大的突破,为道路养护和交通安全提供更加有力的支持,为智能交通系统和智慧城市建设做出更大的贡献。