123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134 |
- 'use strict'
- let os = require("os");
- let isWindows = os.platform().startsWith("win");
- let path = require("path");
- // import nodejs bindings to native tensorflow,
- // not required, but will speed up things drastically (python required)
- let process = require("process");
- process.env.TF_CPP_MIN_LOG_LEVEL=2
- const shell = require("shelljs")
- if(!isWindows){ // 仅在Linux下启动内存加速和GPU加速
- let nvidiaSmi = shell.exec("nvidia-smi",{silent:true})
- if(nvidiaSmi?.stdout.indexOf("CUDA")>-1){
- console.log("facetf gpu mode")
- require('@tensorflow/tfjs-node-gpu');
- }else{
- console.log("facetf cpu mode")
- require('@tensorflow/tfjs-node');
- }
- }
- // implements nodejs wrappers for HTMLCanvasElement, HTMLImageElement, ImageData
- let canvas = require('canvas');
- // import * as faceapi from 'face-api.js';
- let faceapi = require('@vladmandic/face-api/dist/face-api.node.js');
- const baseDir = path.resolve(__dirname, './tmp')
- // 设置识别参数
- // mokey pathing the faceapi canvas
- const { Canvas, Image, ImageData } = canvas
- faceapi.env.monkeyPatch({ Canvas, Image, ImageData })
- const faceDetectionNet = faceapi.nets.ssdMobilenetv1
- // SsdMobilenetv1Options
- const minConfidence = 0.5
- // TinyFaceDetectorOptions
- const inputSize = 408
- const scoreThreshold = 0.5
- // MtcnnOptions
- const minFaceSize = 50
- const scaleFactor = 0.8
- const faceDetectionOptions = getFaceDetectorOptions(faceDetectionNet)
- var FACE_TFJS_WEIGHTS_LOADED = false;
- async function loadModel(){
- // load weights 首次调用加载模型
- if(!FACE_TFJS_WEIGHTS_LOADED){
- await faceDetectionNet.loadFromDisk(path.join(__dirname,'./model'))
- await faceapi.nets.faceLandmark68Net.loadFromDisk(path.join(__dirname,'./model'))
- await faceapi.nets.faceRecognitionNet.loadFromDisk(path.join(__dirname,'./model'))
- FACE_TFJS_WEIGHTS_LOADED = true
- }
- }
- loadModel()
- class FacetfSDK{
- constructor(){
- }
- async getPhotoFeat68(photoUrl){
- let detections = await this.detectFaceWithLandmarksAndDescriptor(photoUrl);
- if(detections?.length>0){
- let feat68 = Array.from(detections[0]?.descriptor);
- return feat68
- }
- return null
- }
- async setReportFeat68(report){
- if(report?.className && !report?.get("feat68")){
- let detections = await this.detectFaceWithLandmarksAndDescriptor(report.get("photo"));
- if(detections?.length>0){
- let feat68 = Array.from(detections[0]?.descriptor);
- report.set("feat68",feat68)
- }
- }
- await report.save();
- return report
- }
- async detectFaceWithLandmarksAndDescriptor(img1){
- await loadModel();
-
- let referenceImage
- try{
- referenceImage = await canvas.loadImage(img1)
- }catch(err){
- throw "图片地址有误无法加载"
- }
- if(!(referenceImage)){
- throw "图片不够清晰请重新上传"
- }
- let detections = await faceapi.detectAllFaces(referenceImage, faceDetectionOptions)
- .withFaceLandmarks()
- .withFaceDescriptors()
- if(!detections){
- throw "图片不够清晰请重新上传"
- }
- if(detections.length==0){
- // openapi.goWrong(response,"照片未上传或不清晰,请重新上传");
- let imgstr = ""
- if(detections.length==0){
- imgstr += "<1>"
- }
- throw `图${imgstr}无法识别人脸`
- }
- // 获取特征向量 68关键点 以及128特征向量
- return detections
- }
- }
- function getFaceDetectorOptions(net) {
- return net === faceapi.nets.ssdMobilenetv1
- ? new faceapi.SsdMobilenetv1Options({ minConfidence })
- : (net === faceapi.nets.tinyFaceDetector
- ? new faceapi.TinyFaceDetectorOptions({ inputSize, scoreThreshold })
- : new faceapi.MtcnnOptions({ minFaceSize, scaleFactor })
- )
- }
- module.exports.FacetfSDK = FacetfSDK
|