ArcSoft3.0 _Nodejs

I. Project description

Rainbow soft official website portal, there are different platforms and different versions of SDK, there is a need to download according to the business. This project supports Windows and Linux, but the Application of Electron packing is disabled on MAC.

  1. The project was created by electron- Vue scaffolding.
  2. In the main thread to achieve interaction with the Rainbow software SDK, if you also need to interact with the Render layer, you also need to use app.on to receive the business transmitted by the Render layer.
  3. When vUE is packaged, you need to configure the include path in package.json.
  4. Use ffi library to call C++ library, ref data 1

Ref data 2 ref data 3 other please their own baidu, here will not elaborate. 5. There are two kinds of image processing, one is OpencV4Nodejs (node version is larger than 10.x, I use the last version of 10, the latest version uses Python3.3, there are too many compilation problems), the other is jimp, both have methods to implement, I recommend OpencV, fast processing, However, the configuration environment is slightly more complex. For more information, see the official NPM. For more information, see python’s opencV call method. 6. This time mainly for Windows version of the DLL, Linux call the same method, the path can be changed to their own path, file name. So

Ffi installation and environment installation

Exe [vs_buildtools. exe] C:\Users\Administrator\. Windows-build-tools: The script installation fails due to a large installation package and network problems. 2, specify the location where msbuild. exe will be compiled, because 2019 and 2017 have this exe, better use 2017, I failed to install 2019. npm configset msbuild_path "C: Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\MSBuild\15.0\Bin\ msbuild.exe"3.8.5 (not recommended) NPM configset python C:/Python27
npm config setPython C:/python3.8.5 install gyp NPM install node-gyp -g or NPM install --global node-gyp@latest Ffi -g NPM install ref -g successfully compiledCopy the code

Opencv4nodejs installation

Manually installed OpencV environment, Set the environment variable OPENCV_BIN_DIR=E: commonsoft opencv build x64 vc14 bin OPENCV_INCLUDE_DIR=E: Commonsoft opencV build include OPENCV_LIB_DIR=E: commonsoft opencv build x64 vc14 libset OPENCV4NODEJS_DISABLE_AUTOBUILD=1
npm i -g opencv4nodejs

Copy the code

4. Code structure

├ ─. Electron - vue ├ ─. Idea ├ ─ build │ └ ─ the ICONS ├ ─ dist │ ├ ─ electron │ └ ─ web ├ ─ images ├ ─ SRC │ ├ ─ the main │ │ ├ ─ inc │ │ ├ ─ lib │ │ │ ├ ─ X64 │ │ │ └ ─ X86 │ │ └ ─ modual │ │ ├ ─ img │ │ │ ├ ─ faces │ │ │ └ ─test│ │ └ ─log│ ├─ exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercises - exercisestest├ ─ e2e │ └ ─ specs └ ─ unit modual folder for face recognition working directory place lib folder for the DLL file path, x86 x64 img image path to the corresponding version (faces for drawFace operation pathtestIs the operation path of cvImages)Copy the code

Five, code call example and description


const arc_face = require('./face_engine');
const path = require('path');
const config = require('./config');
const m = require('./logger');
const client = require('./clients');
const imageHelper = require('./face_cv_image');
const fsUtil = require('./fileUtils'); // Set the DLL pathlet dllPath = "";
if(process.env.NODE_ENV ! = ='development') {
    dllPath = require('path').join(__dirname, '.. /.. /main/lib/X64').replace(/\\/g, '\ \ \ \')}else{
    dllPath = require('path').join(__dirname, '.. /lib/X64').replace(/\\/g, '\ \ \ \'} // add the DLL directory to the environment variable process.env['PATH'] = `${process.env.PATH};${dllPath}`; // Initialize interface const arc = new arc_face(config.lib_win64); Object.prototype.toString =function() {return JSON.stringify(this);
};

Date.prototype.toLocaleString = function() {
    return this.getFullYear() + "-" + (this.getMonth() + 1) + "-" + this.getDate() + "" + this.getHours() + ":" + this.getMinutes() + ":" + this.getSeconds();
};

this.test_arc = async () => {
    try{
        let dataInfo = arc.getActiveFileInfo();
        if(null ! = dataInfo){let start = new Date(parseInt(dataInfo.startTime) * 1000);
            let end = new Date(parseInt(dataInfo.endTime) * 1000);

            m.logger.info("expire date is from %s to %s, please check the date for expired.thank you.",
                start.toLocaleString(),
                end.toLocaleString()
            );

            if (new Date().getTime() > end){
                m.logger.warn('your arc soft is expired,please change the file to continue use it,thank you.');
                return;
            }
        }
        client.get('active', (err, res) => {// Activateif(! res || parseInt(res) ! = = 1) {let ib = arc.activeFaceEngine(config.appId,config.appKey);
                client.set('active',ib? 1-0); }else{
                m.logger.info("engine has already initialed, do not repeat active"); }});let version = arc.getVersion();
        m.logger.info("current verson is %s",version.Version); // initialFaceEngine arc.initialfaceengine (16,50); // Set the reliability arc.setliveParam (0.5,0.7);let img_path1 = path.join(__dirname, './img/1.jpg');
        let img_path2 = path.join(__dirname, './img/2.jpg');
        let img_path3 = path.join(__dirname, './img/3.jpg'); // jimp handles images //let asvl1 = await imageHelper.parseImage(img_path1,false);
        // let asvl2 = await imageHelper.parseImage(img_path2,false);
        // let asvl3 = await imageHelper.parseImage(img_path3,false); // OpencV handles imageslet asvl1 = await imageHelper.cvImages(img_path1,false,path.join(__dirname, './img/test'));
        let asvl2 = await imageHelper.cvImages(img_path2,false,path.join(__dirname, './img/test'));
        let asvl3 = await imageHelper.cvImages(img_path3,false,path.join(__dirname, './img/test')); // Check the facelet data1 = arc.detectFacesEx(asvl1.imageData);
        letdata2 = arc.detectFacesEx(asvl2.imageData); // Extract eigenvalueslet feature1 = arc.extractFeature(asvl1.imageData, data1.multi.faceRect[0], data1.multi.faceOrient[0]);
        let feature2 = arc.extractFeature(asvl2.imageData, data2.multi.faceRect[0], data2.multi.faceOrient[0]);

        if(! feature1 || ! feature2){ m.logger.error("feature1 or feature2 is null. please check.");
            return;
        }

        // console.log("feature1",feature1)
        // console.log("feature2", feature2) / /let sim = arc.compareFeature(feature1.nav,feature2.nav);
        if (sim < 0){
            m.logger.info("similar is %d,is not the same person.",sim);
            return;
        }
        if(sim > 0.8) {m.l ogger. Info ("similar is %d,is the same person.",sim);
        }else{
            m.logger.info("similar is %d,is not the same person.",sim); } // Base64 to feature test, the actual effect will be 0.02 worselet f1 = arc.base64ToFeature(feature1.nab.featureBuffer);
        let f2 = arc.base64ToFeature(feature2.nab.featureBuffer);
        let ff = arc.compareFeature(f1,f2);

        if(ff > 0.8) {m.l ogger. Info ("similar is %d,is the same person.",ff);
        }else{
            m.logger.info("similar is %d,is not the same person.",ff); } // Release the face pointer arc.release(f1.feature); arc.release(f2.feature); // Monomer detectionlet ib = arc.processEx(asvl3.imageData,false);
        if(! ib){ m.logger.error("single process checked failed.");
            return;
        }
        arc.getSexInfo();

        arc.getAgeInfo();

        arc.getAngleInfo();

        arc.getLivenessScore(false); // Test the framelet isIR = false;
        let asvl5 = await imageHelper.cvImages(img_path1,isIR);
        let infos = arc.detectFacesEx(asvl5.imageData);

        let filePath = path.join(__dirname, './img/faces');
        await fsUtil.dirExists(filePath);
        imageHelper.drawFace(img_path1,infos.multi,true,filePath); // Detect and process serieslet fileCv = path.join(__dirname, './img/test');
        await fsUtil.dirExists(fileCv);
        let asvl6 = await imageHelper.cvImages(img_path1,isIR,fileCv);
        let faces = arc.detectFaces(asvl6,false);

        let info = arc.processNone(asvl6,false);
        arc.getLivenessScore(false);

        // console.log('info',info); Arc.uninitialengine (); arc.uninitialEngine (); client.quit(); }catch (e) { m.logger.info("some error happened.%s",e.toString());
        arc.unInitialEngine();
        client.quit()
    }
};

this.test_arc();

Copy the code

Vi. Installation and use

# install dependencies
npm install

# serve with hot reload at localhost:9080
npm run dev

# build electron application for production
npm run build

# run unit & end-to-end tests
npm test

# Test the face part
node face_test.js
Copy the code

7. Common Problems

Dynamic Linking Error: Win32 Linking Error 126 There are three reasons for this Error. (1) The DLL path is usually incorrect and the DLL file cannot be found. (2) If a 32-bit DLL is referenced in the X64 node/electron directory, this error will be reported, and vice versa. Make sure the DLL requires the same CPU architecture as your runtime environment. DLL also references other DLL files, but cannot find the referenced DLL file, may be the VC dependent library or there is a dependency relationship between multiple DLLS. Set the DLL's working environment variable process.env['PATH'] = `${process.env.PATH};${'E:/arface_node/arface_nodejs/src/main/lib/X64'}'// Add the DLL directory to the environment variable Dynamic Linking Error: Win32 Error 127: DLL (3) If app of undefined is prompted, add the following module enableRemoteModule when creating the form:true// In node, pointer -> buffer, e.gletA = new (typedef.mint32.size) a = new (typedef.mint32.size) // ref = = const ref = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = require('ref'); typedef.MLong = ref.types.long; typedef.UMLong = ref.types.uint32; typedef.MFloat = ref.types.float; Const StructType = require('ref-struct'); typedef.__tag_rect = StructType({ left: typedef.MInt32, top: typedef.MInt32, right: typedef.MInt32, bottom: typedef.MInt32 }); // provide C++ ArrayType const ArrayType = require('ref-array'); ppu8Plane: RefType (refType(typedef.MUInt8), 4), ref.refType(XXX), ArrayType(ref.reftype (typedef.muint8), 4), ref.refType(XXX)) Library(libFile, {// map interface name C++ interface, corresponding data type ASFGetActiveFileInfo: [typedef.mresult, [typedef.lpasf_activeFileInfo // [out] active file information]]let libname = ffi.Library('./libname', {
  'setCallback': ['void'['pointer']]});let callback = ffi.Callback('void'['int'.'string'].function(id, name) {
    console.log("id: ", id);
    console.log("name: ", name); }); libname.setCallback(callback); // Reference the callback pointer on exit to avoid GC(garbage collection) process.on('exit'.function() { callback }); Libc.malloc (size); malloc(size); Libc.memset (*p,offset,size); Libc.memcpy (*to, *from,size); Const arr = new buffer (typedef.mbyt.size);for (leti = 0; i < _feature.featureSize; i++) { libc.memcpy(arr.address(), feature.feature.address() + i * TypeDef.MByte.size, TypeDef.MByte.size); this.pointers.push(feature.feature); _normal.feature.push(ref.get(arr, 0, TypeDef.MByte)); } arr. Deref () = libc.free(*p)Copy the code

If you feel my code helps you, please donate to show your support. Thank you

To learn more about face recognition products, please visitRainbow soft visual open platformoh