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

2019-03-07  本文已影响0人  KEAIILIN

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

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

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

获取SDKhttps://ai.arcsoft.com.cn/index.htm?utm_source=csdn&utm_medium=referral

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

提取码: ffag

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

HowOldAreU.javapackageapp;importjava.awt.EventQueue;importjavax.swing.JFrame;importjava.io.File;importjava.io.FileNotFoundException;importjava.io.RandomAccessFile;importjava.nio.channels.FileChannel;importjava.nio.channels.FileLock;importjava.util.ArrayList;importjava.util.List;importjava.util.Map;importjava.util.Timer;importjava.util.TimerTask;importjava.awt.BorderLayout;importcom.alibaba.fastjson.JSONArray;importcom.arcsoft.face.FaceEngine;importcom.github.sarxos.webcam.Webcam;importcom.github.sarxos.webcam.WebcamPanel;importtools.MyFunc;importjavax.swing.JOptionPane;/*这是一个用javav编写的可视化应用,用户通过自己的脸和计算机进行交互,计算机则通过萌萌女孩的语音和用户对话。

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

最后,程序会幽默的、萌萌的告诉用户他的性别、年龄。

作者:huanghua8080@126.com

*/publicclassHowOldAreU{//应用根目录publicstaticString fs = File.separator;publicfinalstaticString localPath = System.getProperty("user.dir")+fs;publicfinalstaticString soundDir = localPath+"sound"+fs;//publicstaticWebcam camera =null;privateJFrame frame;//publicstaticFaceEngine faceEngine =null;@SuppressWarnings("rawtypes")publicstaticList FaceFeature =newArrayList>();publicstaticJSONArray aryFFTime =newJSONArray();publicstaticJSONArray aryFFCnt =newJSONArray();publicstaticString lastTime ="2019-01-09 13:30:00";publicstaticintfaceCnt =0;/**

        * Launch the application.

        */publicstaticvoidmain(String[] args){//判断程序是否已经运行String s = localPath+"lockApp.txt";//RandomAccessFile raf =null;try{                        raf =newRandomAccessFile(newFile(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(newRunnable() {publicvoidrun(){try{                                        HowOldAreU window =newHowOldAreU();                                        window.frame.setVisible(true);                                                                        }catch(Exception e) {                                        e.printStackTrace();                                }                        }                });        }/**

        * Create the application.

        */publicHowOldAreU(){                initialize();        }/**

        * Initialize the contents of the frame.

        */privatevoidinitialize(){//frame =newJFrame();                frame.setTitle("猜年龄");                frame.setBounds(100,100,610,370);                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);                frame.getContentPane().setLayout(newBorderLayout(0,0));                frame.setExtendedState(JFrame.MAXIMIZED_BOTH);                frame.setUndecorated(true);//去边框//摄像头加载到面板WebcamPanel panel =newWebcamPanel(camera);                frame.getContentPane().add(panel, BorderLayout.CENTER);//启动声音HowOldAreUAs.playSound(100);//线程(识别频率:毫秒)Timer timerMain =newTimer();                timerMain.scheduleAtFixedRate(newTimerTask() {publicvoidrun(){if(camera !=null) {                                        HowOldAreUAs.photo();                                }                        }                },0,500);        }

====================================HowOldAreUAs====================================packageapp;importjava.awt.image.BufferedImage;importjava.io.IOException;importjava.math.BigDecimal;importjava.util.ArrayList;importjava.util.List;importjava.util.Random;importcom.alibaba.fastjson.JSONArray;importcom.alibaba.fastjson.JSONObject;importcom.arcsoft.face.AgeInfo;importcom.arcsoft.face.Face3DAngle;importcom.arcsoft.face.FaceFeature;importcom.arcsoft.face.FaceInfo;importcom.arcsoft.face.FaceSimilar;importcom.arcsoft.face.FunctionConfiguration;importcom.arcsoft.face.GenderInfo;importcom.arcsoft.face.Rect;importcom.arcsoft.face.enums.ImageFormat;importcom.sun.jna.Platform;importapp.FaceAbout.ImageInfo;importtools.MyFunc;importtools.SoundPlay;publicclassHowOldAreUAs{publicstaticfinalintrecoFreq =60;//同一人不重复识别时间(秒)publicstaticfinalintscoreThreshold =70;//人脸相似度阀值//3D角度阀值publicstaticfinalBigDecimal yes3d =newBigDecimal("5");//拍照@SuppressWarnings("unchecked")publicstaticvoidphoto(){intrtn=-1,sex=-1,age=-1;//当前时间String nowTime = MyFunc.getSvrTime("yyyy-MM-dd HH:mm:ss");//不重复识别时间(去除过期的)for(intn=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 faceInfoList =newArrayList();                ImageInfo imageInfo =newFaceAbout().bufferedImage2ImageInfo(cameraImg);                HowOldAreU.faceEngine.detectFaces(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(), ImageFormat.CP_PAF_BGR24, faceInfoList);intcnt = 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 =newFaceFeature();                rtn = HowOldAreU.faceEngine.extractFaceFeature(imageInfo.getRgbData(), imageInfo.getWidth(), imageInfo.getHeight(),                                ImageFormat.CP_PAF_BGR24, oneFace, CmFeature);if(rtn !=0) {                        playSound(250);return;                }//是否刚刚识别过intrfe =0;intdSimilScore =0;        FaceSimilar faceSimilar =newFaceSimilar();for(intn=0;n= scoreThreshold){if(MyFunc.datetimeSub(HowOldAreU.aryFFTime.get(n).toString(), nowTime) < recoFreq) {                                        rfe =1;inthdt = 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 face3DAngleList =newArrayList();        rtn = HowOldAreU.faceEngine.getFace3DAngle(face3DAngleList);if(rtn !=0) {                        playSound(250);return;                }if(face3DAngleList.size() ==0) {                        playSound(250);return;                }//0: 正常,其他数值:检测结果不可信intstatus3d = face3DAngleList.get(0).getStatus();if(status3d !=0) {return;}                BigDecimal pitch =newBigDecimal("0");                BigDecimal roll =newBigDecimal("0");                BigDecimal yaw =newBigDecimal("0");                BigDecimal yes3db =newBigDecimal("0").subtract(yes3d);//俯仰角pitch =newBigDecimal(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 =newBigDecimal(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 =newBigDecimal(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 ageInfoList =newArrayList();        rtn = HowOldAreU.faceEngine.getAge(ageInfoList);if(rtn !=0) {                        playSoundSexAge(-1,-1);return;                }                age = ageInfoList.get(0).getAge();if(age >120) {age =120;}//性别提取List genderInfoList =newArrayList();        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);}publicstaticvoidplaySoundSexAge(intsex,intage){//不同年龄段,不同称谓String agename ="frend";if(sex >=0) {if(age >=0&& age <=2) {                                agename ="00-"+sex;                        }elseif(age >=3&& age <=18) {                                agename ="03-"+sex;                        }elseif(age >=19&& age <=45) {                                agename ="19-"+sex;                        }elseif(age >=46&& age <=75) {                                agename ="46-"+sex;                        }elseif(age >=76&& age <=120) {                                agename ="76-"+sex;                        }                }                SoundPlay.playSoundFile(HowOldAreU.soundDir+"agename"+HowOldAreU.fs+"agename-"+agename+".mp3",null);//推测用语JSONArray ary =newJSONArray();                ary.add("401");//你,大概ary.add("402");//我猜你ary.add("403");//我估计你ary.add("404");//我看你ary.add("405");//你看起来intcnt = ary.size();//随机选择一个intidx =0;if(cnt >1) {                        Random random =newRandom();                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 =newJSONArray();                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 =newRandom();                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 =newJSONArray();                ary.add("501");//哈哈!ary.add("502");//嘻嘻!cnt = ary.size();                idx =0;if(cnt >1) {                        Random random =newRandom();                idx = random.nextInt(cnt)%(cnt+1);                }                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3",null);//如果错了ary =newJSONArray();                ary.add("521");//如果我说错了,ary.add("522");//要是我没有说对,cnt = ary.size();                idx =0;if(cnt >1) {                        Random random =newRandom();                    idx = random.nextInt(cnt)%(cnt+1);                }                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3",null);//别生气ary =newJSONArray();                ary.add("541");//你可别生气哦!ary.add("542");//你别往心里去啊!ary.add("543");//你千万别介意哈!cnt = ary.size();                idx =0;if(cnt >1) {                        Random random =newRandom();                    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 =newJSONArray();                ary.add("561");//来,下一个!ary.add("562");//请下一位朋友!ary.add("563");//下一位,谁来?cnt = ary.size();                idx =0;if(cnt >1) {                        Random random =newRandom();                    idx = random.nextInt(cnt)%(cnt+1);                }                SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3",null);        }publicstaticvoidplaySound(intsound_kind){//  http://ai.baidu.com/tech/speech/ttsJSONArray ary =newJSONArray();//文件集switch(sound_kind) {case100:                                                ary.add("101");//秋语已经启动,就要工作啦!break;case150://大家好,我是机器人。主人给我取名:秋语,他还帮我训练了一双火眼金睛,//看一眼就能识别出你们人类的性别和年龄。有人想过来试一试吗?ary.add("150");break;case181:                                                ary.add("181");//你来过的,一分钟之后再来,好吗?break;case182:                                                ary.add("182");//你来过的,一分钟之后再来,好吗?break;case183:                                                ary.add("183");//你怎么还来呀?跟你说了等一分钟的!你真是个急性子,不理你了。break;case200://没有发现人脸时                        ary.add("201");//怎么没有人来跟我玩儿?                        ary.add("202");//有人吗?快来和我玩啦!                        ary.add("203");//我知道你几岁了,过来试试吧!                        ary.add("204");//你们人呢?都到哪儿去了?        ary.add("205");//我等了老半天,怎么连个人影也没看到!break;case250://看不请人脸或无法提取脸纹时                        ary.add("251");//嗨!靠近一点儿,我想看看你呢!ary.add("252");//喂!过来一点嘛,我都看不清你!                        ary.add("253");//hello,离我近一点儿,会有惊喜的!break;//3D角度过大case301://俯仰角过大:请低一下头!case302://俯仰角过大:把头抬一下!case311://横滚角过大:头向左转一下!case312://横滚角过大:向右转一下头!case321://偏航角过大:脖子向左歪一下!case322://偏航角过大:向右歪一下脖子!ary.add(sound_kind);break;case360://性别、年龄均未知                        ary.add("361");//你太神秘了,我实在猜不出你几岁!                        ary.add("362");//你到底几岁呢?我绞尽脑汁也想不出来!                        ary.add("363");//我无法识别你的年龄,我要请主人继续进化我。break;                }intcnt = ary.size();if(cnt ==0) {return;}//随机选择一个intidx =0;if(cnt >1) {                        Random random =newRandom();                idx = random.nextInt(cnt)%(cnt+1);                }//播放SoundPlay.playSoundFile(HowOldAreU.soundDir+ary.get(idx)+".mp3",null);        }publicstaticStringinitEngine(){                JSONObject parm = MyFunc.GetAllProperties("config/parm.properties");                String s = MyFunc.strTrim(parm.getString("err"));if(!"".equals(s)) {return"参数文件读取失败。"+s;        }//APPIDString APPID = MyFunc.strTrim(parm.getString("APP_ID"));if("".equals(APPID)){return"终端APPID缺失,程序将终止。";}//SDKKEYString 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====================================packageapp;importjava.awt.color.ColorSpace;importjava.awt.image.BufferedImage;importjava.awt.image.ColorConvertOp;importjava.awt.image.DataBufferByte;importjava.io.File;importjava.io.IOException;importjava.util.ArrayList;importcom.arcsoft.face.EngineConfiguration;importcom.arcsoft.face.FaceEngine;importcom.arcsoft.face.FunctionConfiguration;importcom.sun.jna.Platform;importtools.FileOpe;publicclassFaceAbout{//加载本地库publicstaticStringloadDllSo(){            String fileType ="",s="",s2="";//路径String dllPath = HowOldAreU.localPath+"ArcSoft";//添加到系统路径addDirToPath(dllPath);//处理依赖库if(Platform.isWindows()) {                        String[] files =newString[2];                        files[0] ="msvcp120.dll";                        files[1] ="msvcr120.dll";for(inti=0;i ary =newArrayList();                ary.add("libarcsoft_face");                ary.add("libarcsoft_face_engine");                ary.add("libarcsoft_face_engine_jni");//加载for(inti=0;i

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

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

作者:Bokeh_JS

链接:https://www.jianshu.com/p/9b1c727ff041

来源:简书

简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。

上一篇下一篇

猜你喜欢

热点阅读