facetf.sdk.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. 'use strict'
  2. let os = require("os");
  3. let isWindows = os.platform().startsWith("win");
  4. let path = require("path");
  5. // import nodejs bindings to native tensorflow,
  6. // not required, but will speed up things drastically (python required)
  7. let process = require("process");
  8. process.env.TF_CPP_MIN_LOG_LEVEL=2
  9. const shell = require("shelljs")
  10. if(!isWindows){ // 仅在Linux下启动内存加速和GPU加速
  11. let nvidiaSmi = shell.exec("nvidia-smi",{silent:true})
  12. if(nvidiaSmi?.stdout.indexOf("CUDA")>-1){
  13. console.log("facetf gpu mode")
  14. require('@tensorflow/tfjs-node-gpu');
  15. }else{
  16. console.log("facetf cpu mode")
  17. require('@tensorflow/tfjs-node');
  18. }
  19. }
  20. // implements nodejs wrappers for HTMLCanvasElement, HTMLImageElement, ImageData
  21. let canvas = require('canvas');
  22. // import * as faceapi from 'face-api.js';
  23. let faceapi = require('@vladmandic/face-api/dist/face-api.node.js');
  24. const baseDir = path.resolve(__dirname, './tmp')
  25. // 设置识别参数
  26. // mokey pathing the faceapi canvas
  27. const { Canvas, Image, ImageData } = canvas
  28. faceapi.env.monkeyPatch({ Canvas, Image, ImageData })
  29. const faceDetectionNet = faceapi.nets.ssdMobilenetv1
  30. // SsdMobilenetv1Options
  31. const minConfidence = 0.5
  32. // TinyFaceDetectorOptions
  33. const inputSize = 408
  34. const scoreThreshold = 0.5
  35. // MtcnnOptions
  36. const minFaceSize = 50
  37. const scaleFactor = 0.8
  38. const faceDetectionOptions = getFaceDetectorOptions(faceDetectionNet)
  39. var FACE_TFJS_WEIGHTS_LOADED = false;
  40. async function loadModel(){
  41. // load weights 首次调用加载模型
  42. if(!FACE_TFJS_WEIGHTS_LOADED){
  43. await faceDetectionNet.loadFromDisk(path.join(__dirname,'./model'))
  44. await faceapi.nets.faceLandmark68Net.loadFromDisk(path.join(__dirname,'./model'))
  45. await faceapi.nets.faceRecognitionNet.loadFromDisk(path.join(__dirname,'./model'))
  46. FACE_TFJS_WEIGHTS_LOADED = true
  47. }
  48. }
  49. loadModel()
  50. class FacetfSDK{
  51. constructor(){
  52. }
  53. async getPhotoFeat68(photoUrl){
  54. let detections = await this.detectFaceWithLandmarksAndDescriptor(photoUrl);
  55. if(detections?.length>0){
  56. let feat68 = Array.from(detections[0]?.descriptor);
  57. return feat68
  58. }
  59. return null
  60. }
  61. async setReportFeat68(report){
  62. if(report?.className && !report?.get("feat68")){
  63. let detections = await this.detectFaceWithLandmarksAndDescriptor(report.get("photo"));
  64. if(detections?.length>0){
  65. let feat68 = Array.from(detections[0]?.descriptor);
  66. report.set("feat68",feat68)
  67. }
  68. }
  69. await report.save();
  70. return report
  71. }
  72. async detectFaceWithLandmarksAndDescriptor(img1){
  73. await loadModel();
  74. let referenceImage
  75. try{
  76. referenceImage = await canvas.loadImage(img1)
  77. }catch(err){
  78. throw "图片地址有误无法加载"
  79. }
  80. if(!(referenceImage)){
  81. throw "图片不够清晰请重新上传"
  82. }
  83. let detections = await faceapi.detectAllFaces(referenceImage, faceDetectionOptions)
  84. .withFaceLandmarks()
  85. .withFaceDescriptors()
  86. if(!detections){
  87. throw "图片不够清晰请重新上传"
  88. }
  89. if(detections.length==0){
  90. // openapi.goWrong(response,"照片未上传或不清晰,请重新上传");
  91. let imgstr = ""
  92. if(detections.length==0){
  93. imgstr += "<1>"
  94. }
  95. throw `图${imgstr}无法识别人脸`
  96. }
  97. // 获取特征向量 68关键点 以及128特征向量
  98. return detections
  99. }
  100. }
  101. function getFaceDetectorOptions(net) {
  102. return net === faceapi.nets.ssdMobilenetv1
  103. ? new faceapi.SsdMobilenetv1Options({ minConfidence })
  104. : (net === faceapi.nets.tinyFaceDetector
  105. ? new faceapi.TinyFaceDetectorOptions({ inputSize, scoreThreshold })
  106. : new faceapi.MtcnnOptions({ minFaceSize, scaleFactor })
  107. )
  108. }
  109. module.exports.FacetfSDK = FacetfSDK