尧图网络 高端网站定制 · 原创设计
免费咨询热线
400-888-6620
免费获取方案
ESP32-S3马赛克动画显示:从图像解码到LVGL动效实践
前段时间翻乐鑫Espressif的社区项目时注意到一个名字挺抓眼球的ESP-Mosaico。Mosaico在西班牙语里就是“马赛克”单看ESP前缀就知道这又是一块面向ESP32系列芯片折腾的项目。不少朋友第一反应是“马赛克打码”其实这个项目完全没有往那种方向走它倒是把图像分成一块块色块再通过屏幕逐渐拼合成一幅完整画面整个过程看上去像是一幅像素画自己慢慢组装出来视觉冲击力很强。这种项目的实用价值很直白它把“图像解码、像素处理、LCD显示、动画调度”这四件事全部压到一颗MCU上而且不需要外接显卡或昂贵的处理器一颗ESP32-S3加一块小屏幕就能跑。对刚接触嵌入式显示的朋友来说这是一条非常合适的练手路线因为每层都有肉眼可见的反馈对想搞创意硬件的朋友来说它又是一个可以快速出效果的小品项目拍照、取色、动画节奏都能自己定义。下面从头到尾拆解一下我把跑通这个项目过程中涉及的选型逻辑、核心算法、代码实现和调试心得都写出来顺便解决几个最常见的新手问题。1. 先说清楚ESP-Mosaico 到底在做什么1.1 不仅仅是“马赛克打码”很多人听到马赛克就只想到那种模糊化处理但ESP-Mosaico的思路正好反过来。它不是把高清图变糊而是故意把画面打散成整齐的色块每个色块保持自己独立的颜色和位置然后在一段时间内将这些色块依次点亮或拼合形成动态的“由碎片到完整”的视觉过程。简单来说项目干了三件事读取一张图片解码成屏幕上能直接显示的像素数据。将整张图片划分成规则网格比如横向20格、纵向20格每个格子取一个代表颜色。通过动画逻辑让这些代表颜色的色块按照设定顺序逐块出现或者分批从暗变亮最终呈现原始图像的轮廓和色彩。跑出来的效果很有“像素艺术”的感觉但又比单纯放大像素多了一层动态组装的过程。你可以把它理解为把一张照片变成大量乐高积木然后演奏慢动作一样一块块搭起来。正因为如此它在电子相框、桌面摆件、创客展台这类场景都很合适。1.2 谁适合拿这个项目练手这项目定位非常清晰适合下面几类人玩过ESP32基础GPIO、串口但还没接触过LCD显示的朋友。它让你第一次完整感受到“显示驱动”和“UI框架”是怎么回事。想做“视觉感官类”作品的创客。不需要复杂云平台一块板子加一个屏幕就能产生很耐看的动态视觉。想理解图像处理最基础概念的嵌入式爱好者。先把一张位图拆成网格、取平均色、再组合显示这比一上来就上各种高大上算法要友好得多。对完全没有经验的人来说主要门槛在于ESP-IDF环境搭建和LVGL基础配置这两块我会在后面的实操部分尽量写清楚照着做基本不会有太大障碍。2. 硬件和屏幕的选型逻辑2.1 为什么核心芯片是ESP32-S3如果你搜过乐鑫相关的显示屏项目大概率会发现ESP32-S3出镜率极高这不是偶然。做马赛克这种带图像处理加动画渲染的项目芯片需要满足几个条件首先是内存。图像数据非常吃内存一张320x240的RGB565图片就要大概150KB如果要做动画缓冲还得再预留一到两份屏幕缓冲区。普通ESP32的520KB SRAM如果省着点用可能刚好够但想从容地同时放原图、马赛克缓冲区、LVGL绘制缓冲和系统运行堆就太紧张了。ESP32-S3可以外接并映射8MB的PSRAM也就是所谓的“N16R8”或“N8R8”版本模块跑这种项目就从容得多大图完全不用像以前那样拆东墙补西墙。其次是显示接口。ESP32-S3内置LCD外设接口可以直接驱动RGB并口屏或者用SPI方式连接常见彩屏硬件上天生适合做小屏幕设备。第三是算力。双核LX7主频可以跑到240MHz还配套了一些针对图像处理的SIMD指令。虽然马赛克算法本身不算重但如果要做实时摄像头取景、或者每帧更新几百个色块的颜色原生指令的优化空间都会被拿进来用。当然如果你手头只有普通ESP32也不是完全不能玩把图片压缩到160x128网格再小一点静态马赛克效果仍然可以跑起来只是动画流畅度和可玩空间会差一些。如果是从零开始买板子直接选带PSRAM的ESP32-S3即可。2.2 屏幕与显示接口的选择做马赛克显示效果对屏幕的最低要求是能显示彩色、分辨率不要太低、刷新速度够用。我推荐从1.8英寸到2.4英寸的小尺寸彩屏入手。小屏的像素总数少内存压力低动画更容易做流畅看起来也更精致。最常见的驱动方案是ST7735、ST7789这类SPI接口屏接线少、资料多、驱动成熟。分辨率建议选择240x320或240x240。240x320的屏算是黄金选择尺寸够展示细节像素量又不至于让MCU处理不过来。如果再大例如3.5寸480x320虽然效果更震撼但对PSRAM带宽和SPI刷新时钟都提出了更高要求新手初期会容易卡顿掉帧如果只是小尺寸圆形屏例如1.28寸圆形LCD也能跑马赛克网格会更少出片非常有装饰感。关于并口屏和SPI屏的选择我个人的建议是入门阶段优先用SPI屏。因为并口屏需要占用更多GPIO接线复杂而且底层驱动需要专门适配SPI屏只需很少线就能快速显示先看到效果比追求极致性能更重要。2.3 实用列表我手里这套跑的配置前面讲偏理论这里给一份我自己实际在跑的搭配供参考硬件/软件选择说明主控板ESP32-S3-DevKitC-18MB PSRAM版带模组是N16R8或N8R8比较合适屏幕2.4英寸SPI彩屏ST7789驱动240x320性价比高资料好找屏幕连接GPIO10CS、GPIO11SCLK、GPIO12SDA等不同开发板引脚不一样按丝印和例程调整图像源SD卡或直接把C数组图片编译进固件新手阶段推荐先编译进固件省去文件系统调试图形库LVGL v8.3成熟、组件化、文档多框架ESP-IDF v5.2以上用到新版LCD驱动组件接线方面ST7789通常有八个引脚VCC、GND、SCL、SDA、RES、DC、CS、BLK。VCC接3.3VBLK背光也要接3.3V或独立上拉不然屏幕亮不起来。我调试时曾把BLK漏接屏幕一直黑误以为是代码问题排查了很久才发现。这类小坑后面汇总时再展开。3. 软件工程最简但完整的系统搭建3.1 开发环境ESP-IDF LVGL很多朋友一听到ESP-IDF就有点怵其实比起以前跑裸机代码它已经封装得很好了。ESP-Mosaico这类项目我建议直接用乐鑫官方的ESP-IDF扩展组件生态把LVGL当作一个component加进工程里而不是手动下载源码。这样以后更新也方便。创建工程我用的是IDF模板方式执行idf.py create-project esp_mosaico然后在工程根目录的main文件夹下写代码。关键是main/idf_component.yml它声明项目依赖dependencies: idf: 5.2 lvgl/lvgl: ^8.3.0 espressif/esp_lcd_st7789: *版本号可以根据实际情况调整。写完这个文件后执行idf.py build时ESP-IDF会自动从组件仓库拉取LVGL和ST7789驱动非常省事。这里需要注意一个点LVGL本身依赖lv_drivers或者esp_lcd这种底层驱动框架ESP-IDF的esp_lcd组件是独立存在的不需要再额外配置底层接口比老式手动移植少走很多弯路。3.2 LCD初始化与LVGL接入LCD初始化看似代码量多其实核心逻辑很固定。首先要配置SPI主机然后是LCD面板参数例如屏幕宽高、颜色字节序、RGB565或RGB888格式最后把LVGL的显示驱动绑定到LCD面板上。初始化SPI时有个关键参数叫clk_flags建议设置SPI_MASTER_FREQ_80M的时钟源标志否则SPI时钟容易在GFX场景下出现不稳定。我实际跑下来ST7789这类屏跑40MHz到60MHz的SPI时钟都没问题再高就要看接线质量和屏幕个体体质了。LVGL接入时需要提供至少一块绘图缓冲。很多人纠结缓冲区要多大初期可以用两行240像素宽的缓冲区大概2x320x2字节约1.2KB但刷新时会不够顺滑。有不差内存的中配方案如下static lv_disp_draw_buf_t draw_buf; static lv_color_t buf_1[320 * 40]; static lv_color_t buf_2[320 * 40]; lv_disp_draw_buf_init(draw_buf, buf_1, buf_2, 320 * 40);这样每块缓冲区能容纳40行两块交替刷新动画流畅度会好很多。ESP32-S3有内部SRAM我建议放在内部SRAM而不是PSRAM里因为内部SRAM访问速度快能减少刷新瓶颈。3.3 关于“为什么用LVGL”的思考很多人会觉得我只需要把一张图片分块显示直接写裸驱动不就成了这个项目硬上裸驱动当然可行但LVGL带来的好处在动效阶段特别明显。它帮你把“对象重绘”和“局部刷新”封装好了你用lv_obj_invalidate()标脏某个区域框架自动完成重绘不需要自己维护各种脏矩形逻辑。更重要的是LVGL提供了动画系统。在ESP-Mosaico里你只需要创建一条动画曲线然后在回调里计算当前显示多少块剩下的画面刷新全部交给LVGL。如果不用LVGL这些逻辑全部手工实现一方面代码量大增另一方面调试难度也明显上升。做嵌入式显示从第一天起就该明白一个道理复杂界面和动效靠裸驱动硬怼是不现实的。4. 马赛克的原理从一个色块到一幅图像4.1 一张照片如何变马赛克马赛克效果的本质是“降采样再升采样”。听起来有点绕其实特别简单。比如原图是240x240像素我们设定网格数为20x20那么每个格子就对应原图上12x12像素的区域。计算这个区域里所有像素的平均颜色得到一格颜色。把整张图取完就得到一张20x20的缩略图。然后再把这个20x20的小图放大回240x240每个网格内所有像素都填同一种颜色这就成了马赛克画面。整个过程就像你把一张100人的集体照裁成100个小方块每个方块只保留平均色再按原位置拼回去。放大后每个方块就是一个小色块原始局部的细节全部消失只留下大色块构成的轮廓和整体色调。RGB565格式下每个像素用16位表示红色5位、绿色6位、蓝色5位。取平均色时直接对RGB565的各个颜色分量做加法再求平均。但要注意如果直接用RGB565像素相加低位的截断误差会积累出偏色。所以累加时最好先拆成R、G、B三个独立变量uint16_t px src[y * width x]; uint32_t r (px 11) 0x1F; uint32_t g (px 5) 0x3F; uint32_t b px 0x1F;之后分别累加、求平均再拼成RGB565回写。这样的颜色比直接在RGB565上平均要准确得多。4.2 格子大小和颜色取值怎么定网格数直接决定视觉效果。网格越少每个色块越大画面越抽象“积木感”越强网格越多画面越接近原图马赛克感减弱最后变成普通缩略图。我试过的经验值如下网格规模320x240屏幕上的效果适用场景10x8左右大色块像抽象拼图强调“像素风”、只保留主体轮廓20x16左右马赛克感最佳细节和抽象平衡照片、人像、风景都合适32x24左右很接近原图了只有轻微颗粒感强调“色彩还原”、动态闪出效果收尾阶段颜色取值除了平均色也可以取格子中心像素的颜色或者格子内随机一个像素的颜色。平均色表现最稳定画面柔和但速度略慢中心点颜色速度快但容易受单个噪点影响比如一张纯蓝天突然有一小块白色云朵取到白色就会让整块变成白斑。一般还是用平均色最保险预处理耗时对MCU来说完全可接受。4.3 动态展开的实现思路静态马赛克只是第一步动态展开才是真正的亮点。动态功能的目标是让色块“按某种节奏”逐一出现在屏幕上而不是瞬间全部出现。常见做法有几种逐行扫描像老式电视一样从上往下扫。随机打乱把所有格子位置打乱然后按乱序逐个点亮有种烟花散开的感觉。从中心向外扩散先亮中央色块再一圈圈扩散视觉重心更强。透明度渐变每个色块从0%透明逐渐变成100%不透明像水墨晕染。LVGL动画系统里这些都不难实现。你只需维护一张顺序表里面存了每个格子在动画中的排列序号然后设置一个总的动画进度值比如从0到100。每次进度更新时计算当前应该显示的格子数然后逐块更新画布数据即可。这里要重点说一个性能问题如果每次刷新都把整块画布几百个格子的颜色全部重写一遍是很浪费算力的。正确的做法是只更新“从上一次进度到现在新亮起的那几个格子”让变化量最小化。5. 实操把静态马赛克跑起来5.1 生成马赛克画布数据以一张已经解码为RGB565数组的图片为例假设屏幕分辨率是240x320我们要把整张图显示成20x20网格。先将图片缩到目标网格大小再存成一块小缓冲区这是“马赛克小图”。#define GRID_W 20 #define GRID_H 20 uint16_t mosaic_data[GRID_W * GRID_H]; void generate_mosaic(const uint16_t *src, int img_w, int img_h) { int cell_w img_w / GRID_W; int cell_h img_h / GRID_H; for (int gy 0; gy GRID_H; gy) { for (int gx 0; gx GRID_W; gx) { uint32_t r_sum 0, g_sum 0, b_sum 0, count 0; for (int y gy * cell_h; y (gy 1) * cell_h; y) { for (int x gx * cell_w; x (gx 1) * cell_w; x) { uint16_t px src[y * img_w x]; r_sum (px 11) 0x1F; g_sum (px 5) 0x3F; b_sum px 0x1F; count; } } uint16_t r r_sum / count; uint16_t g g_sum / count; uint16_t b b_sum / count; mosaic_data[gy * GRID_W gx] (r 11) | (g 5) | b; } } }这个函数的时间复杂度是O(像素总数)对240x320图来说就是约7.7万次读取和累加ESP32-S3跑到240MHz就跟玩一样基本可以忽略。得到mosaic_data之后再按原尺寸展开为一张全屏画布。我的做法是申请一块和屏分辨率一样的RGB565缓冲然后循环写入每种格子颜色static uint16_t mosaic_canvas[240 * 320]; void expand_mosaic_to_canvas(uint16_t *canvas, const uint16_t *mosaic) { int cell_w 240 / GRID_W; int cell_h 320 / GRID_H; for (int gy 0; gy GRID_H; gy) { for (int gx 0; gx GRID_W; gx) { uint16_t color mosaic[gy * GRID_W gx]; for (int y 0; y cell_h; y) { for (int x 0; x cell_w; x) { int px (gy * cell_h y) * 240 (gx * cell_w x); canvas[px] color; } } } } }这是一份可以直接显示在屏幕上的完整马赛克数据。接下来要做的就是把这个RM图的起点动态显示。5.2 用动画逐步亮出马赛克块推荐用LVGL的动画接口来实现动态效果。先创建一张lv_img并绑定mosaic_canvas然后创建Animation数值范围从0到100每次回调中根据进度计算应该亮多少块。为了减少重写量我在回调里维护上次进度last_progress每次只处理进度差值中新出现的块。比如格子总数是400上一次进度显示200块这次进度显示210块那就只画这新增的10块其他格子颜色不动。实现代码如下static int last_progress 0; static int order_table[GRID_W * GRID_H]; // 保存格子显示顺序 void mosaic_anim_cb(void *var, int32_t v) { int target_visible GRID_W * GRID_H * v / 100; for (int i last_progress; i target_visible; i) { int pos order_table[i]; int gx pos % GRID_W; int gy pos / GRID_W; uint16_t color mosaic_data[gy * GRID_W gx]; fill_canvas_tile(mosaic_canvas, gx, gy, color); } last_progress target_visible; lv_obj_invalidate(img_mosaic); }fill_canvas_tile函数就是把一个格子的颜色扩展到画布对应的区域逻辑与前面的expand_mosaic_to_canvas内层循环差不多。这里把顺序表初始化为随机打乱就实现了“随机点亮”效果初始化为按行列顺序则呈现“逐行扫出”效果。动画时长一般设为2000到3000毫秒。太短会显得像闪屏太长又拖沓。我试过1000毫秒和3000毫秒两种1000毫秒适合做动态桌面3000毫秒适合展示沉浸式拼合过程。5.3 代码组织建议整个工程不大但建议不要把所有代码堆在main.c。我习惯这样分文件bsp_lcd.c屏幕初始化、SPI初始化。bsp_lvgl.cLVGL初始化、显示驱动注册。image_source.c图片数据的提供可以是内存数组也可以后续改成SD卡读取。mosaic_algorithm.c网格划分、颜色平均、画布展开。mosaic_anim.c动画顺序表、动画回调、进度控制。这样分层的好处是后续换屏、换图片来源、加触摸控制都很方便不会动一处崩全局。5.4 参数调节与手感几个参数直接决定最终视觉效果我把调参心得整理成一条参考线网格数先定在20x16左右开始调太高了没有马赛克感太低了看不出原图。动画顺序建议从“随机打乱”开始因为效果最明显容易出成就感后续再研究扩散和扫描。颜色平均时用RGB888分解累加不要直接用RGB565相加不然会出偏色。如果画面出现闪烁优先考虑增加LVGL绘制缓冲高度而不是降低SPI频率因为许多闪烁其实是绘制不及时导致的撕裂。6. 现场调试常见问题与排查技巧6.1 启动黑屏或一直白屏这个问题排第一因为它遇到概率超高。我刚接手那段时间几乎每次换屏模组都会栽一遍。主要检查顺序如下第一步确认背光引脚有没有拉高。很多屏的BLK脚如果不接3.3V或者没被GPIO控制背光不亮屏幕看起来就是全黑代码再对也没用。第二步确认CS片选有没有被其他外设占用。如果SPI总线上同时挂了SD卡CS分不清LCD就会收不到数据表现就是白屏。第三步是确认分辨率是否正确。ST7789并不是所有屏都是240x320同样一块ST7789驱动IC很可能配的是240x240面板。如果驱动里写死320x240显示区域计算错位画面自然不正常。第四步是检查LVGL颜色格式。LCD初始化用了RGB565LVGL也要设置为RGB565两者不一致会出现严重花屏或亮度异常。6.2 内存不足或启动疯狂重启如果你用的是没有PSRAM的ESP32-S3版本跑全分辨率马赛克很容易OOM。现象是启动后没一会儿就反复重启串口打印里带“memory allocation failed”之类日志。解决办法有两个思路。一是缩小屏幕分辨率或网格数把大画布缓冲省下来二是直接上带8MB PSRAM的版本并把大缓冲放到PSRAM。LVGL绘制缓冲可以保持在内部分配因为这部分频繁读写放在内部SRAM能发挥更高性能。如果已经用了PSRAM版本还需要在menuconfig里确认两项开启CONFIG_SPIRAMy和CONFIG_SPIRAM_MODE_OCTy。否则外部内存没启用代码照样以为只有内部SRAM可用。6.3 动画掉帧、画面撕裂动态展开时如果卡顿主要瓶颈不在CPU而在显示刷新带宽。SPI屏写一整帧240x320的数据即使SPI时钟跑到40MHz理论上也要约30毫秒实际受协议开销影响会更多如果LVGL每帧还要做大量内存拷贝就会进一步压缩刷新余量。优化方向有三个提高SPI时钟ST7789很多能跑40到60MHz接线短且质量好的情况下可以更激进。使用双缓冲配合DMA让屏幕刷新和数据准备并行执行避免相互等待。动画回调里只更新新增格子不要每次把全画布重画一遍把CPU占用降下来。实测下来做到这三点的240x320动画帧率稳定在30fps以上没问题眼睛看着已经非常顺滑。6.4 颜色不对出现“摩尔纹”如果你发现颜色整体像蒙了一层灰或者边缘出现彩色条纹先别急最常见原因之一是在RGB565与RGB888之间转换时搞混了字节序。ST7789一般需要把RGB565拆成高低字节并按大端顺序发送。摩尔纹的出现则通常是因为网格划分方法和屏幕分辨率不整除。例如240像素宽分成20格时刚好每格12像素但如果屏幕宽不是网格数的整数倍格子尺寸就得取整边缘会出现奇形怪状的半格。解决方法很直接要么用取整后的尺寸填满余数要么干脆放弃边缘几个像素把图片先居中裁剪到能被网格整除的尺寸。这里有个专门的经验做马赛克前先把图片预处理到“屏幕等比且可被网格数整除”的尺寸比如240x320屏幕用20x16网格图片就裁成240x320。这样每个格子的尺寸永远是正整数不会出现最后一行和最后一列格子比别的格子宽的情况。6.5 常见问题速查表现象排查点推荐解法黑屏背光电源、SPI接线先确认BLK和VCC再用逻辑分析仪看波形白屏片选、驱动分辨率对照屏幕规格书改宽高参数花屏颜色格式、SPI时钟检查RGB565字节序降SPI时钟测试自动重启内存不足换PSRAM版本或降低分辨率动画闪烁LVGL绘制缓冲不足增大缓冲行数开启双缓冲画面撕裂SPI带宽不足、刷新冲突提SPI时钟、用DMA发送像素色块错位网格尺寸不整除先裁剪图片到合适尺寸7. 我踩过的坑和一些后续想法7.1 个人经验总结做了好几轮马赛克显示实验最大的体会是这类视觉项目的真正难点从来不是“马赛克算法”本身算法一共就几十行代码难点在于把整条显示链路跑顺链条上的每一环都容易出妖怪。尤其是别一上来就上摄像头实时马赛克。摄像头实时方案的帧率要求和内存占用都比静态图高一个量级如果静态显示还没有调到不闪烁直接上实时处理会让问题大混战很难定位。先静态再动态再实时这个顺序我特别推荐。另外数据来源也别一开始就上SD卡。SD卡文件系统会引入额外的初始化、读取和解析逻辑一旦图片加载不出来你很难判断是SD卡问题还是算法问题。我建议第一步把一张图片转成C数组直接编译进固件跑通整个流水线后再去折腾SD卡或者其他外部存储。7.2 可以怎么继续玩下去这个项目往后扩展的空间其实不小我自己列了几个方向准备以后逐个试接入OV2640摄像头把实时画面转成马赛克风格做成一个“像素风取景器”。增加触摸按钮点击切换图片、调整马赛克格子数量、改变动画速度。把屏幕从单个变成阵列多个ESP32-S3各自驱动一块屏组成一个超大马赛克墙每块负责渲染一部分图像。加音频输入让马赛克块随着音乐节奏闪动做成一个灯光音乐装置。把数据源换成Wi-Fi接收手机照片配合Espressif的RainMaker或类似框架做远程传图就是一个完整的智能相框方案。做这个项目过程中我反复体会到一句话嵌入式视觉项目里真正决定成品质量的往往是那些琐碎的衔接细节。从图片裁剪尺寸到SPI时钟再到动画更新范围每一个细节都不值钱但累加起来就是“能跑”和“质感好”的区别。希望这篇文章能让你少走一些弯路也欢迎一起把马赛克玩出新花样。
RELATED

相关推荐

嵌入式DMA实战:串口、SPI、定时器触发与测速避坑指南

嵌入式DMA实战:串口、SPI、定时器触发与测速避坑指南

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

📅 2026/10/27 9:12:57
Java项目中DML与数据迁移SQL的规范化管理实践

Java项目中DML与数据迁移SQL的规范化管理实践

1. 问题背景与核心矛盾 在Java开发项目中,DML.sql文件通常被用作开发阶段新增数据的存储容器。这个文件会在上线时被带到生产环境执行,用于同步开发环境与生产环境的数据差异。然而在实际操作中,经常出现团队成员将数据迁移SQL也提交到同一个…

📅 2026/10/27 9:07:40
AI辅助测试用例生成:提升效率与覆盖率

AI辅助测试用例生成:提升效率与覆盖率

1. 项目概述:AI测试用例生成效率革命 去年在负责一个电商后台系统迭代时,我遇到了测试用例编写的瓶颈——新上线的优惠券模块涉及12种业务场景,按照传统方式编写测试用例需要3人天的工作量。直到尝试用Cursor的Skill功能,才真正体…

📅 2026/10/27 9:07:40
MORE NEWS

更多资讯

📰

Genkit skills本质解析:可编排的LLM能力契约单元

1. 这个“skills”到底指什么?别被热搜词带偏了方向 最近刷技术社区、开发者论坛,甚至朋友圈里都频繁跳出“skills”这个词——不是英文单词本意的“技能”,而是某种具体可安装、可调用、可配置的实体模块。它和 Gemini、GKE、Genkit、Googl…

📰

MonitorControl 快速上手:3 分钟找回外接显示器的亮度与音量快捷键

MonitorControl 快速上手:3 分钟找回外接显示器的亮度与音量快捷键 【免费下载链接】MonitorControl 🖥 Control your displays brightness & volume on your Mac as if it was a native Apple Display. Use Apple Keyboard keys or custom shortcut…

📰

【跑包网】wifi握手包跑包网站 cap在线分析

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

📰

CNN为何在MNIST上远超全连接网络?局部感受野与权值共享的数学本质

简介:本资源是一份面向深度学习初学者与实践者的MNIST手写数字识别完整项目包,聚焦神经网络与卷积神经网络(CNN)在图像分类任务中的落地应用。项目基于TensorFlow框架,涵盖数据加载、CNN模型构建、训练调优、性能评估及…

📰

大模型应用开发入门:吴恩达课程提示工程、RAG与避坑指南

简介:面向希望快速上手大模型与人工智能应用开发的开发者,这是一份完整中文化吴恩达大模型系列课程并复现范例代码的入门教程,适合具备基础 Python 知识、希望系统学习 LLM 开发流程的技术人群。内容围绕提示工程、检索增强生成、函数调用等课…

📰

NVMe Write Zeroes及周边命令:语义、命令帧与实测坑

盘一台机器上的盘,最容易被忽略的往往不是读带宽、写带宽这些跑分指标,而是“这块区间我想让它变成干净的零”这类管理动作。几年前给一批测试机做批量镜像还原,脚本里老老实实地用dd往整盘灌/dev/zero,一块 1.6 TB 的企业级盘要跑…

TODAY

今日更新

THIS WEEK

本周精选

THIS MONTH

本月热门

读完文章,想聊聊您的网站?

告诉我们您的行业与需求,资深顾问一对一梳理方案与报价,全程免费。

📞 💬