face-api.js

GitHub
17.8k 3.9k 简单 1 次阅读 今天MIT图像视频开发框架
AI 解读 由 AI 自动生成,仅供参考

face-api.js 是一款基于 TensorFlow.js 构建的 JavaScript 人脸分析工具,让开发者能够轻松在浏览器或 Node.js 环境中实现人脸识别功能。它主要解决了以往人脸技术依赖复杂后端服务、难以在前端直接运行的痛点,让用户无需配置重型服务器即可在网页端完成实时人脸检测与分析。

这款工具非常适合前端开发者、全栈工程师以及希望快速原型验证的研究人员使用。无论是想制作互动滤镜、安防监控演示,还是进行用户身份验证,face-api.js 都能提供开箱即用的解决方案。普通用户虽不直接操作代码,但能享受到由它驱动的流畅网页体验,如自动美颜、表情互动游戏等。

其技术亮点在于集成了多种高精度模型,不仅能精准定位人脸关键点,还能识别面部表情、估算年龄与性别,甚至支持多人脸实时追踪。所有计算均在客户端完成,既保护了用户隐私,又降低了延迟。配合丰富的示例代码和清晰的文档,face-api.js 让人脸智能应用的开发门槛大幅降低,成为连接人工智能与 Web 开发的桥梁。

使用场景

某在线教育平台希望在其直播课堂中实时分析学生的专注度与情绪状态,以便教师及时调整授课节奏。

没有 face-api.js 时

  • 开发者必须自行搭建复杂的 Python 后端服务来处理视频流,导致前端架构臃肿且延迟高。
  • 引入重型深度学习框架(如 TensorFlow 或 PyTorch)需要昂贵的 GPU 服务器支持,大幅推高运营成本。
  • 实现人脸关键点定位和表情识别需从零训练模型或集成多个独立库,开发周期长达数周。
  • 用户隐私数据需上传至云端处理,面临严格的数据合规风险及用户信任危机。
  • 跨浏览器兼容性差,移动端设备往往因算力不足而无法流畅运行检测功能。

使用 face-api.js 后

  • 直接在浏览器端利用 WebGL 加速运行模型,无需后端转发视频流,实现了毫秒级实时反馈。
  • 基于轻量级的 tensorflow.js 核心,普通用户的笔记本电脑或手机即可流畅运行,彻底省去 GPU 服务器开支。
  • 调用封装好的人脸检测、 landmarks 定位及表情识别 API,仅需几十行代码即可在两天内完成功能上线。
  • 所有图像数据仅在本地设备处理,不离开用户浏览器,完美解决隐私泄露顾虑并符合 GDPR 规范。
  • 依托成熟的 JavaScript 生态,天然兼容 Chrome、Firefox 及各类移动浏览器,无需额外适配工作。

face-api.js 将原本依赖昂贵后端算力的人脸分析能力下沉至浏览器端,以极低的成本实现了高性能、高隐私保护的实时交互体验。

运行环境要求

操作系统
  • Linux
  • macOS
  • Windows
GPU
  • 非必需
  • 在 Node.js 环境下可选安装 @tensorflow/tfjs-node 以利用本地 TensorFlow C++ 库加速(隐含支持 CPU 及可能的 GPU 后端,但 README 未明确指定 CUDA 版本或特定显卡型号要求)
  • 浏览器端依赖 WebGL
内存

未说明

依赖
notes该工具主要面向浏览器和 Node.js 环境。在 Node.js 中运行时,必须安装 'canvas' 包来模拟浏览器图像元素(HTMLImageElement, HTMLCanvasElement)。若需高性能,建议安装 '@tensorflow/tfjs-node'(安装此包可能需要 Python 环境来编译原生绑定,但运行时本身是 JS)。模型文件(manifest.json 和权重分片)需单独下载并放置在可访问的目录中。
python不需要 Python (基于 JavaScript/Node.js)
face-api.js
@tensorflow/tfjs-core
canvas (Node.js 环境必选)
@tensorflow/tfjs-node (Node.js 环境推荐)
face-api.js hero image

快速开始

face-api.js

构建状态 Slack

基于 tensorflow.js core(tensorflow/tfjs-core)实现的浏览器和 Node.js 的 JavaScript 人脸识别 API

faceapi

点击这里查看实时演示!

教程

目录

功能特性

人脸识别

face-recognition

人脸关键点检测

face_landmark_detection

面部表情识别

preview_face-expression-recognition

年龄估计与性别识别

age_gender_recognition

运行示例

克隆仓库:

git clone https://github.com/justadudewhohacks/face-api.js.git

运行浏览器示例

cd face-api.js/examples/examples-browser
npm i
npm start

打开 http://localhost:3000/。

运行 Node.js 示例

cd face-api.js/examples/examples-nodejs
npm i

现在可以使用 ts-node 运行其中一个示例:

ts-node faceDetection.ts

或者直接编译并用 node 运行:

tsc faceDetection.ts
node faceDetection.js

适用于浏览器的 face-api.js

只需从 dist/face-api.js 引入最新脚本即可。

或者通过 npm 安装:

npm i face-api.js

适用于 Node.js 的 face-api.js

我们可以通过 polyfill 一些浏览器特有的对象,如 HTMLImageElement、HTMLCanvasElement 和 ImageData,在 Node.js 环境中使用等效的 API。最简单的方法是安装 node-canvas 包。

另外,你也可以直接从图像数据构造张量,并将张量作为输入传递给 API。

此外,建议安装 @tensorflow/tfjs-node(非必需,但强烈推荐),它通过编译并与原生 TensorFlow C++ 库绑定,可显著提升性能:

npm i face-api.js canvas @tensorflow/tfjs-node

接下来,我们只需对环境进行 monkey patch,以使用这些 polyfill:

// 导入 Node.js 绑定到原生 TensorFlow,
// 虽然不是必需的,但会极大地加速处理(需要 Python)
import '@tensorflow/tfjs-node';

// 实现 Node.js 对 HTMLCanvasElement、HTMLImageElement 和 ImageData 的封装
import * as canvas from 'canvas';

import * as faceapi from 'face-api.js';

// 对 Node.js 环境进行补丁,我们需要提供 HTMLCanvasElement 和 HTMLImageElement 的实现
const { Canvas, Image, ImageData } = canvas
faceapi.env.monkeyPatch({ Canvas, Image, ImageData })

开始使用

加载模型

所有全局神经网络实例都通过 faceapi.nets 导出:

console.log(faceapi.nets)
// ageGenderNet
// faceExpressionNet
// faceLandmark68Net
// faceLandmark68TinyNet
// faceRecognitionNet
// ssdMobilenetv1
// tinyFaceDetector
// tinyYolov2

要加载一个模型,你需要提供对应的 manifest.json 文件以及模型权重文件(分片)作为资源。只需将它们复制到你的 publicassets 文件夹中。模型的 manifest.json 和分片文件必须位于同一目录下,或可通过相同的路径访问。

假设模型存放在 public/models 目录中:

await faceapi.nets.ssdMobilenetv1.loadFromUri('/models')
// 对其他模型同样操作:
// await faceapi.nets.faceLandmark68Net.loadFromUri('/models')
// await faceapi.nets.faceRecognitionNet.loadFromUri('/models')
// ...

在 Node.js 环境中,你还可以直接从磁盘加载模型:

await faceapi.nets.ssdMobilenetv1.loadFromDisk('./models')

你也可以从 tf.NamedTensorMap 加载模型:

await faceapi.nets.ssdMobilenetv1.loadFromWeightMap(weightMap)

此外,你还可以创建自己的神经网络实例:

const net = new faceapi.SsdMobilenetv1()
await net.loadFromUri('/models')

你还可以将权重作为 Float32Array 加载(如果你希望使用未压缩的模型):

// 使用 fetch
net.load(await faceapi.fetchNetWeights('/models/face_detection_model.weights'))

// 使用 axios
const res = await axios.get('/models/face_detection_model.weights', { responseType: 'arraybuffer' })
const weights = new Float32Array(res.data)
net.load(weights)

高级 API

以下示例中,input 可以是 HTML 的 <img><video><canvas> 元素,也可以是这些元素的 ID。

<img id="myImg" src="images/example.png" />
<video id="myVideo" src="media/example.mp4" />
<canvas id="myCanvas" />
const input = document.getElementById('myImg')
// const input = document.getElementById('myVideo')
// const input = document.getElementById('myCanvas')
// 或者直接:
// const input = 'myImg'

检测人脸

检测图像中的所有人脸。返回 Array<FaceDetection>

const detections = await faceapi.detectAllFaces(input)

检测图像中置信度最高的单张人脸。返回 FaceDetection | undefined

const detection = await faceapi.detectSingleFace(input)

默认情况下,detectAllFacesdetectSingleFace 使用 SSD MobileNet V1 人脸检测器。你可以通过传递相应的选项对象来指定使用的检测器:

const detections1 = await faceapi.detectAllFaces(input, new faceapi.SsdMobilenetv1Options())
const detections2 = await faceapi.detectAllFaces(input, new faceapi.TinyFaceDetectorOptions())

你可以根据 这里 所示调整每个检测器的选项。

检测 68 个面部关键点

在完成人脸检测后,我们还可以为每个检测到的人脸预测面部关键点,具体如下:

检测图像中的所有人脸,并为每个检测到的人脸计算 68 个关键点。返回 Array<WithFaceLandmarks<WithFaceDetection<{}>>>

const detectionsWithLandmarks = await faceapi.detectAllFaces(input).withFaceLandmarks()

检测图像中置信度最高的单张人脸,并为其计算 68 个面部关键点。返回 WithFaceLandmarks<WithFaceDetection<{}>> | undefined

const detectionWithLandmarks = await faceapi.detectSingleFace(input).withFaceLandmarks()

你也可以选择使用小型模型而不是默认模型:

const useTinyModel = true
const detectionsWithLandmarks = await faceapi.detectAllFaces(input).withFaceLandmarks(useTinyModel)

计算人脸描述符

在完成人脸检测和面部关键点预测后,可以为每个人脸计算描述符,具体如下:

检测图像中的所有人脸,并为每个检测到的人脸计算 68 个关键点。返回 Array<WithFaceDescriptor<WithFaceLandmarks<WithFaceDetection<{}>>>>

const results = await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceDescriptors()

检测图像中置信度最高的单张人脸,并为其计算 68 个关键点和人脸描述符。返回 WithFaceDescriptor<WithFaceLandmarks<WithFaceDetection<{}>>> | undefined

const result = await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceDescriptor()

识别面部表情

可以对检测到的人脸进行面部表情识别,具体如下:

检测图像中的所有人脸,并识别每个人脸的面部表情。返回 Array<WithFaceExpressions<WithFaceLandmarks<WithFaceDetection<{}>>>>

const detectionsWithExpressions = await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions()

检测图像中置信度最高的单张人脸,并识别该人脸的面部表情。返回 WithFaceExpressions<WithFaceLandmarks<WithFaceDetection<{}>>> | undefined

const detectionWithExpressions = await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions()

你也可以跳过 .withFaceLandmarks(),这样会跳过人脸对齐步骤(准确性可能会降低):

检测所有人脸而不进行人脸对齐,并识别每个人脸的面部表情。返回 Array<WithFaceExpressions<WithFaceDetection<{}>>>

const detectionsWithExpressions = await faceapi.detectAllFaces(input).withFaceExpressions()

检测置信度最高的单张人脸,不进行人脸对齐,并识别该人脸的面部表情。返回 WithFaceExpressions<WithFaceDetection<{}>> | undefined

const detectionWithExpressions = await faceapi.detectSingleFace(input).withFaceExpressions()

年龄估计与性别识别

可以从检测到的人脸中进行年龄估计和性别识别,具体方法如下:

检测图像中的所有人脸 + 估计每个脸的年龄并识别性别。返回 Array<WithAge<WithGender<WithFaceLandmarks<WithFaceDetection<{}>>>>>

const detectionsWithAgeAndGender = await faceapi.detectAllFaces(input).withFaceLandmarks().withAgeAndGender()

检测图像中置信度最高的那张人脸 + 估计该脸的年龄并识别性别。返回 WithAge<WithGender<WithFaceLandmarks<WithFaceDetection<{}>>>> | undefined

const detectionWithAgeAndGender = await faceapi.detectSingleFace(input).withFaceLandmarks().withAgeAndGender()

你也可以跳过 .withFaceLandmarks(),这样就会跳过人脸对齐步骤(准确性会稍差):

检测所有未进行人脸对齐的人脸 + 估计每个脸的年龄并识别性别。返回 Array<WithAge<WithGender<WithFaceDetection<{}>>>>

const detectionsWithAgeAndGender = await faceapi.detectAllFaces(input).withAgeAndGender()

检测未进行人脸对齐的置信度最高的那张人脸 + 估计该脸的年龄并识别性别。返回 WithAge<WithGender<WithFaceDetection<{}>>> | undefined

const detectionWithAgeAndGender = await faceapi.detectSingleFace(input).withAgeAndGender()

任务组合

任务可以按以下方式组合:

// 所有人脸
await faceapi.detectAllFaces(input)
await faceapi.detectAllFaces(input).withFaceExpressions()
await faceapi.detectAllFaces(input).withFaceLandmarks()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions().withFaceDescriptors()
await faceapi.detectAllFaces(input).withFaceLandmarks().withAgeAndGender().withFaceDescriptors()
await faceapi.detectAllFaces(input).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptors()

// 单张人脸
await faceapi.detectSingleFace(input)
await faceapi.detectSingleFace(input).withFaceExpressions()
await faceapi.detectSingleFace(input).withFaceLandmarks()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions().withFaceDescriptor()
await faceapi.detectSingleFace(input).withFaceLandmarks().withAgeAndGender().withFaceDescriptor()
await faceapi.detectSingleFace(input).withFaceLandmarks().withFaceExpressions().withAgeAndGender().withFaceDescriptor()

通过描述符匹配进行人脸识别

要进行人脸识别,可以使用 faceapi.FaceMatcher 将参考人脸描述符与查询人脸描述符进行比较。

首先,我们用参考数据初始化 FaceMatcher。例如,我们可以简单地在 referenceImage 中检测人脸,并将检测到的人脸描述符与后续图像中的人脸进行匹配:

const results = await faceapi
  .detectAllFaces(referenceImage)
  .withFaceLandmarks()
  .withFaceDescriptors()

if (!results.length) {
  return
}

// 使用参考图像的检测结果自动分配标签,创建 FaceMatcher
const faceMatcher = new faceapi.FaceMatcher(results)

现在我们可以识别 queryImage1 中出现的人脸:

const singleResult = await faceapi
  .detectSingleFace(queryImage1)
  .withFaceLandmarks()
  .withFaceDescriptor()

if (singleResult) {
  const bestMatch = faceMatcher.findBestMatch(singleResult.descriptor)
  console.log(bestMatch.toString())
}

或者我们可以识别 queryImage2 中出现的所有人脸:

const results = await faceapi
  .detectAllFaces(queryImage2)
  .withFaceLandmarks()
  .withFaceDescriptors()

results.forEach(fd => {
  const bestMatch = faceMatcher.findBestMatch(fd.descriptor)
  console.log(bestMatch.toString())
})

你也可以按照以下方式创建带标签的参考描述符:

const labeledDescriptors = [
  new faceapi.LabeledFaceDescriptors(
    'obama',
    [descriptorObama1, descriptorObama2]
  ),
  new faceapi.LabeledFaceDescriptors(
    'trump',
    [descriptorTrump]
  )
]

const faceMatcher = new faceapi.FaceMatcher(labeledDescriptors)

显示检测结果

准备叠加画布:

const displaySize = { width: input.width, height: input.height }
// 将叠加画布调整为输入图像的尺寸
const canvas = document.getElementById('overlay')
faceapi.matchDimensions(canvas, displaySize)

face-api.js 预定义了一些高级绘图函数,你可以直接使用:

/* 显示检测到的人脸边界框 */
const detections = await faceapi.detectAllFaces(input)
// 如果显示的图像尺寸与原始图像不同,则调整检测框的大小
const resizedDetections = faceapi.resizeResults(detections, displaySize)
// 将检测结果绘制到画布上
faceapi.draw.drawDetections(canvas, resizedDetections)

/* 显示人脸关键点 */
const detectionsWithLandmarks = await faceapi
  .detectAllFaces(input)
  .withFaceLandmarks()
// 如果显示的图像尺寸与原始图像不同,则调整检测框和关键点的大小
const resizedResults = faceapi.resizeResults(detectionsWithLandmarks, displaySize)
// 将检测结果绘制到画布上
faceapi.draw.drawDetections(canvas, resizedResults)
// 将关键点绘制到画布上
faceapi.draw.drawFaceLandmarks(canvas, resizedResults)


/* 显示面部表情结果 */
const detectionsWithExpressions = await faceapi
  .detectAllFaces(input)
  .withFaceLandmarks()
  .withFaceExpressions()
// 如果显示的图像尺寸与原始图像不同,则调整检测框和关键点的大小
const resizedResults = faceapi.resizeResults(detectionsWithExpressions, displaySize)
// 将检测结果绘制到画布上
faceapi.draw.drawDetections(canvas, resizedResults)
// 在画布上绘制一个显示最低置信度面部表情的文本框
const minProbability = 0.05
faceapi.draw.drawFaceExpressions(canvas, resizedResults, minProbability)

你还可以绘制带有自定义文本的矩形框(DrawBox):

const box = { x: 50, y: 50, width: 100, height: 100 }
// 参见下方的 DrawBoxOptions
const drawOptions = {
  label: '你好,我是一个矩形框!',
  lineWidth: 2
}
const drawBox = new faceapi.draw.DrawBox(box, drawOptions)
drawBox.draw(document.getElementById('myCanvas'))

DrawBox 绘图选项:

export interface IDrawBoxOptions {
  boxColor?: string
  lineWidth?: number
  drawLabelOptions?: IDrawTextFieldOptions
  label?: string
}

最后,你还可以绘制自定义文本框(DrawTextField):

const text = [
  '这是一行文字!',
  '这是另一行文字!'
]
const anchor = { x: 200, y: 200 }
// 参见下方的 DrawTextField
const drawOptions = {
  anchorPosition: 'TOP_LEFT',
  backgroundColor: 'rgba(0, 0, 0, 0.5)'
}
const drawBox = new faceapi.draw.DrawTextField(text, anchor, drawOptions)
drawBox.draw(document.getElementById('myCanvas'))

DrawTextField 绘图选项:

export interface IDrawTextFieldOptions {
  anchorPosition?: AnchorPosition
  backgroundColor?: string
  fontColor?: string
  fontSize?: number
  fontStyle?: string
  padding?: number
}

export enum AnchorPosition {
  TOP_LEFT = 'TOP_LEFT',
  TOP_RIGHT = 'TOP_RIGHT',
  BOTTOM_LEFT = 'BOTTOM_LEFT',
  BOTTOM_RIGHT = 'BOTTOM_RIGHT'
}

人脸检测选项

SsdMobilenetv1Options

export interface ISsdMobilenetv1Options {
  // 最小置信度阈值
  // 默认:0.5
  minConfidence?: number

  // 返回的最大人脸数量
  // 默认:100
  maxResults?: number
}

// 示例
const options = new faceapi.SsdMobilenetv1Options({ minConfidence: 0.8 })

TinyFaceDetectorOptions

export interface ITinyFaceDetectorOptions {
  // 图像处理时的尺寸,越小速度越快,
  // 但对较小人脸的检测精度较低,必须能被32整除,
  // 常用尺寸有128、160、224、320、416、512、608等。
  // 对于通过摄像头进行人脸跟踪,建议使用较小尺寸,
  // 比如128或160;而检测较小人脸时则应使用较大尺寸,
  // 比如512或608。
  // 默认:416
  inputSize?: number

  // 最小置信度阈值
  // 默认:0.5
  scoreThreshold?: number
}

// 示例
const options = new faceapi.TinyFaceDetectorOptions({ inputSize: 320 })

工具类

IBox

export interface IBox {
  x: number
  y: number
  width: number
  height: number
}

IFaceDetection

export interface IFaceDetection {
  score: number
  box: Box
}

IFaceLandmarks

export interface IFaceLandmarks {
  positions: Point[]
  shift: Point
}

WithFaceDetection

export type WithFaceDetection<TSource> = TSource & {
  detection: FaceDetection
}

WithFaceLandmarks

export type WithFaceLandmarks<TSource> = TSource & {
  unshiftedLandmarks: FaceLandmarks
  landmarks: FaceLandmarks
  alignedRect: FaceDetection
}

WithFaceDescriptor

export type WithFaceDescriptor<TSource> = TSource & {
  descriptor: Float32Array
}

WithFaceExpressions

export type WithFaceExpressions<TSource> = TSource & {
  expressions: FaceExpressions
}

WithAge

export type WithAge<TSource> = TSource & {
  age: number
}

WithGender

export type WithGender<TSource> = TSource & {
  gender: Gender
  genderProbability: number
}

export enum Gender {
  FEMALE = 'female',
  MALE = 'male'
}

其他实用工具

使用低级 API

除了使用高级 API 外,你还可以直接调用各个神经网络的前向方法:

const detections1 = await faceapi.ssdMobilenetv1(input, options)
const detections2 = await faceapi.tinyFaceDetector(input, options)
const landmarks1 = await faceapi.detectFaceLandmarks(faceImage)
const landmarks2 = await faceapi.detectFaceLandmarksTiny(faceImage)
const descriptor = await faceapi.computeFaceDescriptor(alignedFaceImage)

提取图像区域的画布

const regionsToExtract = [
  new faceapi.Rect(0, 0, 100, 100)
]
// extractFaces 实际上用于从边界框中提取人脸区域,
// 但你也可以用它来提取任何其他区域。
const canvases = await faceapi.extractFaces(input, regionsToExtract)

欧几里得距离

// 用于计算两个面部描述符之间的欧几里得距离
const dist = faceapi.euclideanDistance([0, 0], [0, 10])
console.log(dist) // 10

获取人脸关键点和轮廓

const landmarkPositions = landmarks.positions

// 或者获取单个轮廓的关键点位置,
// 仅适用于68点人脸关键点(FaceLandmarks68)
const 下颌轮廓 = landmarks.getJawOutline()
const 鼻子 = landmarks.getNose()
const 嘴巴 = landmarks.getMouth()
const 左眼 = landmarks.getLeftEye()
const 右眼 = landmarks.getRightEye()
const 左眉 = landmarks.getLeftEyeBrow()
const 右眉 = landmarks.getRightEyeBrow()

从 URL 获取并显示图片

<img id="myImg" src="">
const image = await faceapi.fetchImage('/images/example.png')

console.log(image instanceof HTMLImageElement) // 输出: true

// 显示获取到的图片内容
const myImg = document.getElementById('myImg')
myImg.src = image.src

获取 JSON 数据

const json = await faceapi.fetchJson('/files/example.json')

创建图片选择器

<img id="myImg" src="">
<input id="myFileUpload" type="file" onchange="uploadImage()" accept=".jpg, .jpeg, .png">
async function uploadImage() {
  const imgFile = document.getElementById('myFileUpload').files[0]
  // 从 Blob 对象创建 HTMLImageElement
  const img = await faceapi.bufferToImage(imgFile)
  document.getElementById('myImg').src = img.src
}

从图片或视频元素创建 Canvas 元素

<img id="myImg" src="images/example.png" />
<video id="myVideo" src="media/example.mp4" />
const canvas1 = faceapi.createCanvasFromMedia(document.getElementById('myImg'))
const canvas2 = faceapi.createCanvasFromMedia(document.getElementById('myVideo'))

可用模型

人脸检测模型

SSD MobileNet V1

本项目实现了一个基于 MobileNetV1 的 SSD(单次多框检测器)用于人脸检测。该神经网络会计算图像中每张人脸的位置,并返回包含置信度分数的边界框。此检测器旨在高精度地定位人脸边界框,而非追求极低的推理时间。量化后的模型大小约为 5.4 MB(ssd_mobilenetv1_model)。

该人脸检测模型在 WIDERFACE 数据集 上训练,权重由 yeephycho此仓库 中提供。

Tiny 人脸检测器

Tiny 人脸检测器是一种性能优异、实时性很强的人脸检测器,相比 SSD MobileNet V1 检测器速度更快、体积更小、资源消耗更低,但对小人脸的检测效果稍逊一筹。该模型非常适合移动设备和资源受限的客户端使用,因此在这些场景下应优先选择它。量化后的模型大小仅为 190 KB(tiny_face_detector_model)。

该检测器基于一个约 1.4 万张带边界框标注的自定义数据集进行训练。此外,该模型被优化为预测能够完全覆盖面部特征点的边界框,因此与后续的人脸关键点检测结合使用时,通常能获得比 SSD MobileNet V1 更好的结果。

该模型本质上是 Tiny YOLO V2 的更小型版本,用深度可分离卷积替换了 YOLO 中的常规卷积。YOLO 是全卷积网络,因此可以轻松适应不同输入图像尺寸,在准确性和性能(推理时间)之间进行权衡。

68 点人脸关键点检测模型

本包实现了一种轻量级、快速且准确的 68 点人脸关键点检测器。默认模型大小仅为 350 KB(face_landmark_68_model),而小型模型仅为 80 KB(face_landmark_68_tiny_model)。这两个模型均采用了深度可分离卷积和密集连接块的设计思想。它们是在包含约 3.5 万张标注了 68 个关键点的人脸图像的数据集上训练而成的。

人脸识别模型

对于人脸识别任务,本项目实现了一个类似 ResNet-34 的架构,可以从任意一张人脸图像中计算出一个包含 128 个值的特征向量(即人脸描述符),用于表征一个人的面部特征。该模型并不局限于训练数据集中的人脸,因此可用于识别任何人,例如您自己。通过比较两张人脸的描述符,例如计算欧几里得距离或其他分类器,即可判断两人的相似程度。

该神经网络等同于 face-recognition.js 中使用的 FaceRecognizerNet,以及 dlib 人脸识别示例中所用的网络。权重由 davisking 训练,该模型在 LFW(Labeled Faces in the Wild)人脸识别基准测试中的预测准确率达到 99.38%。

量化后的模型大小约为 6.2 MB(face_recognition_model)。

人脸表情识别模型

该表情识别模型轻量、快速,且具有合理的准确性。模型大小约为 310 KB,采用深度可分离卷积和密集连接块结构。它基于公开数据集中的多种图像以及从网上抓取的图像进行训练。需要注意的是,佩戴眼镜可能会影响预测结果的准确性。

年龄和性别识别模型

年龄和性别识别模型是一个多任务网络,包含特征提取层、年龄回归层和性别分类器。该模型大小约为 420 KB,其特征提取部分采用了与 Xception 极为相似的小型架构。

该模型分别在以下数据库上进行了训练和测试,每次采用 80/20 的训练/测试划分:UTK、FGNET、Chalearn、Wiki、IMDB*、CACD*、MegaAge、MegaAge-Asian。其中“*”表示这些数据库经过算法清理,因为原始数据集噪声较大。

总体测试结果

总平均年龄误差(MAE):4.54

性别识别准确率:95%

各数据库的测试结果

“-”表示这些数据库中没有性别标签。

数据库 UTK FGNET Chalearn Wiki IMDB* CACD* MegaAge MegaAge-Asian
MAE 5.25 4.23 6.24 6.54 3.63 3.20 6.23 4.21
性别准确率 0.93 - 0.94 0.95 - 0.97 - -

不同年龄类别组别的测试结果

年龄范围 0 - 3 4 - 8 9 - 18 19 - 28 29 - 40 41 - 60 60 - 80 80+
MAE 1.52 3.06 4.82 4.99 5.43 4.94 6.17 9.91
性别准确率 0.69 0.80 0.88 0.96 0.97 0.97 0.96 0.9

版本历史

0.22.22020/03/22
0.22.12020/02/07
0.22.02019/12/15
0.21.02019/09/15
0.20.12019/06/28
0.20.02019/05/07
0.19.02019/03/27
0.18.02019/01/28
0.17.12019/01/04
0.17.02019/01/02
0.16.22018/12/13
0.16.12018/11/18
0.16.02018/11/12
0.15.12018/10/30
0.15.02018/10/23
0.14.32018/10/03
0.14.22018/10/02
0.14.12018/09/30
0.14.02018/09/26
0.13.02018/09/16

常见问题

相似工具推荐

openclaw

OpenClaw 是一款专为个人打造的本地化 AI 助手,旨在让你在自己的设备上拥有完全可控的智能伙伴。它打破了传统 AI 助手局限于特定网页或应用的束缚,能够直接接入你日常使用的各类通讯渠道,包括微信、WhatsApp、Telegram、Discord、iMessage 等数十种平台。无论你在哪个聊天软件中发送消息,OpenClaw 都能即时响应,甚至支持在 macOS、iOS 和 Android 设备上进行语音交互,并提供实时的画布渲染功能供你操控。 这款工具主要解决了用户对数据隐私、响应速度以及“始终在线”体验的需求。通过将 AI 部署在本地,用户无需依赖云端服务即可享受快速、私密的智能辅助,真正实现了“你的数据,你做主”。其独特的技术亮点在于强大的网关架构,将控制平面与核心助手分离,确保跨平台通信的流畅性与扩展性。 OpenClaw 非常适合希望构建个性化工作流的技术爱好者、开发者,以及注重隐私保护且不愿被单一生态绑定的普通用户。只要具备基础的终端操作能力(支持 macOS、Linux 及 Windows WSL2),即可通过简单的命令行引导完成部署。如果你渴望拥有一个懂你

349.3k|★★★☆☆|1周前
Agent开发框架图像

stable-diffusion-webui

stable-diffusion-webui 是一个基于 Gradio 构建的网页版操作界面,旨在让用户能够轻松地在本地运行和使用强大的 Stable Diffusion 图像生成模型。它解决了原始模型依赖命令行、操作门槛高且功能分散的痛点,将复杂的 AI 绘图流程整合进一个直观易用的图形化平台。 无论是希望快速上手的普通创作者、需要精细控制画面细节的设计师,还是想要深入探索模型潜力的开发者与研究人员,都能从中获益。其核心亮点在于极高的功能丰富度:不仅支持文生图、图生图、局部重绘(Inpainting)和外绘(Outpainting)等基础模式,还独创了注意力机制调整、提示词矩阵、负向提示词以及“高清修复”等高级功能。此外,它内置了 GFPGAN 和 CodeFormer 等人脸修复工具,支持多种神经网络放大算法,并允许用户通过插件系统无限扩展能力。即使是显存有限的设备,stable-diffusion-webui 也提供了相应的优化选项,让高质量的 AI 艺术创作变得触手可及。

162.1k|★★★☆☆|1周前
开发框架图像Agent

everything-claude-code

everything-claude-code 是一套专为 AI 编程助手(如 Claude Code、Codex、Cursor 等)打造的高性能优化系统。它不仅仅是一组配置文件,而是一个经过长期实战打磨的完整框架,旨在解决 AI 代理在实际开发中面临的效率低下、记忆丢失、安全隐患及缺乏持续学习能力等核心痛点。 通过引入技能模块化、直觉增强、记忆持久化机制以及内置的安全扫描功能,everything-claude-code 能显著提升 AI 在复杂任务中的表现,帮助开发者构建更稳定、更智能的生产级 AI 代理。其独特的“研究优先”开发理念和针对 Token 消耗的优化策略,使得模型响应更快、成本更低,同时有效防御潜在的攻击向量。 这套工具特别适合软件开发者、AI 研究人员以及希望深度定制 AI 工作流的技术团队使用。无论您是在构建大型代码库,还是需要 AI 协助进行安全审计与自动化测试,everything-claude-code 都能提供强大的底层支持。作为一个曾荣获 Anthropic 黑客大奖的开源项目,它融合了多语言支持与丰富的实战钩子(hooks),让 AI 真正成长为懂上

154.3k|★★☆☆☆|今天
开发框架Agent语言模型

ComfyUI

ComfyUI 是一款功能强大且高度模块化的视觉 AI 引擎,专为设计和执行复杂的 Stable Diffusion 图像生成流程而打造。它摒弃了传统的代码编写模式,采用直观的节点式流程图界面,让用户通过连接不同的功能模块即可构建个性化的生成管线。 这一设计巧妙解决了高级 AI 绘图工作流配置复杂、灵活性不足的痛点。用户无需具备编程背景,也能自由组合模型、调整参数并实时预览效果,轻松实现从基础文生图到多步骤高清修复等各类复杂任务。ComfyUI 拥有极佳的兼容性,不仅支持 Windows、macOS 和 Linux 全平台,还广泛适配 NVIDIA、AMD、Intel 及苹果 Silicon 等多种硬件架构,并率先支持 SDXL、Flux、SD3 等前沿模型。 无论是希望深入探索算法潜力的研究人员和开发者,还是追求极致创作自由度的设计师与资深 AI 绘画爱好者,ComfyUI 都能提供强大的支持。其独特的模块化架构允许社区不断扩展新功能,使其成为当前最灵活、生态最丰富的开源扩散模型工具之一,帮助用户将创意高效转化为现实。

108.3k|★★☆☆☆|3天前
开发框架图像Agent

gemini-cli

gemini-cli 是一款由谷歌推出的开源 AI 命令行工具,它将强大的 Gemini 大模型能力直接集成到用户的终端环境中。对于习惯在命令行工作的开发者而言,它提供了一条从输入提示词到获取模型响应的最短路径,无需切换窗口即可享受智能辅助。 这款工具主要解决了开发过程中频繁上下文切换的痛点,让用户能在熟悉的终端界面内直接完成代码理解、生成、调试以及自动化运维任务。无论是查询大型代码库、根据草图生成应用,还是执行复杂的 Git 操作,gemini-cli 都能通过自然语言指令高效处理。 它特别适合广大软件工程师、DevOps 人员及技术研究人员使用。其核心亮点包括支持高达 100 万 token 的超长上下文窗口,具备出色的逻辑推理能力;内置 Google 搜索、文件操作及 Shell 命令执行等实用工具;更独特的是,它支持 MCP(模型上下文协议),允许用户灵活扩展自定义集成,连接如图像生成等外部能力。此外,个人谷歌账号即可享受免费的额度支持,且项目基于 Apache 2.0 协议完全开源,是提升终端工作效率的理想助手。

100.8k|★★☆☆☆|4天前
插件Agent图像

markitdown

MarkItDown 是一款由微软 AutoGen 团队打造的轻量级 Python 工具,专为将各类文件高效转换为 Markdown 格式而设计。它支持 PDF、Word、Excel、PPT、图片(含 OCR)、音频(含语音转录)、HTML 乃至 YouTube 链接等多种格式的解析,能够精准提取文档中的标题、列表、表格和链接等关键结构信息。 在人工智能应用日益普及的今天,大语言模型(LLM)虽擅长处理文本,却难以直接读取复杂的二进制办公文档。MarkItDown 恰好解决了这一痛点,它将非结构化或半结构化的文件转化为模型“原生理解”且 Token 效率极高的 Markdown 格式,成为连接本地文件与 AI 分析 pipeline 的理想桥梁。此外,它还提供了 MCP(模型上下文协议)服务器,可无缝集成到 Claude Desktop 等 LLM 应用中。 这款工具特别适合开发者、数据科学家及 AI 研究人员使用,尤其是那些需要构建文档检索增强生成(RAG)系统、进行批量文本分析或希望让 AI 助手直接“阅读”本地文件的用户。虽然生成的内容也具备一定可读性,但其核心优势在于为机器

93.4k|★★☆☆☆|1周前
插件开发框架