34
chenyc
2025-01-24 fb5abaff7d80096163dd712e74b8b7e0b968b84d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
require("@tensorflow/tfjs-node");
const fs= require ('fs');
const express = require("express");
const moment = require("moment");
// 配置 cors 这个中间件
const cors = require('cors')
// const faceapi = require("face-api.js");
const faceapi = require('@vladmandic/face-api');
const mongoose = require("mongoose");
const canvas = require("canvas");
const { Canvas, Image } = require("canvas");
const fileUpload = require("express-fileupload");
const multer = require('multer')
console.log('----')
faceapi.env.monkeyPatch({ Canvas, Image });
 
const app = express();
// 设置存放格式
const storage = multer.diskStorage({
  destination(req, file, cb) {
    cb(null, './uploads')
  },
  filename(req, file, cb) {
    cb(null, Date.now() + '-' + file.originalname)
  }
})
// 加载文件存储
const upload = multer({ storage })
// app.use(
//   fileUpload({
//     useTempFiles: true,
//   })
// );
app.use(cors())
app.use(express.static('./web'))
app.use('/uploads', express.static('./uploads'));
async function LoadModels() {
  await faceapi.nets.faceRecognitionNet.loadFromDisk(__dirname + "/models");
  await faceapi.nets.faceLandmark68Net.loadFromDisk(__dirname + "/models");
  await faceapi.nets.ssdMobilenetv1.loadFromDisk(__dirname + "/models");
}
 
LoadModels();
 
const faceSchema = new mongoose.Schema({
  label: {
    type: String,
    required: true,
    unique: true,
  },
  images:{
    type:Array,
    required:true
  },
  descriptions: {
    type: Array,
    required: true,
  },
});
 
const FaceModel = mongoose.model("Face", faceSchema);
 
 
/**
 * 
 * @param {图片} images 
 * @param {图片标记:张三} label 
 * @returns 
 */
async function uploadLabeledImages(images, label) {
  try {
    let counter = 0;
    const descriptions = [];
    const imgs=[]
    // 循环图片
    for (let i = 0; i < images.length; i++) {
      const img = await canvas.loadImage(images[i]);
      counter = (i / images.length) * 100;
      console.log(`Progress = ${counter}%`);
      // Read each face and save the face descriptions in the descriptions array
      const detections = await faceapi.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor();
      descriptions.push(detections.descriptor);
      imgs.push(images[i])
    }
    //用给定的标签创建一个新的面文档,并将其保存在数据库中
    const createFace = new FaceModel({
      label: label,
      descriptions: descriptions,
      images:imgs
    });
    try{
      await createFace.save();
      console.log('人脸录入成功!')
      return true
    }catch(error){
      return error;
    }
  } catch (error) {
    console.log(error);
    return (error);
  }
}
/**
 * 清空 人脸库
 * @param {人物标记} label 
 * @returns 
 */
async function deleteLabelImages(label) {
  try{
    await FaceModel.deleteMany({ label: label })
    return true
  }catch(error){  
    return error
  }
  
}
/**
 * 清空 人脸库
 * @param {人物标记} label 
 * @returns 
 */
async function selectLabelImages(label) {
  try{
    await FaceModel.findOne({ label: label })
    return true
  }catch(error){  
    return error
  }
  
}
async function getDescriptorsFromDB(image) {
  // 从mongodb获取所有的面部数据,并循环遍历每个面部数据以读取数据
  let faces = await FaceModel.find();
  for (i = 0; i < faces.length; i++) {
    // 将面数据描述符从obiects更改为Float32Array类型
    for (j = 0; j < faces[i].descriptions.length; j++) {
      faces[i].descriptions[j] = new Float32Array(Object.values(faces[i].descriptions[j]));
    }
    // 将DB面文档改为
    faces[i] = new faceapi.LabeledFaceDescriptors(faces[i].label, faces[i].descriptions);
  }
 
  // 加载面匹配器以查找匹配面
  const faceMatcher = new faceapi.FaceMatcher(faces, 0.45);
  // 使用画布或其他方法读取图像
  const img = await canvas.loadImage(image);
  let temp = faceapi.createCanvasFromMedia(img);
  // 处理模型的图像
  const displaySize = { width: img.width, height: img.height };
  faceapi.matchDimensions(temp, displaySize);
  const currentTime = moment().format("YYYY-MM-DD HH:mm:ss");
  // 查找匹配的人脸
  const detections = await faceapi.detectAllFaces(img).withFaceLandmarks().withFaceDescriptors();
  const currentTime2 = moment().format("YYYY-MM-DD HH:mm:ss");
  const resizedDetections = faceapi.resizeResults(detections, displaySize);
  const results = resizedDetections.map((d) => faceMatcher.findBestMatch(d.descriptor));
  return results;
}
 
 
/**
 * 上传人脸信息
 */
app.post("/post-face",upload.array('files',6),async (req,res)=>{
    let imgs=[]
    for (let i = 0; i < req.files.length; i++) {
      imgs.push(req.files[i].path)
    }
    let label = req.body.label
    console.log('---------------',label)
    let result = await uploadLabeledImages(imgs, label);
    console.log('---------------',result)
    if(result===true){ 
        
        res.json({code:200, message:"录入成功"})
    }else{
        // let result = await getDescriptorsFromDB(File1);
        imgs.forEach(e=>{
          fs.unlink(e,(err)=>{
            if(err){
              console.log('删除失败')
            }else{
              console.log('删除成功')
            }
          })
        })
        
        res.json({code:400, message:"人脸模型录入失败,请重新录入"})
        
    }
})
/**验证人脸对比 */
app.post("/check-face",upload.single('file'), async (req, res) => {
  console.log(req.file)
  const File1 = req.file.path;
  try {
    let result = await getDescriptorsFromDB(File1);
    fs.unlink(File1,(err)=>{
      if(err){
        console.log('删除失败')
      }else{
        console.log('删除成功')
      }
    })
    res.json({code:200,result });
  } catch (error) {
    res.json({code:200,error });
  }
  
  
});
// 获取人脸模型
app.post('/get-face',upload.single('file'),async (req, res) => {
  const label = req.body.label
  const result=await FaceModel.findOne({ "label": label })
  res.json({code:200,result})
})
// 清除人脸模型
app.post("/del-face",upload.single('file'),async(req,res)=>{
  const label = req.body.label
  console.log('删除人脸库',label)
  FaceModel.findOne({ "label": label }).then(re=>{
    console.log('kankan---')
    console.log(re.images)
    if(re.images.length>0){
      for (let i = 0; i < re.images.length; i++) {
        fs.unlink(re.images[i],(err)=>{
          if(err){
            console.log('删除失败')
          }else{
            console.log('删除成功')
          }
        })
      }
    }
  })
  let result= deleteLabelImages(label)
  if(result){
    res.json({message:'success'})
 
  }else{
    res.json({message:"err"})
  }
})
app.post("/test",async(req,res)=>{
  console.log('---测试--------')
  res.json({message:"err"})
  
})
 
 
 
//链接数据库初始化
mongoose
  .connect(
    `mongodb://localhost/test`,
    {
      useNewUrlParser: true,
      useUnifiedTopology: true,
      useCreateIndex: true,
    }
  )
  .then(() => {
    app.listen(process.env.PORT || 5000);
    console.log("DB connected and server us running.");
    console.log('http-sse-'+5000)
  })
  .catch((err) => {
    console.log(err);
  });