const psqlDB = require("./psql.service"); class FaceService{ async getSameReportList(feat68,limit){ limit = limit || 10; // cosine_similarity let sql = ` select "objectId" as id,"photo","createdAt", array_agg(item)::vector(128) <=> $1::vector(128) as cos from ( SELECT *, jsonb_array_elements("feat68")::float AS item from ( SELECT "objectId","photo","feat68","createdAt" FROM "FaceReport" WHERE "feat68" is not null ORDER BY "createdAt" DESC limit ${limit} ) as rt1 ) as rt GROUP BY "objectId",rt."photo","createdAt" ` let params = [feat68] let result = await psqlDB.any(sql,params) // 人物不同 0.08 0.09 0.06 0.059 // 人物不同 长相像 0.046 0.045 0.043 0.039 // 人物相同 仰角/光照有变化 0.03846 // 人物相同 > 0.0214 0.0188 0.00218 0.038 0.023 result = result.filter(item=>item.cos<0.0385 && item.id!=report.id) result.sort((a,b)=>a.createdAt-b.createdAt) if(result?.length>0){ console.log(result) } return result } async matchDistance(img1,img2){ let referenceImage let queryImage try{ referenceImage = await canvas.loadImage(img1) queryImage = await canvas.loadImage(img2) }catch(err){ console.error(err) response.status(500); response.json({ code: 500, mess: "图片地址有误无法加载" }); } if(!(referenceImage&&queryImage)){ response.status(500); response.json({ code: 500, mess: "图片不够清晰请重新上传" }); } let resultsRef = await faceapi.detectAllFaces(referenceImage, faceDetectionOptions) .withFaceLandmarks() .withFaceDescriptors() let resultsQuery = await faceapi.detectAllFaces(queryImage, faceDetectionOptions) .withFaceLandmarks() .withFaceDescriptors() if(!resultsRef || !resultsQuery){ response.json({ code:200, data:{ label:`照片未上传或不清晰,请重新上传`, distance:1, score:0 } }) return } if(resultsRef.length==0 || resultsQuery.length==0){ // openapi.goWrong(response,"照片未上传或不清晰,请重新上传"); let imgstr = "" if(resultsRef.length==0){ imgstr += "<1>" } if(resultsQuery.length==0){ imgstr += "<2>" } response.json({ code:200, data:{ label:`图${imgstr}无法识别人脸`, distance:1, score:0 } }) return } let faceMatcher = new faceapi.FaceMatcher(resultsRef) let labels = faceMatcher.labeledDescriptors .map(ld => ld.label) let bestMatch; let label="",distance=1,score=0; resultsQuery.forEach(res => { bestMatch = faceMatcher.findBestMatch(res.descriptor) if(bestMatch._label.startsWith("person")){ label = bestMatch._label; distance = bestMatch._distance; score = 1-distance; }; // if(bestMatch._distance > score){ // score=bestMatch._distance // }; }) } } module.exports.FaceService = FaceService