阿里人脸识别接口
最近研究了一下阿里的人脸识别功能,只是调用阿里提供的接口返回数据给我们就OK了。
详细文档可参考阿里的api 阿里人脸识别api
人脸比对的方法
直接上代码吧:
1 package com.guoxin.common.test; 2 3 import sun.misc.BASE64Encoder; 4 import javax.crypto.Mac; 5 import javax.crypto.spec.SecretKeySpec; 6 import org.slf4j.Logger; 7 import org.slf4j.LoggerFactory; 8 import com.alibaba.fastjson.JSON; 9 import com.alibaba.fastjson.JSONObject; 10 import java.io.*; 11 import java.net.HttpURLConnection; 12 import java.net.URL; 13 import java.net.URLConnection; 14 import java.security.MessageDigest; 15 import java.text.SimpleDateFormat; 16 import java.util.Date; 17 import java.util.Locale; 18 19 //@SuppressWarnings("restriction") 20 public class FaceDemoVerify { 21 private final static Logger logger = LoggerFactory.getLogger(FaceDemoVerify.class.getName()); 22 /* 23 * 计算MD5+BASE64 24 */ 25 public static String MD5Base64(String s) { 26 if (s == null) 27 return null; 28 String encodeStr = ""; 29 byte[] utfBytes = s.getBytes(); 30 MessageDigest mdTemp; 31 try { 32 mdTemp = MessageDigest.getInstance("MD5"); 33 mdTemp.update(utfBytes); 34 byte[] md5Bytes = mdTemp.digest(); 35 BASE64Encoder b64Encoder = new BASE64Encoder(); 36 encodeStr = b64Encoder.encode(md5Bytes); 37 } catch (Exception e) { 38 throw new Error("Failed to generate MD5 : " + e.getMessage()); 39 } 40 return encodeStr; 41 } 42 /* 43 * 计算 HMAC-SHA1 44 */ 45 public static String HMACSha1(String data, String key) { 46 String result; 47 try { 48 SecretKeySpec signingKey = new SecretKeySpec(key.getBytes(), "HmacSHA1"); 49 Mac mac = Mac.getInstance("HmacSHA1"); 50 mac.init(signingKey); 51 byte[] rawHmac = mac.doFinal(data.getBytes()); 52 result = (new BASE64Encoder()).encode(rawHmac); 53 } catch (Exception e) { 54 throw new Error("Failed to generate HMAC : " + e.getMessage()); 55 } 56 return result; 57 } 58 /* 59 * 等同于javaScript中的 new Date().toUTCString(); 60 */ 61 public static String toGMTString(Date date) { 62 SimpleDateFormat df = new SimpleDateFormat("E, dd MMM yyyy HH:mm:ss z", Locale.UK); 63 df.setTimeZone(new java.util.SimpleTimeZone(0, "GMT")); 64 return df.format(date); 65 } 66 /* 67 * 发送POST请求 68 */ 69 public static String sendPost(String url, String body, String ak_id, String ak_secret) throws Exception { 70 PrintWriter out = null; 71 BufferedReader in = null; 72 String result = ""; 73 int statusCode = 200; 74 try { 75 URL realUrl = new URL(url); 76 /* 77 * http header 参数 78 */ 79 String method = "POST"; 80 String accept = "application/json"; 81 String content_type = "application/json"; 82 83 // String content_type = "application/octet-stream"; 84 85 String path = realUrl.getFile(); 86 String date = toGMTString(new Date()); 87 // 1.对body做MD5+BASE64加密 88 String bodyMd5 = MD5Base64(body); 89 String stringToSign = method + "\n" + accept + "\n" + bodyMd5 + "\n" + content_type + "\n" + date + "\n" 90 + path; 91 // 2.计算 HMAC-SHA1 92 String signature = HMACSha1(stringToSign, ak_secret); 93 // 3.得到 authorization header 94 String authHeader = "Dataplus " + ak_id + ":" + signature; 95 // 打开和URL之间的连接 96 URLConnection conn = realUrl.openConnection(); 97 // 设置通用的请求属性 98 conn.setRequestProperty("accept", accept); 99 conn.setRequestProperty("content-type", content_type); 100 conn.setRequestProperty("date", date); 101 conn.setRequestProperty("Authorization", authHeader); 102 // 发送POST请求必须设置如下两行 103 conn.setDoOutput(true); 104 conn.setDoInput(true); 105 // 获取URLConnection对象对应的输出流 106 out = new PrintWriter(conn.getOutputStream()); 107 // 发送请求参数 108 out.print(body); 109 // flush输出流的缓冲 110 out.flush(); 111 // 定义BufferedReader输入流来读取URL的响应 112 statusCode = ((HttpURLConnection)conn).getResponseCode(); 113 if(statusCode != 200) { 114 in = new BufferedReader(new InputStreamReader(((HttpURLConnection)conn).getErrorStream())); 115 } else { 116 in = new BufferedReader(new InputStreamReader(conn.getInputStream())); 117 } 118 String line; 119 while ((line = in.readLine()) != null) { 120 result += line; 121 } 122 } catch (Exception e) { 123 e.printStackTrace(); 124 } finally { 125 try { 126 if (out != null) { 127 out.close(); 128 } 129 if (in != null) { 130 in.close(); 131 } 132 } catch (IOException ex) { 133 ex.printStackTrace(); 134 } 135 } 136 if (statusCode != 200) { 137 throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result); 138 } 139 return result; 140 } 141 /* 142 * GET请求 143 */ 144 public static String sendGet(String url, String ak_id, String ak_secret) throws Exception { 145 String result = ""; 146 BufferedReader in = null; 147 int statusCode = 200; 148 try { 149 URL realUrl = new URL(url); 150 /* 151 * http header 参数 152 */ 153 String method = "GET"; 154 String accept = "application/json"; 155 String content_type = "application/json"; 156 157 // String content_type = "application/octet-stream"; 158 String path = realUrl.getFile(); 159 String date = toGMTString(new Date()); 160 // 1.对body做MD5+BASE64加密 161 // String bodyMd5 = MD5Base64(body); 162 String stringToSign = method + "\n" + accept + "\n" + "" + "\n" + content_type + "\n" + date + "\n" + path; 163 // 2.计算 HMAC-SHA1 164 String signature = HMACSha1(stringToSign, ak_secret); 165 // 3.得到 authorization header 166 String authHeader = "Dataplus " + ak_id + ":" + signature; 167 // 打开和URL之间的连接 168 URLConnection connection = realUrl.openConnection(); 169 // 设置通用的请求属性 170 connection.setRequestProperty("accept", accept); 171 connection.setRequestProperty("content-type", content_type); 172 connection.setRequestProperty("date", date); 173 connection.setRequestProperty("Authorization", authHeader); 174 connection.setRequestProperty("Connection", "keep-alive"); 175 // 建立实际的连接 176 connection.connect(); 177 // 定义 BufferedReader输入流来读取URL的响应 178 statusCode = ((HttpURLConnection)connection).getResponseCode(); 179 if(statusCode != 200) { 180 in = new BufferedReader(new InputStreamReader(((HttpURLConnection)connection).getErrorStream())); 181 } else { 182 in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 183 } 184 String line; 185 while ((line = in.readLine()) != null) { 186 result += line; 187 } 188 } catch (Exception e) { 189 e.printStackTrace(); 190 } finally { 191 try { 192 if (in != null) { 193 in.close(); 194 } 195 } catch (Exception e) { 196 e.printStackTrace(); 197 } 198 } 199 if (statusCode != 200) { 200 throw new IOException("\nHttp StatusCode: "+ statusCode + "\nErrorMessage: " + result); 201 } 202 return result; 203 } 204 public static void main(String[] args) throws Exception { 205 // 发送POST请求示例 206 String ak_id = "L.............BL"; //用户ak 207 String ak_secret = "7W..................4EPW"; // 用户ak_secret 208 String url = "https://dtplus-cn-shanghai.data.aliyuncs.com/face/verify"; 209 210 //上传本地图片 211 // Request body 212 String pic_path = "C:\\Users\\TEST\\1.jpg";//本地图片的路径 213 String pic_path2 = "C:\\Users\\TEST\\8.jpg";//本地图片的路径 214 215 File picBase64 = new File(pic_path); 216 File picBase642 = new File(pic_path2); 217 String pic = encodeImageToBase64(picBase64); 218 String pic2 = encodeImageToBase64(picBase642); 219 // String pic = encodeImageToBase64(pic_path); 220 // String pic2 = encodeImageToBase64(pic_path2); 221 //提出base64编码的换行符问题 222 String data = pic.replaceAll("[\\s*\t\n\r]", ""); 223 String data2 = pic2.replaceAll("[\\s*\t\n\r]", ""); 224 data = "'" + data + "'"; 225 data2 = "'" + data2 + "'"; 226 String body = "{\"type\":1,\n" + 227 "\"content_1\":"+data+",\n" + 228 "\"content_2\":"+data2+"\n" + 229 "}"; 230 231 String re = sendPost(url, body, ak_id, ak_secret); 232 System.out.println("response body:" + re); 233 234 getJsonData(re); 235 } 236 237 /** 238 * 将本地图片编码为base64 239 * 240 * @param file 241 * @return 242 * @throws Exception 243 */ 244 public static String encodeImageToBase64(File file) throws Exception { 245 //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 246 // loggerger.info("图片的路径为:" + file.getAbsolutePath()); 247 InputStream in = null; 248 byte[] data = null; 249 //读取图片字节数组 250 try { 251 in = new FileInputStream(file); 252 data = new byte[in.available()]; 253 in.read(data); 254 in.close(); 255 } catch (IOException e) { 256 e.printStackTrace(); 257 throw new Exception("图片上传失败,请联系客服!"); 258 } 259 //对字节数组Base64编码 260 BASE64Encoder encoder = new BASE64Encoder(); 261 String base64 = encoder.encode(data); 262 return base64;//返回Base64编码过的字节数组字符串 263 } 264 265 /** 266 * 将网络图片编码为base64 267 * 268 * @param url 269 * @return 270 * @throws BusinessException 271 */ 272 public static String encodeImageToBase64(URL url) throws Exception { 273 //将图片文件转化为字节数组字符串,并对其进行Base64编码处理 274 logger.info("图片的路径为:" + url.toString()); 275 //打开链接 276 HttpURLConnection conn = null; 277 try { 278 conn = (HttpURLConnection) url.openConnection(); 279 //设置请求方式为"GET" 280 conn.setRequestMethod("GET"); 281 //超时响应时间为5秒 282 conn.setConnectTimeout(5 * 1000); 283 //通过输入流获取图片数据 284 InputStream inStream = conn.getInputStream(); 285 //得到图片的二进制数据,以二进制封装得到数据,具有通用性 286 ByteArrayOutputStream outStream = new ByteArrayOutputStream(); 287 //创建一个Buffer字符串 288 byte[] buffer = new byte[1024]; 289 //每次读取的字符串长度,如果为-1,代表全部读取完毕 290 int len = 0; 291 //使用一个输入流从buffer里把数据读取出来 292 while ((len = inStream.read(buffer)) != -1) { 293 //用输出流往buffer里写入数据,中间参数代表从哪个位置开始读,len代表读取的长度 294 outStream.write(buffer, 0, len); 295 } 296 //关闭输入流 297 inStream.close(); 298 byte[] data = outStream.toByteArray(); 299 //对字节数组Base64编码 300 BASE64Encoder encoder = new BASE64Encoder(); 301 String base64 = encoder.encode(data); 302 // logger.info("网络文件[{}]编码成base64字符串:[{}]", url.toString(), base64); 303 return base64;//返回Base64编码过的字节数组字符串 304 } catch (IOException e) { 305 e.printStackTrace(); 306 throw new Exception("图片上传失败,请联系客服!"); 307 } 308 } 309 310 311 public static void getJsonData(String re){ 312 // String s = "{\"confidence\":80.6434326171875,\"thresholds\":[61.0,69.0,75.0],\"rectA\":[92,50,74,87],\"rectB\":[171,101,118,137],\"errno\":0,\"request_id\":\"754af075-1d6b-4cb0-a709-7015eac53a7c\"}"; 313 JSONObject jsonObj = JSON.parseObject(re); 314 315 String confidence = jsonObj.getString("confidence"); 316 System.out.println(confidence); 317 } 318 }
选择两本地照片或者网络,经过base64编码处理,作为两个参数传入调用,人脸比对接口,返回数据。
结果 如下
{\"confidence\":80.6434326171875,\"thresholds\":[61.0,69.0,75.0],\"rectA\":[92,50,74,87],\"rectB\":[171,101,118,137],\"errno\":0,\"request_id\":\"754af075-1d6b-4cb0-a709-7015eac53a7c\"}
confidence值即为比对结果的分数,分值越大两张脸相似度高。
提莫队长