☰
基于多视觉语言模型交叉描述的智能眼镜图像理解与质量评估实战指南(OpenGlass 项目)
2026/10/3 2:31:33 网站建设 项目流程
  • 人工智能
  • AI 应用
  • 智能硬件
  • 本地部署
  • 可穿戴
  • AI Agent

【免费下载链接】OpenGlass

Turn any glasses into AI-powered smart glasses

项目地址:https://gitcode.com/GitHub_Trending/op/OpenGlass
点击查看免费下载

OpenGlass 是一个让任何普通眼镜变身 AI 智能眼镜的开源项目:硬件端用不到 25 美元的现成元件(XIAO ESP32 S3 Sense 摄像头 + 蓝牙),软件端则通过多路视觉语言模型(VLM)对眼镜拍摄到的画面进行实时描述、过滤与问答。本文以prompts/series_1/系列测试集中的img_55.md为线索,完整讲解 OpenGlass 如何用 4 种不同规格的 VLM(默认 moondream 微模型、llava-llama3、llava:34b-v1.6、moondream:1.8b-v2-fp16)对同一张照片做交叉描述,如何用 moondream 文本模型做图像模糊质量判定,以及如何基于这些描述用 Groq 的 llama3-70b 或 OpenAI GPT-4o 回答用户问题,最终实现"拍下来 → 看懂 → 答上来"的完整 Agent 链路。

一、img_55.md 是什么:一份多模型图像描述实验记录

在 OpenGlass 仓库的prompts/series_1/img_55.md中,保存着对一张人物特写照片的四份独立描述。文件内部按####模型名####分节组织,每一节对应一次独立的图像描述推理输出:

####Description#### (默认模型描述……) ####Description (llava-llama3)#### (llava-llama3 模型描述……) ####Description (llava:34b-v1.6)#### (llava:34b-v1.6 模型描述……) ####Description (moondream:1.8b-v2-fp16)#### (moondream:1.8b-v2-fp16 模型描述……)

对照 img_55.md 的实际内容,四份描述从不同角度刻画同一画面:默认模型(moondream)报告"一名男子面部特写、头微微上扬、眼睛直视镜头,背景像是仓库或大型房间";llava-llama3 补充了"卷曲棕色头发、玻璃天窗、空阔的白墙空间、孤独感"等细节;llava:34b-v1.6 则强调"低机位仰拍、人物略微向左转身、半侧面与颈部轮廓、工业建筑结构、柔和的漫射光";moondream:1.8b-v2-fp16 描述为"穿蓝色衬衫的人站在工业建筑前,仰头看向镜头"。同一个画面,四个模型给出的信息互为印证又各有侧重——这正是交叉描述(cross-description)的价值所在:单模型可能漏掉的细节(比如"玻璃天窗""低机位")可以由另一个模型补全,为后续问答提供更完整的证据池。

生成这些.md记录的直接脚本是 prompts/generate.ts:它遍历prompts/下的每个series_*目录,读取全部.jpeg图片,依次调用imageDescription()生成默认描述,再分别指定'llava-llama3'、'llava:34b-v1.6'、'moondream:1.8b-v2-fp16'三个模型生成交叉描述,最后把结果按####标题####分节写入同名.md文件。img_55.md 正是该流水线的一次输出快照。

二、核心函数 imageDescription:一次调用,多模型可切换

所有描述都来自 sources/agent/imageDescription.ts 中的imageDescription():

export async function imageDescription(src: Uint8Array, model: KnownModel = 'moondream:1.8b-v2-fp16'): Promise<string> { return ollamaInference({ model: model, messages: [{ role: 'system', content: 'You are a very advanced model and your task is to describe the image as precisely as possible. Transcribe any text you see.' }, { role: 'user', content: 'Describe the scene', images: [src], }] }); }

值得注意的细节:

  • 默认模型是moondream:1.8b-v2-fp16,而不是 llama 系列。moondream 是一个专为图像理解设计的小体量视觉语言模型,fp16 版本在推理精度与资源占用之间取得了平衡,适合作为眼镜端实时管线的默认选项。
  • System Prompt 明确要求"尽可能精确地描述图像,并转写画面中出现的任何文字"。这意味着描述不是泛泛的"有人站在室内",而是会尽量给出场景细节与可见文本,为后续问答提供结构化证据。在 img_55.md 中,llava-llama3 描述提到的"玻璃天窗(skylight)"、"白墙开放空间"即是对该指令的响应。
  • 模型名通过KnownModel联合类型约束,见 sources/modules/ollama.ts:
export type KnownModel = | 'llama3' | 'llama3-gradient' | 'llama3:8b-instruct-fp16' | 'llava-llama3' | 'llava:34b-v1.6' | 'moondream:1.8b-v2-fp16' | 'moondream:1.8b-v2-moondream2-text-model-f16'

在 TypeScript 层,传一个不属于该集合的字符串会在编译期直接报错,从类型系统层面杜绝了"模型名拼写错误"这类运行时事故。

三、底层推理封装 ollamaInference:Base64 编码 + 指数退避

imageDescription并非直接调用 Ollama,而是经过 sources/modules/ollama.ts 中的ollamaInference()封装。它完成三件事:

  1. 把图片转为 Base64:通过 sources/utils/base64.ts 的toBase64()将Uint8Array图片数据编码为 Ollama Chat API 要求的images: string[]字段;
  2. 缩进规范化:用trimIdent()清理 prompt 中的多余缩进,避免空白干扰模型输出;
  3. 指数退避重试:用 sources/utils/time.ts 的backoff()包裹 HTTP 请求,在 Ollama 服务繁忙时自动退避重试,提升管线稳定性。

请求体核心为:

await axios.post(keys.ollama, { stream: false, // 一次性返回完整回答 model: args.model, messages: converted, // 含 role/content/images 的消息数组 });

其中keys.ollama来自 sources/keys.ts:

export const keys = { groq: process.env.EXPO_PUBLIC_GROQ_API_KEY ?? '', ollama: process.env.EXPO_PUBLIC_OLLAMA_API_URL ?? '', openai: process.env.EXPO_PUBLIC_OPENAI_API_KEY ?? '', };

也就是说,Ollama 的地址通过环境变量EXPO_PUBLIC_OLLAMA_API_URL注入,典型取值为本地自托管服务的http://localhost:11434/api/chat(见 README.md 软件准备步骤)。要在本地复现 img_55.md 那样的描述,需要先执行ollama pull moondream:1.8b-v2-fp16(以及交叉描述用到的llava-llama3、llava:34b-v1.6),确保模型已下载到本地 Ollama。

四、质量门:imageBlurry 用独立文本模型判定模糊

在交叉描述之外,OpenGlass 还设计了图像质量筛查逻辑 sources/agent/imageBlurry.ts:

export async function imageBlurry(src: Uint8Array): Promise<string> { return ollamaInference({ model: 'moondream:1.8b-v2-moondream2-text-model-f16', messages: [{ role: 'system', content: 'You are an very advanced model and your task is to determine if the image is broken, blurry or just low quality. You must always answer as YES or NO.' }, { role: 'user', content: 'Is this image blurry, broken or low quality? YES or NO.', images: [src], }] }); }

关键点:

  • 它复用的是moondream 的纯文本模型变体(moondream:1.8b-v2-moondream2-text-model-f16,同样收录在KnownModel联合类型中),但以图像问答(VQA)方式运行——传入图片并强制要求输出"YES or NO";
  • System Prompt 强制答案二值化:"你必须始终回答 YES 或 NO",这与描述任务的自由文本输出形成鲜明对比,便于上层代码用简单字符串匹配即可过滤掉模糊/破损/低质量帧;
  • 在 prompts/generate.ts 中该测试默认被注释掉(// console.log(\Run blurry tests`)`),属于可选的质量评估环节,可用于在把照片送进描述管线前先做一次"该不该处理"的判定。

五、从描述到答案:llamaFind / openAIFind 的检索式问答

描述只是中间产物,OpenGlass 的 Agent 最终要把"这段描述"变成"用户问题的答案"。这由 sources/agent/imageDescription.ts 中的两个函数完成,它们共享几乎相同的 Prompt 模板:

export async function llamaFind(question: string, images: string): Promise<string> { return groqRequest( ` You are a smart AI that need to read through description of a images and answer user's questions. This are the provided images: ${images} DO NOT mention the images, scenes or descriptions in your answer, just answer the question. DO NOT try to generalize or provide possible scenarios. ONLY use the information in the description of the images to answer the question. BE concise and specific. `, question ); }

openAIFind使用相同模板但走gptRequest(GPT-4o)。模板的约束非常有针对性:

  • "不要提及图像、场景或描述本身,只回答问题"——保证输出是直接答案而非复述;
  • "不要泛化或臆想可能场景"——限制模型只能使用描述中已存在的信息,避免幻觉;
  • "只使用描述中的信息"+"简洁具体"——把回答牢牢锚定在证据池内。

针对 img_55 这类照片,如果用户问"这个人在室内还是室外?",模型会综合"工业建筑结构""玻璃天窗""漫射光"等描述证据给出明确回答;而 llava-llama3 的"空阔、孤独"等主观描述也会被约束为辅助信息而非臆测来源。

两个函数分别由 sources/modules/groq-llama3.ts(调用 Groq 上的llama3-70b-8192,鉴权用keys.groq)和 sources/modules/openai.ts(调用 OpenAIgpt-4o,鉴权用keys.openai)实现。API Key 同样通过环境变量注入:EXPO_PUBLIC_GROQ_API_KEY与EXPO_PUBLIC_OPENAI_API_KEY。

六、Agent 串联:从拍照到回答的完整调用链

把上述模块串起来的是 sources/agent/Agent.ts 中的Agent类。它的两个核心方法展示了真实运行时的数据流:

  • addPhoto(photos: Uint8Array[]):把每次眼镜传来的照片帧依次送入imageDescription()生成描述,连同原始照片一起压入#photos数组(内部用AsyncLock串行化,避免并发写入),并更新lastDescription驱动 UI 展示;
  • answer(question: string):把所有已积累照片的描述拼成Image #i + 描述的文本块,调用llamaFind()得到答案,同时尝试startAudio()准备语音播报(见 sources/modules/openai.ts)。

从数据链路看,一条完整路径是:

  1. ESP32 S3 Sense 摄像头捕获 JPEG 帧(固件见 firmware/firmware.ino);
  2. 通过 BLE 传输到 Web 端(sources/modules/useDevice.ts 按设备名OpenGlass和 UUID19B10000-E8F2-537E-4F6C-D104768A1214建立 GATT 连接);
  3. 帧进入Agent.addPhoto(),经imageDescription()(Ollama + moondream/llava)产出描述;
  4. 用户提问后,Agent.answer()用llamaFind()/openAIFind()(Groq/OpenAI)基于描述生成答案并语音输出。

img_55.md 中的四份描述,正是第 3 步针对同一帧照片跑四次的离线快照,可以被视为对整个 Agent 感知层的一种"多视角校验"。

七、在本地复现 img_55.md 的完整步骤

想在自己环境里产出与 img_55.md 相同格式的多模型描述,可按 README.md 与 prompts/generate.ts 的流程操作:

  1. 准备环境:安装 Node.js 与依赖(npm install或yarn install),项目为 Expo 工程;
  2. 启动并拉取模型:自托管 Ollama,执行ollama pull moondream:1.8b-v2-fp16,如需交叉描述再ollama pull llava-llama3、ollama pull llava:34b-v1.6;
  3. 配置密钥:在环境变量中设置EXPO_PUBLIC_OLLAMA_API_URL(如http://localhost:11434/api/chat),若需要 Groq/GPT 问答链路再设置EXPO_PUBLIC_GROQ_API_KEY与EXPO_PUBLIC_OPENAI_API_KEY(见 sources/keys.ts);
  4. 运行批处理:把待测图片放入prompts/下的series_*目录后,执行生成脚本,程序会按####Description####、####Description (llava-llama3)####、####Description (llava:34b-v1.6)####、####Description (moondream:1.8b-v2-fp16)####四个分节写出与 img_55.md 结构一致的.md文件,每批跑完显示进度条。

注意事项:生成脚本依赖本地 Ollama 服务可用,且四个模型的显存/内存需求不同(llava:34b-v1.6 明显大于 moondream),在资源受限设备上建议先用默认 moondream 模型跑通,再按需叠加交叉描述;图像模糊测试(imageBlurry)默认被注释,可按需取消注释启用。

八、对智能眼镜 Agent 管线的几点启示

结合 img_55.md 与上述源码,这套"多模型描述 + 文本模型质检 + 检索式问答"的架构对任何端侧视觉 Agent 都有参考价值:

  • 交叉描述是廉价的"感知冗余":不同体量、不同训练分布的 VLM 对同一画面的关注点不同,将多份描述合并后喂给问答模型,相当于给证据池做了数据增强,能显著降低单模型漏检风险;
  • 模型分层避免资源浪费:默认走轻量 moondream,需要更丰富细节时再升级到 llava 系列,既满足实时性又保留深度描述能力;KnownModel联合类型从类型层保证模型名合法;
  • 问答模型与感知模型解耦:描述用本地 Ollama 完成(隐私、零成本),问答按需路由到 Groq 的 llama3-70b 或 OpenAI GPT-4o,llamaFind/openAIFind共用的严格 Prompt 模板约束了答案必须"只用描述中的信息",天然抑制幻觉;
  • 质检前置是可插拔的工程习惯:imageBlurry以二值输出做模糊帧过滤,在 prompts/generate.ts 中作为独立可开关环节存在,便于按场景取舍。

当前仓库的 README 说明项目已迁移至 Omi 仓库、本仓库不再维护,但这不影响其软件管线(描述、质检、问答)作为可复用的参考实现;对希望构建"眼镜拍 → AI 答"场景的开发者,img_55.md 连同 sources/agent/、sources/modules/ 下的源码,是一套可以直接对照复刻的完整样本。

  • 人工智能
  • AI 应用
  • 智能硬件
  • 本地部署
  • 可穿戴
  • AI Agent

【免费下载链接】OpenGlass

Turn any glasses into AI-powered smart glasses

项目地址:https://gitcode.com/GitHub_Trending/op/OpenGlass
点击查看免费下载

相关推荐

上一篇:Ray Tune 实战:用可视化工具函数深度剖析 PBT(Population Based Training)超参数进化过程
下一篇:Prettier Markdown 格式化解析:blockquote 中转义大于号(`\>`)在 proseWrap: always 模式下的处理机制

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询