调用腾讯优图开放平台进行人脸识别-Java调用API实现

第一步:鉴权服务技术方案

Java代码实现如下

import java.util.Date;  
  
import com.baidu.aip.util.Base64Util;  
/** 
 * 获取Authorization 
 * @author 小帅丶 
 * @类名称  Sign 
 * @remark  
 * @date  2017-8-18 
 */  
public class Sign {  
    /** 
     * Authorization方法 
     * @param userQQ 开发者创建应用时的QQ号 
     * @param AppID 开发者创建应用后的AppID 
     * @param SecretID 开发者创建应用后的SecretID 
     * @param SecretKey 开发者创建应用后的SecretKey 
     * @return sign 
     * @throws Exception 
     */  
    public static String getSign(String userQQ,String AppID,String SecretID,String SecretKey) throws Exception{  
        long tnowTimes = new Date().getTime()/1000;  
        long enowTimes = tnowTimes+2592000;  
        String rRandomNum = HMACSHA1.genRandomNum(10);  
        String param = "u=" + userQQ + "&a=" + AppID + "&k=" + SecretID + "&e="  
                + enowTimes + "&t=" + tnowTimes + "&r=" + rRandomNum + "&f=";  
        byte [] hmacSign = HMACSHA1.getSignature(param, SecretKey);  
        byte[] all = new byte[hmacSign.length+param.getBytes().length];  
        System.arraycopy(hmacSign, 0, all, 0, hmacSign.length);  
        System.arraycopy(param.getBytes(), 0, all, hmacSign.length, param.getBytes().length);  
        String sign = Base64Util.encode(all);  
        return sign;  
    }  
} 

需要的HMACSHA1代码及随机数代码

    import java.util.Random;  
      
    import javax.crypto.Mac;  
    import javax.crypto.spec.SecretKeySpec;  
      
    /** 
     * HMACSHA1算法 
     *  
     * @author 小帅丶 
     * @类名称 HMACSHA1 
     * @remark 
     * @date 2017-8-18 
     */  
    public class HMACSHA1 {  
        /** 
         * 算法标识 
         */  
        private static final String HMAC_SHA1 = "HmacSHA1";  
        /** 
         * 加密 
         * @param data 要加密的数据 
         * @param key 密钥  
         * @return 
         * @throws Exception 
         */  
        public static byte[] getSignature(String data, String key) throws Exception {  
            Mac mac = Mac.getInstance(HMAC_SHA1);  
            SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(),  
                    mac.getAlgorithm());  
            mac.init(signingKey);  
            return mac.doFinal(data.getBytes());  
        }  
        /** 
         * 生成随机数字 
         * @param length 
         * @return 
         */  
        public static String genRandomNum(int length){    
            int  maxNum = 62;    
            int i;    
            int count = 0;    
            char[] str = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};        
            StringBuffer pwd = new StringBuffer("");    
            Random r = new Random();    
            while(count < length){    
             i = Math.abs(r.nextInt(maxNum));       
             if (i >= 0 && i < str.length) {    
              pwd.append(str[i]);    
              count ++;    
             }    
            }    
            return pwd.toString();    
          }   
    }  

第二步:准备相关代码

保存SIGN 或者每次都生成一个也可以 方便测试就直接每次生成一个了

开始识别图片之前需要工具类Base64Util  FileUtil

FileUtil代码

    import java.io.*;  
      
    /** 
     * 文件读取工具类 
     */  
    public class FileUtil {  
      
        /** 
         * 读取文件内容,作为字符串返回 
         */  
        public static String readFileAsString(String filePath) throws IOException {  
            File file = new File(filePath);  
            if (!file.exists()) {  
                throw new FileNotFoundException(filePath);  
            }   
      
            if (file.length() > 1024 * 1024 * 1024) {  
                throw new IOException("File is too large");  
            }   
      
            StringBuilder sb = new StringBuilder((int) (file.length()));  
            // 创建字节输入流    
            FileInputStream fis = new FileInputStream(filePath);    
            // 创建一个长度为10240的Buffer  
            byte[] bbuf = new byte[10240];    
            // 用于保存实际读取的字节数    
            int hasRead = 0;    
            while ( (hasRead = fis.read(bbuf)) > 0 ) {    
                sb.append(new String(bbuf, 0, hasRead));    
            }    
            fis.close();    
            return sb.toString();  
        }  
      
        /** 
         * 根据文件路径读取byte[] 数组 
         */  
        public static byte[] readFileByBytes(String filePath) throws IOException {  
            File file = new File(filePath);  
            if (!file.exists()) {  
                throw new FileNotFoundException(filePath);  
            } else {  
                ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length());  
                BufferedInputStream in = null;  
      
                try {  
                    in = new BufferedInputStream(new FileInputStream(file));  
                    short bufSize = 1024;  
                    byte[] buffer = new byte[bufSize];  
                    int len1;  
                    while (-1 != (len1 = in.read(buffer, 0, bufSize))) {  
                        bos.write(buffer, 0, len1);  
                    }  
      
                    byte[] var7 = bos.toByteArray();  
                    return var7;  
                } finally {  
                    try {  
                        if (in != null) {  
                            in.close();  
                        }  
                    } catch (IOException var14) {  
                        var14.printStackTrace();  
                    }  
      
                    bos.close();  
                }  
            }  
        }  
    }  

Base64Util  代码

    /** 
     * Base64 工具类 
     */  
    public class Base64Util {  
        private static final char last2byte = (char) Integer.parseInt("00000011", 2);  
        private static final char last4byte = (char) Integer.parseInt("00001111", 2);  
        private static final char last6byte = (char) Integer.parseInt("00111111", 2);  
        private static final char lead6byte = (char) Integer.parseInt("11111100", 2);  
        private static final char lead4byte = (char) Integer.parseInt("11110000", 2);  
        private static final char lead2byte = (char) Integer.parseInt("11000000", 2);  
        private static final char[] encodeTable = new char[]{'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'};  
      
        public Base64Util() {  
        }  
      
        public static String encode(byte[] from) {  
            StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3);  
            int num = 0;  
            char currentByte = 0;  
      
            int i;  
            for (i = 0; i < from.length; ++i) {  
                for (num %= 8; num < 8; num += 6) {  
                    switch (num) {  
                        case 0:  
                            currentByte = (char) (from[i] & lead6byte);  
                            currentByte = (char) (currentByte >>> 2);  
                        case 1:  
                        case 3:  
                        case 5:  
                        default:  
                            break;  
                        case 2:  
                            currentByte = (char) (from[i] & last6byte);  
                            break;  
                        case 4:  
                            currentByte = (char) (from[i] & last4byte);  
                            currentByte = (char) (currentByte << 2);  
                            if (i + 1 < from.length) {  
                                currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6);  
                            }  
                            break;  
                        case 6:  
                            currentByte = (char) (from[i] & last2byte);  
                            currentByte = (char) (currentByte << 4);  
                            if (i + 1 < from.length) {  
                                currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4);  
                            }  
                    }  
      
                    to.append(encodeTable[currentByte]);  
                }  
            }  
      
            if (to.length() % 4 != 0) {  
                for (i = 4 - to.length() % 4; i > 0; --i) {  
                    to.append("=");  
                }  
            }  
      
            return to.toString();  
        }  
    }  

创建应用得到的值放在一个常量类里面

    /** 
     * 常量 
     * @author 小帅丶 
     * @类名称  YouTuAppContants 
     * @remark  
     * @date  2017-8-18 
     */  
    public class YouTuAppContants {  
        public static String AppID = "你自己的AppID ";  
        public static String SecretID = "你自己的SecretID";  
        public static String SecretKey = "你自己的SecretKey";  
        public static String userQQ = "你自己的userQQ";  
    }  

还需要一个HTTPUTIL工具类 发送请求

    import java.io.BufferedReader;  
    import java.io.DataOutputStream;  
    import java.io.IOException;  
    import java.io.InputStreamReader;  
    import java.net.HttpURLConnection;  
    import java.net.URL;  
    import java.security.KeyManagementException;  
    import java.security.NoSuchAlgorithmException;  
    import java.security.cert.CertificateException;  
    import java.security.cert.X509Certificate;  
       
    import javax.net.ssl.HostnameVerifier;  
    import javax.net.ssl.SSLContext;  
    import javax.net.ssl.SSLSession;  
    import javax.net.ssl.TrustManager;  
    import javax.net.ssl.X509TrustManager;  
      
    /** 
     * http 工具类 
     */  
    public class HttpUtilYoutu {  
         private static class TrustAnyTrustManager implements X509TrustManager {  
               
                public void checkClientTrusted(X509Certificate[] chain, String authType)  
                        throws CertificateException {  
                }  
           
                public void checkServerTrusted(X509Certificate[] chain, String authType)  
                        throws CertificateException {  
                }  
           
                public X509Certificate[] getAcceptedIssuers() {  
                    return new X509Certificate[] {};  
                }  
            }  
           
            private static class TrustAnyHostnameVerifier implements HostnameVerifier {  
                public boolean verify(String hostname, SSLSession session) {  
                    return true;  
                }  
            }  
           
            /** 
             * post方式请求服务器(https协议) 
             *  
             * @param url 
             *            请求地址 
             * @param content 
             *            参数 
             * @param charset 
             *            编码 
             * @return 
             * @throws NoSuchAlgorithmException 
             * @throws KeyManagementException 
             * @throws IOException 
             */  
            public static String post(String url, String content,String charset,String sign)  
                    throws NoSuchAlgorithmException, KeyManagementException,  
                    IOException {  
                SSLContext sc = SSLContext.getInstance("SSL");  
                sc.init(null, new TrustManager[] { new TrustAnyTrustManager() },  
                        new java.security.SecureRandom());  
                URL console = new URL(url);  
                Integer length = content.length();  
                HttpURLConnection conn = (HttpURLConnection) console.openConnection();  
                //文档要求填写的Header参数                  
                    conn.setRequestProperty("Host", "api.youtu.qq.com");  
                conn.setRequestProperty("Content-Length",length.toString());  
                conn.setRequestProperty("Content-Type", "text/json");  
                conn.setRequestProperty("Authorization", sign);  
                    //文档要求填写的Header参数  
                   conn.setDoOutput(true);  
                conn.connect();  
                DataOutputStream out = new DataOutputStream(conn.getOutputStream());  
                out.write(content.getBytes(charset));  
                // 刷新、关闭  
                out.flush();  
                out.close();  
                BufferedReader in = null;  
                in = new BufferedReader(  
                        new InputStreamReader(conn.getInputStream(), charset));  
                String result = "";  
                String getLine;  
                while ((getLine = in.readLine()) != null) {  
                    result += getLine;  
                }  
                in.close();  
                System.err.println("result:" + result);  
                return result;  
            }  
      
    }  

第三步:测试一下人脸检测接口

请求示例代码:

import com.xiaoshuai.test.Base64Util;  
import com.xiaoshuai.test.FileUtil;  
  
public class DetectFace {  
    //人脸检测接口  
    public static String DETECTFACE_URL="http://api.youtu.qq.com/youtu/api/detectface";  
    public static void main(String[] args) throws Exception {  
        String imagePath = "G:/test2.jpg";  
        System.out.println(getDetectFace(imagePath));  
          
    }  
    /** 
     * 检测图中人脸信息 
     * @param imagePath 图片路径 
     * @return 
     * @throws Exception 
     */  
    public static String getDetectFace(String imagePath) throws Exception{  
        //得到Authorization  
        String sign = Sign.getSign(YouTuAppContants.userQQ,  
                YouTuAppContants.AppID, YouTuAppContants.SecretID,  
                YouTuAppContants.SecretKey);  
        byte[] imgData = FileUtil.readFileByBytes(imagePath);  
        String image =  Base64Util.encode(imgData);;  
        String param = "{\"app_id\":\""+YouTuAppContants.AppID+"\",\"image\":\""+image+"\"}";  
        String result = HttpUtilYoutu.post(DETECTFACE_URL, param, "UTF-8",sign);  
        System.out.println(result);  
        return result;  
    }  
} 

看看返回的内容:

{"session_id":"","image_height":280,"image_width":359,"face":[{"face_id":"2188093443753939350","x":128,"y":127,"height":106.0,"width":106.0,"pitch":6,"roll":3,"yaw":-2,"age":23,"gender":94,"glass":true,"expression":34,"beauty":80,"face_shape":{"face_profile":[{"x":139,"y":160},{"x":139,"y":170},{"x":140,"y":180},{"x":143,"y":189},{"x":146,"y":199},{"x":150,"y":208},{"x":156,"y":217},{"x":162,"y":225},{"x":170,"y":232},{"x":179,"y":236},{"x":189,"y":238},{"x":199,"y":235},{"x":207,"y":230},{"x":214,"y":222},{"x":221,"y":214},{"x":225,"y":205},{"x":229,"y":195},{"x":231,"y":185},{"x":232,"y":174},{"x":233,"y":164},{"x":232,"y":155}],"left_eye":[{"x":152,"y":159},{"x":156,"y":161},{"x":161,"y":163},{"x":166,"y":162},{"x":171,"y":160},{"x":167,"y":157},{"x":162,"y":156},{"x":157,"y":157}],"right_eye":[{"x":216,"y":156},{"x":212,"y":159},{"x":208,"y":160},{"x":203,"y":160},{"x":198,"y":158},{"x":202,"y":155},{"x":206,"y":154},{"x":211,"y":154}],"left_eyebrow":[{"x":143,"y":148},{"x":151,"y":148},{"x":159,"y":148},{"x":166,"y":148},{"x":174,"y":147},{"x":167,"y":142},{"x":158,"y":141},{"x":150,"y":142}],"right_eyebrow":[{"x":224,"y":145},{"x":216,"y":145},{"x":208,"y":145},{"x":200,"y":146},{"x":192,"y":146},{"x":199,"y":141},{"x":208,"y":139},{"x":217,"y":139}],"mouth":[{"x":170,"y":209},{"x":175,"y":214},{"x":180,"y":218},{"x":187,"y":219},{"x":194,"y":217},{"x":200,"y":213},{"x":204,"y":207},{"x":199,"y":203},{"x":192,"y":201},{"x":186,"y":203},{"x":180,"y":202},{"x":174,"y":205},{"x":175,"y":210},{"x":181,"y":211},{"x":187,"y":211},{"x":193,"y":210},{"x":198,"y":209},{"x":198,"y":207},{"x":193,"y":208},{"x":187,"y":209},{"x":180,"y":207},{"x":175,"y":207}],"nose":[{"x":184,"y":184},{"x":183,"y":160},{"x":180,"y":166},{"x":177,"y":173},{"x":174,"y":180},{"x":170,"y":188},{"x":178,"y":191},{"x":185,"y":192},{"x":192,"y":190},{"x":199,"y":186},{"x":194,"y":179},{"x":191,"y":172},{"x":187,"y":166}]}}],"errorcode":0,"errormsg":"OK"}  

忽略掉检测五官位置的数据:

    "face_id": "2188093443753939350",  
    "x": 128,  
    "y": 127,  
    "height": 106,  
    "width": 106,  
    "pitch": 6,  
    "roll": 3,  
    "yaw": -2,  
    "age": 23,//年龄 [0~100]  
    "gender": 94,//性别 [0/(female)~100(male)]  
    "glass": true,//是否有眼镜 [true,false]  
    "expression": 34,//微笑[0(normal)~50(smile)~100(laugh)]  
    "beauty": 80,//魅力 [0~100]  

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Ken的杂谈

C#加密解密(AES)-AESHelper

1.4K20
来自专栏三流程序员的挣扎

RxJava 算术和聚合操作符

将依次连续发送 observableStr,observableInt,observableBoolean 里的 12 个数据。

35840
来自专栏Android机动车

RxJava从入门到不离不弃(四)——过滤操作符

RxJava中的过滤操作符,顾名思义,这类操作符主要用于对事件数据的筛选过滤,只返回满足我们条件的数据。

20230
来自专栏数据结构与算法

10:简单密码

10:简单密码 总时间限制: 1000ms 内存限制: 65536kB描述 Julius Caesar曾经使用过一种很简单的密码。对于明文中的每个字符,将它用...

41260
来自专栏史上最简单的Spring Cloud教程

常见的安全算法

本文整理了常见的安全算法,包括MD5、SHA、DES、AES、RSA等,并写了完整的工具类(Java 版),工具类包含测试。 一、数字摘要算法 数字摘要也称为...

31470
来自专栏三流程序员的挣扎

RxJava 组合操作符

现在看上面的最后一个方法,最后一个参数是多个 Observable,第二个参数 bufferSize 是内部缓冲队列的大小。

31930
来自专栏三流程序员的挣扎

RxJava 过滤操作符

现在想到的应用场景也许是某些 Callable 返回的数据之类,先过滤拿到第一个,然后再用 Observable 发射这第一个数。

21910
来自专栏史上最简单的Spring Cloud教程

一篇RxJava友好的文章(一)

Rxjava在目前的开发中已经是如火如荼,非常的流行,唯一的就是上手不太容易,学习成本高,学习rxjava有一段时间了,也看了老罗的rxjava视频,决定自己总...

23170
来自专栏XAI

调用腾讯优图开放平台进行人脸识别-Java调用API实现

保存SIGN 或者每次都生成一个也可以 方便测试就直接每次生成一个了

2.5K130
来自专栏算法修养

浙江工业大学校赛 竹之书(大数,同余定理)

竹之书 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java...

32480

扫码关注云+社区

领取腾讯云代金券