查看 Markdown

视觉 SDK

调摄像头、拍照、从文件选图,压缩后交给视觉模型做结构化判断(质检)或物体检测(类别 + 位置框),再把结果画回图上;看公司 NVR / 网络摄像机的实时画面与高清截图(见下文「网络摄像机 / NVR」)。只用浏览器原生能力(getUserMedia、canvas、createImageBitmap、WebCodecs),不引第三方库。页面必须是 HTTPS(或 localhost)。

import { vision } from "/developer/sdk/v1/aidc.js";

清单里声明:"sdk": ["vision", "model"]、"permissions": { "camera": true }、"models": ["gpt-6-luna"]。

摄像头

const camera = await vision.openCamera({ video: document.querySelector("video"), facingMode: "environment" });
const photo = await camera.capture({ maxSize: 1280 });  // 长边 1280 的 JPEG
await camera.switchTo({ facingMode: "user" });          // 切前置
camera.stop();                                          // 幂等
方法 说明
openCamera(options) video(挂到哪个 <video>)、facingMode(environment 后置 / user 前置)、deviceId、width / height
camera.capture(options) 拍一张 → Photo;maxSize(长边像素,缺省 1280)、type、quality
camera.switchTo(target) 换摄像头
camera.devices() 列出可用摄像头
camera.stop() 关闭(释放设备)

Photo = { blob, dataUrl, width, height, type, takenAt }。

没有摄像头时

const photo = await vision.pickImage();          // 手机上优先调起相机;电脑上选文件;取消返回 null
const photo2 = await vision.fromFile(file);      // 已有的 File / Blob

看图判断

const result = await vision.inspect(photo, {
  task: "检查成衣表面有没有污渍、破洞、跳线",
  criteria: "任何肉眼可见的污渍或破损都判不合格",   // 可选
  model: "gpt-6-luna",                             // 缺省
  reasoning: "low",                                // 缺省
});
// → { verdict: "pass" | "fail" | "uncertain", summary, findings: [...], model }

每条 finding:label(油污、划痕…)、category、severity(low / medium / high)、confidence(0–1)、box(归一化坐标 [x0, y0, x1, y1],定位不准时为 null)、note。图片模糊或看不清时模型给 uncertain,不会硬判合格。

可以一次给多张图(同一件物品的不同角度):vision.inspect([photoA, photoB], { task })。

物体检测

输入一张图,输出画面里每个物体的类别、把握和位置框。缺省模型 gpt-6-luna;用量记在当前应用 / 开发者 Key 名下(清单 models 要声明它)。

const result = await vision.detect(photo, {
  labels: ["人", "叉车", "托盘"],   // 可选:只找这些类别(≤ 40 个),label 原样用你写的;不给就找所有显著物体
  prompt: "仓库出入口,安全帽算人的一部分",   // 可选:场景与类别的补充说明
  maxObjects: 30,                   // 可选:1–100,缺省 50,按把握从高到低
});
// → { objects: [{ label: "叉车", confidence: 0.92, box: [0.61, 0.38, 0.88, 0.79], note: "画面右侧,载着托盘" }, …], count, summary, model }
const canvas = await vision.annotate(photo, result.objects);   // 画框

box 是归一化坐标 [x0, y0, x1, y1]:图片左上角 (0,0)、右下角 (1,1)——换算像素时乘图片宽高。平台会把坐标夹到 0–1、摆正左上 / 右下、丢掉面积几乎为零的框;给了 labels 时不在清单里的类别不返回。视觉大模型的框是近似定位(适合计数、找位置、配合人工复核),不是逐像素的分割。

同一个能力也是 HTTP API,任何语言都能调:POST /api/v1/models/vision/detect,body { "image": "data:image/jpeg;base64,…" | "https://…", "labels"?, "prompt"?, "maxObjects"?, "model"? },Authorization: Bearer <开发者 Key 或应用票据>。

画框标注

const canvas = await vision.annotate(photo, result.findings);   // inspect 的 findings、detect 的 objects 都能传;返回画好框的 <canvas>
document.body.append(canvas);

上传给智能体

图片可以直接交给某个智能体(走 Agent API 的附件协议,24 小时内有效):

const agent = model.agent(agentKey);
const fileId = await agent.upload(photo.blob, "defect.jpg");
await agent.send("这是今天 3 号线的不合格品,请登记。", { files: [fileId] });

见模型 SDK · 智能体。

网络摄像机 / NVR

公司 NVR(大华、海康等)上的摄像头走 RTSP,浏览器直接连不了。平台在有人打开画面时去拉流(RTSP over TCP,Digest 认证),把码流原样(H.264 / H.265,不转码)转给浏览器,SDK 用 WebCodecs 硬解、画到 canvas。口令只在平台里(AES-256-GCM 加密存放、任何接口都不回显),应用与浏览器都拿不到。

1. 登记(本公司开发者,一次):

AIDC_CAMERA_PASSWORD='只读账号的口令' aidc vision camera add nvr \
  --host 58.x.x.x --port 18554 --vendor dahua --username viewer \
  --channels "1:大门,2:仓库" --title "总部 NVR"
aidc vision camera probe nvr --channels 1-16      # 连上、认证、读编码(不拉流),找出有哪些通道

口令只从环境变量 AIDC_CAMERA_PASSWORD 或 --password-stdin 读,绝不写在命令行参数里;重新登记时不给口令 = 保留原来的。也可以在应用里做一个只给开发者的「登记摄像头」表单(vision.saveCamera,见样板 camera-live)。--vendor dahua(缺省)的路径是 /cam/realmonitor?channel={channel}&subtype={stream},hikvision 是 /Streaming/Channels/{channel}0{stream},其他品牌 --vendor generic --path '/live/ch{channel}/{stream}'。主机必须是公网地址(路由器上给 NVR 做端口映射)。

2. 清单:"sdk": ["vision"]、"cameras": ["nvr"](应用只看得到这里登记的摄像头)。

3. 页面:

const cams = await vision.cameras();                       // [{ name, title, channels: [{ id, title }], defaultStream, … }]
const view = vision.live(document.querySelector("canvas"), {
  camera: "nvr", channel: 1, stream: "sub",                 // sub 子码流(缺省,远程流畅)/ main 主码流(要登记时开 allowMainLive)
  onStatus: (status, { info, error }) => { /* connecting → live;reconnecting / paused / error */ },
});
view.switchTo({ channel: 2 });                             // 换一路
const photo = await view.snapshot();                        // 当前画面 → Photo,可直接 vision.detect(photo)
const hd = await vision.cameraSnapshot("nvr", { channel: 1 }); // 主码流高清截图(取下一个关键帧,不用开主码流实时)
view.stop();

同样是 HTTP API(开发者 Key 或应用票据):GET /api/v1/developer/vision/{命名空间}/cameras、PUT …/cameras/{名字}(登记,支持 dry-run)、POST …/probe、GET …/live?channel=&stream=(流式,application/vnd.aidc.live)、GET …/keyframe?channel=&stream=(一帧原始码流,Annex B)。线格式与每个字段见 API 与 OpenAPI。

命令行

aidc vision inspect a.jpg b.jpg --task "布面有没有污渍" --json
aidc vision detect warehouse.jpg --labels 人,叉车,托盘 --json      # 物体检测:类别 + 把握 + 归一化框
aidc vision camera list                                             # 公司的网络摄像机
aidc vision camera snapshot nvr --channel 1 -o gate.jpg             # 截一帧(缺省主码流高清;本机 ffmpeg 转 JPEG)
aidc vision detect gate.jpg --labels 人,车辆 --json                  # 智能体「看一眼现场」= 截图 + 物体检测

错误

本机摄像头:camera_denied(没给权限)、camera_not_found、camera_busy、camera_unsupported(非 HTTPS / 旧浏览器)、invalid_model_output;以及 API 的 forbidden(清单没声明模型)、quota_exhausted(应用当日额度用完)、rate_limited。

网络摄像机(API):camera_not_found(没登记这台)、camera_channel_not_found(没这一路)、camera_unreachable(连不上:地址、端口映射、出口防火墙)、camera_auth_failed(摄像头拒绝口令,冷却 10 分钟)、camera_timeout(请求石沉大海或等不到关键帧)、camera_stream_failed、camera_busy(同时观看满了)、vision_unconfigured(平台加密密钥缺失或换过,重新登记口令);浏览器侧 codec_unsupported、unsupported_environment(没有 WebCodecs)。

本页由 developer/docs/vision.md 生成 · Markdown 原文 · llms.txt