深度神经网络——如何在浏览器中运行深度网络 OpenCV v4.8.0

上一个教程YOLO DNNs

下一个教程自定义深度学习层支持

原作者Dmitry Kurtaev
兼容性OpenCV >= 3.3.1

简介

本教程将向我们展示如何在浏览器中使用 OpenCV.js 运行深度学习模型。教程参考了人脸检测和人脸识别模型管道的示例。

人脸检测

人脸检测网络将 BGR 图像作为输入,并生成一组可能包含人脸的边界框。我们需要做的只是选择具有较强置信度的边界框。

人脸识别

网络名为 OpenFace(项目 https://github.com/cmusatyalab/openface)。人脸识别模型接收大小为 96x96 的 RGB 人脸图像。然后返回 128 维单位向量,将输入的人脸表示为单位多维球体上的一个点。因此,两个人脸之间的差异就是两个输出向量之间的夹角。

样本

所有示例都是 HTML 页面,其中包含使用 OpenCV.js 功能的 JavaScript 代码。您可以在下面看到该页面的插入内容。按开始按钮开始演示。按添加一个人,命名一个被识别为未知的人。接下来我们将讨论代码的主要部分。

原页面可以实现这个功能,但是这里跳接的时候无法还原这个功能,所以只能把原页面地址给出了:
https://docs.opencv.org/4.8.0/d5/d86/tutorial_dnn_javascript.html

  1. 运行人脸检测网络,检测输入图像上的人脸。
function detectFaces(img) {
  var blob = cv.blobFromImage(img, 1, {width: 192, height: 144}, [104, 117, 123, 0], false, false);
  netDet.setInput(blob);
  var out = netDet.forward();
  var faces = [];
  for (var i = 0, n = out.data32F.length; i < n; i += 7) {
    var confidence = out.data32F[i + 2];
    var left = out.data32F[i + 3] * img.cols;
    var top = out.data32F[i + 4] * img.rows;
    var right = out.data32F[i + 5] * img.cols;
    var bottom = out.data32F[i + 6] * img.rows;
    left = Math.min(Math.max(0, left), img.cols - 1);
    right = Math.min(Math.max(0, right), img.cols - 1);
    bottom = Math.min(Math.max(0, bottom), img.rows - 1);
    top = Math.min(Math.max(0, top), img.rows - 1);
    if (confidence > 0.5 && left < right && top < bottom) {
      faces.push({x: left, y: top, width: right - left, height: bottom - top})
    }
  }
  blob.delete();
  out.delete();
  return faces;
};

您可以调整输入 blob 的大小,以平衡检测质量和效率。输入 blob 越大,检测到的人脸可能越少。

  1. 运行人脸识别网络,接收输入人脸图像的 128 维单位特征向量。
function face2vec(face) {
  var blob = cv.blobFromImage(face, 1.0 / 255, {width: 96, height: 96}, [0, 0, 0, 0], true, false)
  netRecogn.setInput(blob);
  var vec = netRecogn.forward();
  blob.delete();
  return vec;
};
  1. 执行识别。
function recognize(face) {
  var vec = face2vec(face);
  var bestMatchName = 'unknown';
  var bestMatchScore = 0.5; // 实际上,最小值是-1,但我们将其作为阈值。
  for (name in persons) {
    var personVec = persons[name];
    var score = vec.dot(personVec)if (score > bestMatchScore) {
      bestMatchScore = score;
      bestMatchName = name;
    }
  }
  vec.delete()return bestMatchName;
};

将新的特征向量与已注册的特征向量匹配。返回匹配度最高的人的姓名。

  1. 主循环
  var isRunning = falseconst FPS = 30; // 每秒处理的目标帧数。
  function captureFrame() {
    var begin = Date.now();
    cap.read(frame); // 从摄像机读取一帧图像
    cv.cvtColor(frame, frameBGR, cv.COLOR_RGBA2BGR);
    var faces = detectFaces(frameBGR);
    faces.forEach(function(rect) {
      cv.rectangle(frame, {x: rect.x, y: rect.y}, {x: rect.x + rect.width, y: rect.y + rect.height}, [0, 255, 0, 255]);
      var face = frameBGR.roi(rect);
      var name = recognize(face);
      cv.putText(frame, name, {x: rect.x, y: rect.y}, cv.FONT_HERSHEY_SIMPLEX, 1.0, [0, 255, 0, 255])});
    cv.imshow(output, frame)// 循环此函数。
    if (isRunning) {
      var delay = 1000 / FPS - (Date.now() - begin)setTimeout(captureFrame, delay)}
  };

应用程序的主循环接收来自摄像头的帧,并对帧上检测到的每个人脸进行识别。我们在初始化 OpenCV.js 和下载深度学习模型时启动该函数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值