美文网首页
java版 利用人脸识别猜年龄 基于ArcFace2.0的 de

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

作者: Rising_suns | 来源:发表于2019-02-11 16:09 被阅读0次

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

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

    获取SDK 请戳这里

    完整的项目源码、可执行程序,放在百度网盘:链接: https://pan.baidu.com/s/1eHF66l111S3Rs0VaS7v_LA
    提取码: 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/webcam-capture

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

    相关文章

      网友评论

          本文标题:java版 利用人脸识别猜年龄 基于ArcFace2.0的 de

          本文链接:https://www.haomeiwen.com/subject/fgbssqtx.html