java版 利用人脸识别猜年龄 基于ArcFace2.0的 demo

栏目: 编程工具 · 发布时间: 7年前

内容简介:首先感谢虹软,是你们提供这么好的SDK支撑了我们的想象力!这是一个用javav编写的可视化应用,用户通过自己的脸和计算机进行交互,计算机则通过萌萌女孩的语音和用户对话。核心程序就是利用ArcFace2.0识别性别、年龄,但是为了获得正面脸,会根据ArcFace2.0的人脸3D角度、用语音提醒用户,这是一个的互动环节。最后,程序会幽默的、萌萌的告诉用户他的性别、年龄。

首先感谢虹软,是你们提供这么好的SDK支撑了我们的想象力!

这是一个用javav编写的可视化应用,用户通过自己的脸和计算机进行交互,计算机则通过萌萌女孩的语音和用户对话。

核心程序就是利用ArcFace2.0识别性别、年龄,但是为了获得正面脸,会根据ArcFace2.0的人脸3D角度、用语音提醒用户,这是一个的互动环节。最后,程序会幽默的、萌萌的告诉用户他的性别、年龄。

获取SDK 请戳这里

完整的项目源码、可执行程序,放在百度网盘:链接: https://pan.baidu.com/s/1eHF6...

提取码: ffag

其中主要的3个 java 文件,代码如下:

=====================================
HowOldAreU.java
=====================================
package app;

import java.awt.EventQueue;
import javax.swing.JFrame;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.channels.FileChannel;
import java.nio.channels.FileLock;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;
import java.awt.BorderLayout;
import com.alibaba.fastjson.JSONArray;
import com.arcsoft.face.FaceEngine;
import com.github.sarxos.webcam.Webcam;
import com.github.sarxos.webcam.WebcamPanel;
import tools.MyFunc;
import javax.swing.JOptionPane;

/*这是一个用javav编写的可视化应用,用户通过自己的脸和计算机进行交互,计算机则通过萌萌女孩的语音和用户对话。
核心程序就是利用ArcFace2.0识别性别、年龄,但是为了获得正面脸,会根据ArcFace2.0的人脸3D角度、用语音提醒用户,这是一个的互动环节。
最后,程序会幽默的、萌萌的告诉用户他的性别、年龄。

作者:huanghua8080@126.com
*/

public class HowOldAreU {

        //应用根目录
        public static String fs = File.separator;
        public final static String localPath = System.getProperty("user.dir")+fs;
        public final static String soundDir = localPath+"sound"+fs;
        //
        public static Webcam camera = null;
        private JFrame frame;
        //
        public static FaceEngine faceEngine = null;
        @SuppressWarnings("rawtypes")
        public static List FaceFeature = new ArrayList<Map<String, String>>();
        public static JSONArray aryFFTime = new JSONArray();
        public static JSONArray aryFFCnt = new JSONArray();
        public static String lastTime = "2019-01-09 13:30:00";
        public static int faceCnt = 0;

        /**
         * Launch the application.
         */
        public static void main(String[] args) {
                
                //判断程序是否已经运行
                String s = localPath+"lockApp.txt";
                //
                RandomAccessFile raf = null;
                try {
                        raf = new RandomAccessFile(new File(s), "rws");
                } catch (FileNotFoundException e1) {
                        JOptionPane.showMessageDialog(null, "独占文件时发生异常。"+e1, "错误",JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                }
                FileChannel fcin = raf.getChannel();
                FileLock flin = null;
                try {
                        flin = fcin.tryLock();
                } catch (Exception e) {
                        JOptionPane.showMessageDialog(null, "锁文件时发生异常:"+e, "错误",JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                }
            if (flin == null) {
                        JOptionPane.showMessageDialog(null, "程序已在运行,不可重复。", "错误",JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                }
            
                s = "D:\\Dev\\ec_workspace\\cs1914age";
                if(!s.equals(System.getProperty("user.dir"))) {
                        if(args.length == 0) {
                                JOptionPane.showMessageDialog(null, "没有入参,程序将终止。", "错误",JOptionPane.ERROR_MESSAGE);
                                System.exit(0);
                                return;
                        }
                        if(!"age".equals(MyFunc.strTrim(args[0]).toLowerCase())) {
                                JOptionPane.showMessageDialog(null, "入参错误,程序将终止。", "错误",JOptionPane.ERROR_MESSAGE);
                                System.exit(0);
                                return;
                        }
                }
                
            //获取摄像头
                camera = Webcam.getDefault();
                if (camera == null) {
                        JOptionPane.showMessageDialog(null, "摄像头获取失败。", "错误",JOptionPane.ERROR_MESSAGE);
                        return;
                }
                
                //初始化人脸引擎
                s = HowOldAreUAs.initEngine();
                if(!"".equals(s)) {
                        JOptionPane.showMessageDialog(null, s, "错误",JOptionPane.ERROR_MESSAGE);
                        System.exit(0);
                        return;
                }
                
                //启动窗体
                EventQueue.invokeLater(new Runnable() {
                        public void run() {
                                try {
                                        HowOldAreU window = new HowOldAreU();
                                        window.frame.setVisible(true);                                        
                                } catch (Exception e) {
                                        e.printStackTrace();
                                }
                        }
                });
        }

        /**
         * Create the application.
         */
        public HowOldAreU() {
                initialize();
        }

        /**
         * Initialize the contents of the frame.
         */
        private void initialize() {                
                //
                frame = new JFrame();
                frame.setTitle("猜年龄");
                frame.setBounds(100, 100, 610, 370);
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                frame.getContentPane().setLayout(new BorderLayout(0, 0));
                frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
                frame.setUndecorated(true);//去边框

                //摄像头加载到面板
                WebcamPanel panel = new WebcamPanel(camera);
                frame.getContentPane().add(panel, BorderLayout.CENTER);
                
                //启动声音
                HowOldAreUAs.playSound(100);                

                //线程(识别频率:毫秒)
                Timer timerMain = new Timer();
                timerMain.scheduleAtFixedRate(new TimerTask() {
                        public void run() {
                                if (camera != null) {
                                        HowOldAreUAs.photo();
                                }
                        }
                }, 0, 500);

        }

}
====================================
HowOldAreUAs
====================================
package app;

import java.awt.image.BufferedImage;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.arcsoft.face.AgeInfo;
import com.arcsoft.face.Face3DAngle;
import com.arcsoft.face.FaceFeature;
import com.arcsoft.face.FaceInfo;
import com.arcsoft.face.FaceSimilar;
import com.arcsoft.face.FunctionConfiguration;
import com.arcsoft.face.GenderInfo;
import com.arcsoft.face.Rect;
import com.arcsoft.face.enums.ImageFormat;
import com.sun.jna.Platform;

import app.FaceAbout.ImageInfo;
import tools.MyFunc;
import tools.SoundPlay;

public class HowOldAreUAs {
        public static final int recoFreq = 60;//同一人不重复识别时间(秒)
        public static final int scoreThreshold = 70;//人脸相似度阀值
        //3D角度阀值
        public static final BigDecimal yes3d = new BigDecimal("5");
        
        //拍照
        @SuppressWarnings("unchecked")
        public static void photo() {
                int rtn=-1,sex=-1,age=-1;
                
                //当前时间
                String nowTime = MyFunc.getSvrTime("yyyy-MM-dd HH:mm:ss");
                
                //不重复识别时间(去除过期的)
                for(int n=HowOldAreU.aryFFTime.size()-1;n>=0;n--) {
                        if(MyFunc.datetimeSub(HowOldAreU.aryFFTime.get(n).toString(), nowTime) >= recoFreq) {
                                HowOldAreU.aryFFTime.remove(n);
                                HowOldAreU.aryFFCnt.remove(n);
                                HowOldAreU.FaceFeature.remove(n);
                        }
                }
                
                //拍照
                BufferedImage cameraImg = HowOldAreU.camera.getImage();
                
                //找脸
        List<FaceInfo> faceInfoList = new ArrayList<FaceInfo>();
                ImageInfo imageInfo = new FaceAbout().bufferedImage2ImageInfo(cameraImg);
                HowOldAreU.faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);
                int cnt = faceInfoList.size();
                if (cnt == 0) {
                        //5分钟后,如果没有人来,则呼唤
                        if(MyFunc.datetimeSub(HowOldAreU.lastTime, nowTime) > 300) {
                                HowOldAreU.lastTime = nowTime;
                                playSound(200);
                        }
                        return;
                }
                HowOldAreU.lastTime = nowTime;

                //找最大脸(第一张脸即为最大脸)
                FaceInfo oneFace = faceInfoList.get(0);

                //提取脸纹
        FaceFeature CmFeature = new FaceFeature();
                rtn = HowOldAreU.faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), 
                                ImageFormat.CP_PAF_BGR24, oneFace, CmFeature);
                if (rtn !=  0) {
                        playSound(250);
                        return;
                }
                
                //是否刚刚识别过
                int rfe = 0;
                int dSimilScore = 0;
        FaceSimilar faceSimilar = new FaceSimilar();
                for(int n=0;n<HowOldAreU.aryFFTime.size();n++) {
                rtn = HowOldAreU.faceEngine.compareFaceFeature(CmFeature, (FaceFeature) HowOldAreU.FaceFeature.get(n), faceSimilar);
                        if (rtn != 0) {
                                return;
                        }
                        //得分
                        dSimilScore = new BigDecimal(faceSimilar.getScore()).multiply(new BigDecimal("100")).setScale(0, BigDecimal.ROUND_HALF_UP).intValue();
                        //大于阀值
                        if(dSimilScore >= scoreThreshold){
                                if(MyFunc.datetimeSub(HowOldAreU.aryFFTime.get(n).toString(), nowTime) < recoFreq) {
                                        rfe = 1;
                                        int hdt = Integer.parseInt( HowOldAreU.aryFFCnt.get(n).toString() );
                                        if(hdt >= 1 && hdt <= 3) {
                                                playSound(180+hdt);
                                                HowOldAreU.aryFFCnt.set(n, hdt+1 );
                                                //停顿一下
                                                try {
                                                        Thread.sleep(3000);
                                                } catch(InterruptedException ex) {
                                                        Thread.currentThread().interrupt();
                                                }
                                        }
                                        break;
                                }
                        }
                }
                //最近识别过
                if(rfe == 1) {return;}
                
                //识别过10个人后,做一次自我介绍
                if(HowOldAreU.faceCnt == 11) {
                        HowOldAreU.faceCnt = 0;
                }
                if(HowOldAreU.faceCnt == 0) {
                        playSound(150);
                        HowOldAreU.faceCnt ++;
                }
                //停顿一下
                try {
                        Thread.sleep(1000);
                } catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                }
                
                //原型
        faceInfoList.add(oneFace);
                rtn = HowOldAreU.faceEngine.process(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), 
                        ImageFormat.CP_PAF_BGR24, faceInfoList, 
                        FunctionConfiguration.builder().supportAge(true).supportFace3dAngle(true).supportGender(true).build());
                if (rtn !=  0) {
                        playSound(250);
                        return;
                }

        //3D信息提取
        List<Face3DAngle> face3DAngleList = new ArrayList<Face3DAngle>();
        rtn = HowOldAreU.faceEngine.getFace3DAngle(face3DAngleList);
                if (rtn !=  0) {
                        playSound(250);
                        return;
                }
                if(face3DAngleList.size() == 0) {
                        playSound(250);
                        return;
                }
                
                //0: 正常,其他数值:检测结果不可信
                int status3d = face3DAngleList.get(0).getStatus();
                if(status3d != 0) {return;}
                BigDecimal pitch = new BigDecimal("0");
                BigDecimal roll = new BigDecimal("0");
                BigDecimal yaw = new BigDecimal("0");
                BigDecimal yes3db = new BigDecimal("0").subtract(yes3d);
                
                //俯仰角
                pitch = new BigDecimal(face3DAngleList.get(0).getPitch()).setScale(7, BigDecimal.ROUND_HALF_UP);
                if(pitch.compareTo(yes3d) == 1) {
                        playSound(301);
                        return;
                }
                if(pitch.compareTo(yes3db) == -1) {
                        playSound(302);
                        return;
                }
                //横滚角
                roll = new BigDecimal(face3DAngleList.get(0).getRoll()).setScale(7, BigDecimal.ROUND_HALF_UP);
                if(roll.compareTo(yes3d) == 1) {
                        playSound(311);
                        return;
                }
                if(roll.compareTo(yes3db) == -1) {
                        playSound(312);
                        return;
                }
                
                //偏航角
                yaw = new BigDecimal(face3DAngleList.get(0).getYaw()).setScale(7, BigDecimal.ROUND_HALF_UP);
                if(yaw.compareTo(yes3d) == 1) {
                        playSound(321);
                        return;
                }
                if(yaw.compareTo(yes3db) == -1) {
                        playSound(322);
                        return;
                }

        //年龄提取
        List<AgeInfo> ageInfoList = new ArrayList<AgeInfo>();
        rtn = HowOldAreU.faceEngine.getAge(ageInfoList);
                if (rtn !=  0) {
                        playSoundSexAge(-1,-1);
                        return;
                }
                age = ageInfoList.get(0).getAge();
                if(age > 120) {age = 120;}
                
        //性别提取
        List<GenderInfo> genderInfoList = new ArrayList<GenderInfo>();
        rtn = HowOldAreU.faceEngine.getGender(genderInfoList);
                if (rtn !=  0) {
                        playSoundSexAge(-1,age);
                        return;
                }
                sex = genderInfoList.get(0).getGender();

                //
                if(sex == -1 && age == -1) {
                        playSound(360);
                        return;
                }
                
                //播报
                playSoundSexAge(sex,age);
                
                //记录人脸,防止重复识别同一个人
                HowOldAreU.FaceFeature.add(CmFeature);
                HowOldAreU.aryFFTime.add(nowTime);
                HowOldAreU.aryFFCnt.add("1");

                //记录已识别数量
                HowOldAreU.faceCnt ++;
                //System.out.println(HowOldAreU.faceCnt+" "+now_time);
        }

        public static void playSoundSexAge(int sex,int age) {                
                //不同年龄段,不同称谓
                String agename = "frend";
                if(sex >= 0) {
                        if(age >= 0 && age <= 2) {
                                agename = "00-"+sex;
                        }else if(age >= 3 && age <= 18) {
                                agename = "03-"+sex;
                        }else if(age >= 19 && age <= 45) {
                                agename = "19-"+sex;
                        }else if(age >= 46 && age <= 75) {
                                agename = "46-"+sex;
                        }else if(age >= 76 && age <= 120) {
                                agename = "76-"+sex;
                        }
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+"agename"+HowOldAreU.fs+"agename-"+agename+".mp3", null);
                
                //推测用语
                JSONArray ary = new JSONArray();
                ary.add("401");//你,大概
                ary.add("402");//我猜你
                ary.add("403");//我估计你
                ary.add("404");//我看你
                ary.add("405");//你看起来
                int cnt = ary.size();
                //随机选择一个
                int idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);

                //年龄
                SoundPlay.playSoundFile(HowOldAreU.soundDir+"age"+HowOldAreU.fs+"age"+age+".mp3", null);
                
                //停顿一下
                try {
                        Thread.sleep(1000);
                } catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                }
                                
                //确认
                ary = new JSONArray();
                ary.add("481");//对不对啊?
                ary.add("482");//是不是呢?
                ary.add("483");//准吗?
                ary.add("484");//差不多吗?
                ary.add("485");//靠谱吧?
                cnt = ary.size();
                idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
                
                //停顿一下
                try {
                        Thread.sleep(2000);
                } catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                }
                                
                //笑一个
                ary = new JSONArray();
                ary.add("501");//哈哈!
                ary.add("502");//嘻嘻!
                cnt = ary.size();
                idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
                
                //如果错了
                ary = new JSONArray();
                ary.add("521");//如果我说错了,
                ary.add("522");//要是我没有说对,
                cnt = ary.size();
                idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                    idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
                
                //别生气
                ary = new JSONArray();
                ary.add("541");//你可别生气哦!
                ary.add("542");//你别往心里去啊!
                ary.add("543");//你千万别介意哈!
                cnt = ary.size();
                idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                    idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
                
                //停顿一下
                try {
                        Thread.sleep(2000);
                } catch(InterruptedException ex) {
                        Thread.currentThread().interrupt();
                }
                
                //下一个
                ary = new JSONArray();
                ary.add("561");//来,下一个!
                ary.add("562");//请下一位朋友!
                ary.add("563");//下一位,谁来?
                cnt = ary.size();
                idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                    idx = random.nextInt(cnt)%(cnt+1);
                }
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
        }
        
        public static void playSound(int sound_kind) {
                //  http://ai.baidu.com/tech/speech/tts
                JSONArray ary = new JSONArray();
                //文件集
                switch(sound_kind) {
                case 100:                        
                        ary.add("101");//秋语已经启动,就要工作啦!
                        break;

                case 150:
                        //大家好,我是机器人。主人给我取名:秋语,他还帮我训练了一双火眼金睛,
                        //看一眼就能识别出你们人类的性别和年龄。有人想过来试一试吗?
                        ary.add("150");
                        break;
                        
                case 181:                        
                        ary.add("181");//你来过的,一分钟之后再来,好吗?
                        break;
                case 182:                        
                        ary.add("182");//你来过的,一分钟之后再来,好吗?
                        break;
                case 183:                        
                        ary.add("183");//你怎么还来呀?跟你说了等一分钟的!你真是个急性子,不理你了。
                        break;
                        
                case 200: //没有发现人脸时                        
                        ary.add("201");//怎么没有人来跟我玩儿?                        
                        ary.add("202");//有人吗?快来和我玩啦!                        
                        ary.add("203");//我知道你几岁了,过来试试吧!                        
                        ary.add("204");//你们人呢?都到哪儿去了?        
                        ary.add("205");//我等了老半天,怎么连个人影也没看到!
                        break;
                        
                case 250: //看不请人脸或无法提取脸纹时                        
                        ary.add("251");//嗨!靠近一点儿,我想看看你呢!
                        ary.add("252");//喂!过来一点嘛,我都看不清你!                        
                        ary.add("253");//hello,离我近一点儿,会有惊喜的!
                        break;
                        
                        //3D角度过大
                case 301://俯仰角过大:请低一下头!
                case 302://俯仰角过大:把头抬一下!
                case 311://横滚角过大:头向左转一下!
                case 312://横滚角过大:向右转一下头!
                case 321://偏航角过大:脖子向左歪一下!
                case 322://偏航角过大:向右歪一下脖子!
                        ary.add(sound_kind);
                        break;
                        
                case 360: //性别、年龄均未知                        
                        ary.add("361");//你太神秘了,我实在猜不出你几岁!                        
                        ary.add("362");//你到底几岁呢?我绞尽脑汁也想不出来!                        
                        ary.add("363");//我无法识别你的年龄,我要请主人继续进化我。
                        break;
                }
                int cnt = ary.size();
                if(cnt == 0) {return;}
                //随机选择一个
                int idx = 0;
                if(cnt > 1) {
                        Random random = new Random();
                idx = random.nextInt(cnt)%(cnt+1);
                }
                //播放
                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3", null);
        }
        
        public static String initEngine() {
                JSONObject parm = MyFunc.GetAllProperties("config/parm.properties");
                String s = MyFunc.strTrim(parm.getString("err"));
                if(!"".equals(s)) {return "参数文件读取失败。"+s;        }                
                //APPID
                String APPID = MyFunc.strTrim(parm.getString("APP_ID"));
                if("".equals(APPID)){return "终端APPID缺失,程序将终止。";}
                //SDKKEY
                String WIN_SDKKEY = MyFunc.strTrim(parm.getString("WIN_SDKKEY"));
                String LIN_SDKKEY = MyFunc.strTrim(parm.getString("LIN_SDKKEY"));
                String SDKKEY = WIN_SDKKEY;
                if(!Platform.isWindows()) {SDKKEY = LIN_SDKKEY;}                
                if("".equals(SDKKEY)){return "终端SDKKEY缺失,程序将终止。";}
                
                //加载动态库
                s = FaceAbout.loadDllSo();
                if(!"".equals(s)) {
                        return "动态库加载失败,程序将终止。"+s;
                }
                //人脸引擎初始化
                try {
                        HowOldAreU.faceEngine = FaceAbout.initFaceEngine(APPID, SDKKEY);
                } catch (IOException e) {
                        return "人脸引擎初始化失败,程序将终止。"+e;
                }
                return "";
        }
        
}
====================================
FaceAbout.java
====================================
package app;

import java.awt.color.ColorSpace;
import java.awt.image.BufferedImage;
import java.awt.image.ColorConvertOp;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;

import com.arcsoft.face.EngineConfiguration;
import com.arcsoft.face.FaceEngine;
import com.arcsoft.face.FunctionConfiguration;
import com.sun.jna.Platform;

import tools.FileOpe;

public class FaceAbout {
        
        //加载本地库
        public static String loadDllSo() {
            String fileType = "",s="",s2="";
                //路径
        String dllPath = HowOldAreU.localPath+"ArcSoft";
                //添加到系统路径
                addDirToPath(dllPath);

                //处理依赖库
                if(Platform.isWindows()) {
                        String[] files = new String[2];
                        files[0] = "msvcp120.dll";
                        files[1] = "msvcr120.dll";
                        for(int i=0;i<files.length;i++) {
                                s = dllPath+HowOldAreU.fs+files;
                                s2 = "C:\\Windows\\System32\\"+files;
                                if(!new File(s2).exists()) {
                                        try {
                                                new FileOpe().copyFile(new File(s), new File(s2));
                                        } catch (IOException e) {
                                                return "依赖库复制失败("+s+" -> "+s2+")。"+e;
                                        }
                                }
                        }
                }
                
                //文件类型
        if(Platform.isWindows()) {
                fileType = ".dll";
        }else {
                fileType = ".so";
        }
                ArrayList<String> ary = new ArrayList<String>();
                ary.add("libarcsoft_face");
                ary.add("libarcsoft_face_engine");
                ary.add("libarcsoft_face_engine_jni");
                //加载
                for(int i=0;i<ary.size();i++) {
                        s = dllPath+HowOldAreU.fs+ary.get(i)+fileType;
                        try {
                                System.load(s);
                        }catch (Exception e) {
                                return "动态库("+s+")加载失败。"+e;
                        }
                }
                return "";
        }
        
        //添加路径
        private static void addDirToPath(String s) {
            try {  
                //获取系统path变量对象  
                    java.lang.reflect.Field field = ClassLoader.class.getDeclaredField("sys_paths");
                //设置此变量对象可访问  
                field.setAccessible(true);
                //获取此变量对象的值  
                String[] path = (String[])field.get(null);
                //是否已经存在
                for(int i=0;i<path.length;i++) {
                        if(s.equals(path)) {
                                field.setAccessible(false);
                                return;
                        }
                }
                //创建字符串数组,在原来的数组长度上增加一个,用于存放增加的目录  
                String[] tem = new String[path.length+1];  
                //将原来的path变量复制到tem中  
                System.arraycopy(path,0,tem,0,path.length);  
                //将增加的目录存入新的变量数组中  
                tem[path.length] = s;  
                //将增加目录后的数组赋给path变量对象  
                field.set(null,tem);
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
        }
        
        //初始化
        public static FaceEngine initFaceEngine(String APPID, String SDKKEY) throws IOException {
                //初始化人脸引擎
                FaceEngine faceEngine = new FaceEngine();
                faceEngine.active(APPID, SDKKEY);
        //引擎配置
        EngineConfiguration engineConfiguration = EngineConfiguration.builder().functionConfiguration(
                FunctionConfiguration.builder()
                        .supportAge(true)
                        .supportFace3dAngle(true)
                        .supportFaceDetect(true)
                        .supportFaceRecognition(true)
                        .supportGender(true)
                        .build()).build();
        //初始化引擎
        faceEngine.init(engineConfiguration);
        return faceEngine;
        }

        //错误码
        public static String errCodeList(int codeNo) {
                String infoStr = "";
                switch(codeNo) {
                case 0: infoStr = "成功";break;
                case 1: infoStr = "错误原因不明";break;
                case 2: infoStr = "无效的参数";break;
                case 3: infoStr = "引擎不支持";break;
                case 4: infoStr = "内存不足";break;
                case 5: infoStr = "状态错误";break;
                case 6: infoStr = "用户取消相关操作";break;
                case 7: infoStr = "操作时间过期";break;
                case 8: infoStr = "用户暂停操作";break;
                case 9: infoStr = "缓冲上溢";break;
                case 10: infoStr = "缓冲下溢";break;
                case 11: infoStr = "存贮空间不足";break;
                case 12: infoStr = "组件不存在";break;
                case 13: infoStr = "全局数据不存在";break;
                case 28673: infoStr = "无效的AppId";break;
                case 28674: infoStr = "无效的SDKkey";break;
                case 28675: infoStr = "AppId和SDKKey不匹配";break;
                case 28676: infoStr = "SDKKey和使用的SDK不匹配";break;
                case 28677: infoStr = "系统版本不被当前SDK所支持";break;
                case 28678: infoStr = "SDK有效期过期,需要重新下载更新";break;
                case 73729: infoStr = "无效的输入内存";break;
                case 73730: infoStr = "无效的输入图像参数";break;
                case 73731: infoStr = "无效的脸部信息";break;
                case 73732: infoStr = "当前设备无GPU可用";break;
                case 73733: infoStr = "待比较的两个人脸特征的版本不一致";break;
                case 81921: infoStr = "人脸特征检测错误未知";break;
                case 81922: infoStr = "人脸特征检测内存错误";break;
                case 81923: infoStr = "人脸特征检测格式错误";break;
                case 81924: infoStr = "人脸特征检测参数错误";break;
                case 81925: infoStr = "人脸特征检测结果置信度低";break;
                case 86017: infoStr = "Engine不支持的检测属性";break;
                case 86018: infoStr = "需要检测的属性未初始化";break;
                case 86019: infoStr = "待获取的属性未在process中处理过";break;
                case 86020: infoStr = "ROCESS不支持的检测属性,例如FR,有自己独立的处理函数";break;
                case 86021: infoStr = "无效的输入图像";break;
                case 86022: infoStr = "无效的脸部信息";break;
                case 90113: infoStr = "SDK激活失败,请打开读写权限";break;
                case 90114: infoStr = "SDK已激活";break;
                case 90115: infoStr = "SDK未激活";break;
                case 90116: infoStr = "detectFaceScaleVal不支持";break;
                case 90117: infoStr = "SDK版本不匹配";break;
                case 90118: infoStr = "设备不匹配";break;
                case 90119: infoStr = "唯一标识不匹配";break;
                case 90120: infoStr = "参数为空";break;
                case 90121: infoStr = "活体检测功能已过期";break;
                case 90122: infoStr = "版本不支持";break;
                case 90123: infoStr = "签名错误";break;
                case 90124: infoStr = "数据库插入错误";break;
                case 90125: infoStr = "唯一标识符校验失败";break;
                case 90126: infoStr = "颜色空间不支持";break;
                case 90127: infoStr = "图片宽度或高度不支持";break;
                case 90128: infoStr = "android.permission.READ_PHONE_STATE权限被拒绝";break;
                case 90129: infoStr = "激活数据被破坏,请删除激活文件,重新进行激活";break;
                case 94209: infoStr = "无法解析主机地址";break;
                case 94210: infoStr = "无法连接服务器";break;
                case 94211: infoStr = "网络连接超时";break;
                case 94212: infoStr = "网络未知错误";break;
                case 98305: infoStr = "无法连接激活码服务器";break;
                case 98306: infoStr = "服务器系统错误";break;
                case 98307: infoStr = "请求参数错误";break;
                case 98308: infoStr = "激活码正确,且未被使用,但和传入的APPID及APPKEY不匹配";break;
                case 98309: infoStr = "传入的KEY值虽然正确,但此KEY已经被激活";break;
                case 98310: infoStr = "KEY格式不对,一般来说是KEY错误或者未传入KEY值";break;
                }
                return infoStr;
        }
        
        //
        public ImageInfo bufferedImage2ImageInfo(BufferedImage image) {
        ImageInfo imageInfo = new ImageInfo();
        int width = image.getWidth();
        int height = image.getHeight();
        // 使图片居中
        width = width & (~3);
        height = height & (~3);
        imageInfo.width = width;
        imageInfo.height = height;
        //根据原图片信息新建一个图片缓冲区
        BufferedImage resultImage = new BufferedImage(width, height, BufferedImage.TYPE_3BYTE_BGR);
        //得到原图的rgb像素矩阵
        int[] rgb = image.getRGB(0, 0, width, height, null, 0, width);
        //将像素矩阵 绘制到新的图片缓冲区中
        resultImage.setRGB(0, 0, width, height, rgb, 0, width);
        //进行数据格式化为可用数据
        BufferedImage dstImage = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR);
        if (resultImage.getType() != BufferedImage.TYPE_3BYTE_BGR) {
            ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
            ColorConvertOp colorConvertOp = new ColorConvertOp(cs, dstImage.createGraphics().getRenderingHints());
            colorConvertOp.filter(resultImage, dstImage);
        } else {
            dstImage = resultImage;
        }
        //获取rgb数据
        imageInfo.rgbData = ((DataBufferByte) (dstImage.getRaster().getDataBuffer())).getData();
        return imageInfo;
    }
        //
    public class ImageInfo {
        public byte[] rgbData;
        public int width;
        public int height;

        public byte[] getRgbData() {
            return rgbData;
        }

        public void setRgbData(byte[] rgbData) {
            this.rgbData = rgbData;
        }

        public int getWidth() {
            return width;
        }

        public void setWidth(int width) {
            this.width = width;
        }

        public int getHeight() {
            return height;
        }

        public void setHeight(int height) {
            this.height = height;
        }
    }

}

==============

程序在Windows7 64位 可以运行起来。里面调用摄像头的包,链接: https://github.com/sarxos/web...

程序之中的不当之处,还请社区的技术专家和各位同仁批评指正,谢谢。


以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网

查看所有标签

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

Algorithms

Algorithms

Robert Sedgewick、Kevin Wayne / Addison-Wesley Professional / 2011-3-19 / USD 89.99

Essential Information about Algorithms and Data Structures A Classic Reference The latest version of Sedgewick,s best-selling series, reflecting an indispensable body of knowledge developed over the ......一起来看看 《Algorithms》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

HEX CMYK 转换工具
HEX CMYK 转换工具

HEX CMYK 互转工具

HEX HSV 转换工具
HEX HSV 转换工具

HEX HSV 互换工具