劉孟學
劉孟學

Reputation: 1

How can i save float32array data into mongodb?

i try to save a float32array datatype of Descriptors used in face-api.js tutorial into mongodb, which creats error as follows:

Error [ValidationError]: Face validation failed: face1: Cast to Number failed for value "[
  '-0.07273564487695694',
  '0.06783964484930038',
  '0.017196351662278175',
  '-0.06767699867486954',
  '0.018848462030291557',
  '-0.008953484706580639',
  '-0.10941299051046371',
  '-0.08474595099687576',
  '0.18334418535232544',
  '-0.13277113437652588',
  '0.21881742775440216',
  '0.05348524823784828',
  '-0.1738838255405426',
  '-0.10882828384637833',
  '0.022012043744325638',
  '0.12650063633918762',
  '-0.1980297714471817',
  '-0.05259150266647339',
  '-0.1738252341747284',
  '-0.07430439442396164',
  '-0.00950242392718792',
  '0.016983192414045334',
  '0.14309418201446533',
  '0.007861343212425709',
  '-0.15108434855937958',
  '-0.3753374516963959',
  '-0.09251140058040619',
  '-0.15258368849754333',
  '0.018157916143536568',
  '-0.14218701422214508',
  '-0.09158512204885483',
  '-0.027028504759073257',
  '-0.18213948607444763',
  '-0.08395160734653473',
  '-0.01923770271241665',
  '-0.009705804288387299',
  '-0.016477856785058975',
  '-0.01471498142927885',
  '0.2132747620344162',
  '0.09748928248882294',
  '-0.12596380710601807',
  '0.09632328897714615',
  '-0.010693545453250408',
  '0.2434854358434677',
  '0.2999197244644165',
  '0.045587435364723206',
  '0.03161664679646492',
  '-0.05649133771657944',
  '0.15018106997013092',
  '-0.23106248676776886',
  '0.0143006332218647',
  '0.11923261731863022',
  '0.10614773631095886',
  '0.04596344381570816',
  '0.11038381606340408',
  '-0.1268938034772873',
  '-0.000030407682061195374',
  '0.0907360389828682',
  '-0.09167303889989853',
  '0.06623714417219162',
  '0.03635689243674278',
  '-0.08683675527572632',
  '-0.029647760093212128',
  '0.038635361939668655',
  '0.1835651397705078',
  '0.06123190000653267',
  '-0.13125522434711456',
  '-0.06574095040559769',
  '0.12370463460683823',
  '-0.024815889075398445',
  '0.03423560783267021',
  '-0.015258995816111565',
  '-0.16121728718280792',
  '-0.18937481939792633',
  '-0.2804066240787506',
  '0.035129714757204056',
  '0.2984723448753357',
  '0.12609252333641052',
  '-0.22052307426929474',
  '0.0007893451256677508',
  '-0.19253642857074738',
  '0.02280258946120739',
  '0.008555280975997448',
  '0.013857826590538025',
  '-0.07759181410074234',
  '-0.06886880099773407',
  '-0.08058007806539536',
  '0.027053244411945343',
  '0.13577044010162354',
  '-0.014992798678576946',
  '-0.0033843964338302612',
  '0.18782006204128265',
  '-0.03454151004552841',
  '0.03207124397158623',
  '0.021744150668382645',
  '0.06258267164230347',
  '-0.229567289352417',
  '-0.049789320677518845',
  '-0.15495271980762482',
  '-0.009344004094600677',
  ... 28 more items
]" at path "face1", face2: Cast to Number failed for value "[
  '-0.09841682761907578',   '0.10429154336452484',   '0.02155156247317791',
  '-0.0520382784307003',    '0.003075589891523123',  '0.02731766179203987',
  '-0.06316100805997849',   '-0.08978841453790665',  '0.17524316906929016',
  '-0.06021083891391754',   '0.20898853242397308',   '0.04531601443886757',
  '-0.2273748219013214',    '-0.13791939616203308',  '0.03461577743291855',
  '0.10593116283416748',    '-0.16997823119163513',  '-0.04051877558231354',
  '-0.1157040074467659',    '-0.13753467798233032',  '0.00451170327141881',
  '-0.0035286874044686556', '0.12593451142311096',   '0.03245891258120537',
  '-0.19241401553153992',   '-0.3184763491153717',   '-0.04043048247694969',
  '-0.17030549049377441',   '-0.0513293594121933',   '-0.08657143265008926',
  '-0.043777234852313995',  '0.012140932492911816',  '-0.1894371658563614',
  '-0.12472780793905258',   '0.0404059961438179',    '0.013797461055219173',
  '-0.0014847844140604138', '0.02460971660912037',   '0.20598173141479492',
  '0.01733708567917347',    '-0.10046811401844025',  '0.10734308511018753',
  '0.03710935637354851',    '0.23082618415355682',   '0.25308746099472046',
  '0.06004834920167923',    '-0.01260399166494608',  '-0.06998976320028305',
  '0.14949968457221985',    '-0.24164462089538574',  '0.048128850758075714',
  '0.1337026059627533',     '0.061368342489004135',  '0.02466494031250477',
  '0.0861603170633316',     '-0.15172605216503143',  '-0.0034477391745895147',
  '0.10432615131139755',    '-0.12314924597740173',  '0.037213362753391266',
  '0.02678604982793331',    '-0.09252163767814636',  '-0.07801863551139832',
  '0.03722367063164711',    '0.14181503653526306',   '0.11837714165449142',
  '-0.10465218871831894',   '-0.0963580384850502',   '0.12955503165721893',
  '-0.015165491960942745',  '0.0335954874753952',    '0.04591371864080429',
  '-0.17047487199306488',   '-0.200806125998497',    '-0.24049332737922668',
  '0.1046692430973053',     '0.3785543143749237',    '0.15583226084709167',
  '-0.1976466029882431',    '-0.016453050076961517', '-0.17181381583213806',
  '0.07842658460140228',    '0.07034406810998917',   '-0.011151890270411968',
  '-0.06393297761678696',   '-0.11788173764944077',  '-0.01764458790421486',
  '0.06571757048368454',    '0.0907316505908966',    '0.00919581949710846',
  '-0.06429607421159744',   '0.20871053636074066',   '0.0032271952368319035',
  '0.060321446508169174',   '0.026394570246338844',  '0.03664182126522064',
  '-0.14991241693496704',   '0.005795528646558523',  '-0.20117248594760895',
  '-0.01487714983522892',
  ... 28 more items
]"..............and so on

here is my database

var faceSchema = mongoose.Schema({
   name: String,
   face1: Number,
   face2: Number,
   face3: Number
});

var Face = mongoose.model("Face", faceSchema);

here is when i save it to database

app.post('/face_check',function (req, res){
  

   var faceInfo = req.body; //Get the parsed information
   console.log(faceInfo.name);
   console.log(faceInfo.face1);
   var newFace = new Face({
      name: faceInfo.name,
      face1: faceInfo.face1,
      face2: faceInfo.face2,
      face3: faceInfo.face3

   });
   
   newFace.save(function(err, Face){
      if(err)
         console.log(err);
      else
         console.log("success saveing face ino");
   });

      

   


});
which will get post from the following

const singleResulto1 = await faceapi
      .detectSingleFace(input1)
      .withFaceLandmarks()
      .withFaceDescriptor()

      const singleResulto2 = await faceapi
      .detectSingleFace(input2)
      .withFaceLandmarks()
      .withFaceDescriptor()

      const singleResulto3 = await faceapi
      .detectSingleFace(input3)
      .withFaceLandmarks()
      .withFaceDescriptor()
        
        
$.post("/face_check", {
          name: username, 
          face1: singleResulto1.descriptor,
          face2: singleResulto2.descriptor,
          face3: singleResulto3.descriptor
      });

Upvotes: 0

Views: 599

Answers (2)

Md. Shahla Zulkarnine
Md. Shahla Zulkarnine

Reputation: 56

I'm not sure if you were able to find the solution to this or no, but here is how I solved it. The main problem was that while storing the data into MongoDB, it was getting turned in Object type , therefore when you got the data from MongoDB, you were required to turn it into Float32Array type. This was the tricky part, because in order for the function to work, we first need to turn the ObjectType into Array and then into Float32Array.

To give some background understanding, here is how I defined my Schema -

const faceSchema = new Schema({
    label:{
        type:String,
        required:true,
        unique:true
    },
    descriptions:{
        type:Object,
        required:true
    }
})

Now I think it's clear how I'm storing the data. The following code is where I upload the data to the DB, notice that I only store the descriptions -

async function uploadLabeledImages(images, label) {

    const descriptions = [];
    // Loop through the images
    for (let i = 1; i < images.length; i++) {
      const img = await canvas.loadImage(images[i]);

      // Read each face and save the face descriptions in the descriptions array
      const detections = await faceapi.detectSingleFace(img).withFaceLandmarks().withFaceDescriptor();
      descriptions.push(detections.descriptor);
    }

    // Create a new face document with the given label and save it in DB
    const createFace = new Face({
      label: label,
      descriptions: descriptions,
    });
    await createFace.save();
    return true;
  
}

Next I will show how I got the data from the DB and how I converted it to Float32Array-

async function LoadFaceMatcherFromDB() {
  // Get all the face data from mongodb and loop through each of them to read the data
  let faces = await Face.find();
  for (i = 0; i < faces.length; i++) {
    // Change the face data descriptors from Objects to Float32Array type
    for (j = 0; j < faces[i].descriptions.length; j++) {
    
    // Please pay attention to this part, this is where the magic happens
    // For each desciption Object stored in my DB I turn it into an Array then Float32Array
      faces[i].descriptions[j] = new Float32Array(Object.values(faces[i].descriptions[j]));
    
    
    }
    // Turn the DB face docs to Descriptors
    faces[i] = new faceapi.LabeledFaceDescriptors(faces[i].label, faces[i].descriptions);
  }

  // Load the models
  await faceapi.nets.faceRecognitionNet.loadFromDisk(reqPath + "/models/rec-model");
  await faceapi.nets.faceLandmark68Net.loadFromDisk(reqPath + "/models/rec-model");
  await faceapi.nets.ssdMobilenetv1.loadFromDisk(reqPath + "/models/rec-model");

  // Load face matcher to find the matching face
  const faceMatcher = new faceapi.FaceMatcher(faces, 0.6);
  return faceMatcher;
}

I hope this solves your problem. May the force be with those who visit this page.

Upvotes: 2

WanderQing
WanderQing

Reputation: 1

I am using face-api.js right now. Please try define your schema as following code.

const landMarkSchema = new Schema({
    _label:{
        type: String,
        required: true,
        unique: true
    },
    _descriptors:{
        type: [Object],
        required: true
    }
})
module.exports = mongoose.model('FaceLandmark',landMarkSchema,'face_landmark');

Upvotes: 0

Related Questions