身份证识别&车牌识别
百度文字识别SDK进行身份证识别以及车牌识别
首先我们得在百度智能云上开发者平台上申请一个应用,得到其AK及SK,链接为:https://cloud.baidu.com/?from=console
之后参考官方文档链接:https://ai.baidu.com/ai-doc/OCR/zk3h7xw5e
整体实现效果如下:
工程目录如下:
代码如下:
AuthService.java
1 package text; 2 3 import org.json.JSONObject; 4 5 import java.io.BufferedReader; 6 import java.io.InputStreamReader; 7 import java.net.HttpURLConnection; 8 import java.net.URL; 9 import java.util.List; 10 import java.util.Map; 11 12 /** 13 * 获取token类 14 */ 15 public class AuthService { 16 17 /** 18 * 获取权限token 19 * @return 返回示例: 20 * { 21 * "access_token": "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567", 22 * "expires_in": 2592000 23 * } 24 */ 25 public static String getAuth() { 26 // 官网获取的 API Key 更新为你注册的 27 String clientId = "AK"; 28 // 官网获取的 Secret Key 更新为你注册的 29 String clientSecret = "SK"; 30 return getAuth(clientId, clientSecret); 31 } 32 33 /** 34 * 获取API访问token 35 * 该token有一定的有效期,需要自行管理,当失效时需重新获取. 36 * @param ak - 百度云官网获取的 API Key 37 * @param sk - 百度云官网获取的 Securet Key 38 * @return assess_token 示例: 39 * "24.460da4889caad24cccdb1fea17221975.2592000.1491995545.282335-1234567" 40 */ 41 public static String getAuth(String ak, String sk) { 42 // 获取token地址 43 String authHost = "https://aip.baidubce.com/oauth/2.0/token?"; 44 String getAccessTokenUrl = authHost 45 // 1. grant_type为固定参数 46 + "grant_type=client_credentials" 47 // 2. 官网获取的 API Key 48 + "&client_id=" + ak 49 // 3. 官网获取的 Secret Key 50 + "&client_secret=" + sk; 51 try { 52 URL realUrl = new URL(getAccessTokenUrl); 53 // 打开和URL之间的连接 54 HttpURLConnection connection = (HttpURLConnection) realUrl.openConnection(); 55 connection.setRequestMethod("GET"); 56 connection.connect(); 57 // 获取所有响应头字段 58 Map<String, List<String>> map = connection.getHeaderFields(); 59 // 遍历所有的响应头字段 60 for (String key : map.keySet()) { 61 System.err.println(key + "--->" + map.get(key)); 62 } 63 // 定义 BufferedReader输入流来读取URL的响应 64 BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream())); 65 String result = ""; 66 String line; 67 while ((line = in.readLine()) != null) { 68 result += line; 69 } 70 /** 71 * 返回结果示例 72 */ 73 System.err.println("result:" + result); 74 JSONObject jsonObject = new JSONObject(result); 75 String access_token = jsonObject.getString("access_token"); 76 return access_token; 77 } catch (Exception e) { 78 System.err.printf("获取token失败!"); 79 e.printStackTrace(System.err); 80 } 81 return null; 82 } 83 84 }
Base64Util.java
1 package text; 2 3 /** 4 * Base64 工具类 5 */ 6 public class Base64Util { 7 private static final char last2byte = (char) Integer.parseInt("00000011", 2); 8 private static final char last4byte = (char) Integer.parseInt("00001111", 2); 9 private static final char last6byte = (char) Integer.parseInt("00111111", 2); 10 private static final char lead6byte = (char) Integer.parseInt("11111100", 2); 11 private static final char lead4byte = (char) Integer.parseInt("11110000", 2); 12 private static final char lead2byte = (char) Integer.parseInt("11000000", 2); 13 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', '+', '/'}; 14 15 public Base64Util() { 16 } 17 18 public static String encode(byte[] from) { 19 StringBuilder to = new StringBuilder((int) ((double) from.length * 1.34D) + 3); 20 int num = 0; 21 char currentByte = 0; 22 23 int i; 24 for (i = 0; i < from.length; ++i) { 25 for (num %= 8; num < 8; num += 6) { 26 switch (num) { 27 case 0: 28 currentByte = (char) (from[i] & lead6byte); 29 currentByte = (char) (currentByte >>> 2); 30 case 1: 31 case 3: 32 case 5: 33 default: 34 break; 35 case 2: 36 currentByte = (char) (from[i] & last6byte); 37 break; 38 case 4: 39 currentByte = (char) (from[i] & last4byte); 40 currentByte = (char) (currentByte << 2); 41 if (i + 1 < from.length) { 42 currentByte = (char) (currentByte | (from[i + 1] & lead2byte) >>> 6); 43 } 44 break; 45 case 6: 46 currentByte = (char) (from[i] & last2byte); 47 currentByte = (char) (currentByte << 4); 48 if (i + 1 < from.length) { 49 currentByte = (char) (currentByte | (from[i + 1] & lead4byte) >>> 4); 50 } 51 } 52 53 to.append(encodeTable[currentByte]); 54 } 55 } 56 57 if (to.length() % 4 != 0) { 58 for (i = 4 - to.length() % 4; i > 0; --i) { 59 to.append("="); 60 } 61 } 62 63 return to.toString(); 64 } 65 }
FileUtil.java
1 package text; 2 3 import java.io.*; 4 5 /** 6 * 文件读取工具类 7 */ 8 public class FileUtil { 9 10 /** 11 * 读取文件内容,作为字符串返回 12 */ 13 public static String readFileAsString(String filePath) throws IOException { 14 File file = new File(filePath); 15 if (!file.exists()) { 16 throw new FileNotFoundException(filePath); 17 } 18 19 if (file.length() > 1024 * 1024 * 1024) { 20 throw new IOException("File is too large"); 21 } 22 23 StringBuilder sb = new StringBuilder((int) (file.length())); 24 // 创建字节输入流 25 FileInputStream fis = new FileInputStream(filePath); 26 // 创建一个长度为10240的Buffer 27 byte[] bbuf = new byte[10240]; 28 // 用于保存实际读取的字节数 29 int hasRead = 0; 30 while ( (hasRead = fis.read(bbuf)) > 0 ) { 31 sb.append(new String(bbuf, 0, hasRead)); 32 } 33 fis.close(); 34 return sb.toString(); 35 } 36 37 /** 38 * 根据文件路径读取byte[] 数组 39 */ 40 public static byte[] readFileByBytes(String filePath) throws IOException { 41 File file = new File(filePath); 42 if (!file.exists()) { 43 throw new FileNotFoundException(filePath); 44 } else { 45 ByteArrayOutputStream bos = new ByteArrayOutputStream((int) file.length()); 46 BufferedInputStream in = null; 47 48 try { 49 in = new BufferedInputStream(new FileInputStream(file)); 50 short bufSize = 1024; 51 byte[] buffer = new byte[bufSize]; 52 int len1; 53 while (-1 != (len1 = in.read(buffer, 0, bufSize))) { 54 bos.write(buffer, 0, len1); 55 } 56 57 byte[] var7 = bos.toByteArray(); 58 return var7; 59 } finally { 60 try { 61 if (in != null) { 62 in.close(); 63 } 64 } catch (IOException var14) { 65 var14.printStackTrace(); 66 } 67 68 bos.close(); 69 } 70 } 71 } 72 }
HttpUtil.java
1 package text; 2 3 import java.io.BufferedReader; 4 import java.io.DataOutputStream; 5 import java.io.InputStreamReader; 6 import java.net.HttpURLConnection; 7 import java.net.URL; 8 import java.util.List; 9 import java.util.Map; 10 11 /** 12 * http 工具类 13 */ 14 public class HttpUtil { 15 16 public static String post(String requestUrl, String accessToken, String params) 17 throws Exception { 18 String contentType = "application/x-www-form-urlencoded"; 19 return HttpUtil.post(requestUrl, accessToken, contentType, params); 20 } 21 22 public static String post(String requestUrl, String accessToken, String contentType, String params) 23 throws Exception { 24 String encoding = "UTF-8"; 25 if (requestUrl.contains("nlp")) { 26 encoding = "GBK"; 27 } 28 return HttpUtil.post(requestUrl, accessToken, contentType, params, encoding); 29 } 30 31 public static String post(String requestUrl, String accessToken, String contentType, String params, String encoding) 32 throws Exception { 33 String url = requestUrl + "?access_token=" + accessToken; 34 return HttpUtil.postGeneralUrl(url, contentType, params, encoding); 35 } 36 37 public static String postGeneralUrl(String generalUrl, String contentType, String params, String encoding) 38 throws Exception { 39 URL url = new URL(generalUrl); 40 // 打开和URL之间的连接 41 HttpURLConnection connection = (HttpURLConnection) url.openConnection(); 42 connection.setRequestMethod("POST"); 43 // 设置通用的请求属性 44 connection.setRequestProperty("Content-Type", contentType); 45 connection.setRequestProperty("Connection", "Keep-Alive"); 46 connection.setUseCaches(false); 47 connection.setDoOutput(true); 48 connection.setDoInput(true); 49 50 // 得到请求的输出流对象 51 DataOutputStream out = new DataOutputStream(connection.getOutputStream()); 52 out.write(params.getBytes(encoding)); 53 out.flush(); 54 out.close(); 55 56 // 建立实际的连接 57 connection.connect(); 58 // 获取所有响应头字段 59 Map<String, List<String>> headers = connection.getHeaderFields(); 60 // 遍历所有的响应头字段 61 for (String key : headers.keySet()) { 62 System.err.println(key + "--->" + headers.get(key)); 63 } 64 // 定义 BufferedReader输入流来读取URL的响应 65 BufferedReader in = null; 66 in = new BufferedReader( 67 new InputStreamReader(connection.getInputStream(), encoding)); 68 String result = ""; 69 String getLine; 70 while ((getLine = in.readLine()) != null) { 71 result += getLine; 72 } 73 in.close(); 74 System.err.println("result:" + result); 75 return result; 76 } 77 }
Identity.java
1 package text; 2 3 import java.net.URLEncoder; 4 5 public class Identity { 6 /** 7 * 重要提示代码中所需工具类 8 * FileUtil,Base64Util,HttpUtil,GsonUtils请从 9 * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72 10 * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2 11 * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3 12 * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3 13 * 下载 14 */ 15 public static String idcard() { 16 // 请求url 17 String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard"; 18 try { 19 // 本地文件路径 20 String filePath = "image/identity.png"; 21 byte[] imgData = FileUtil.readFileByBytes(filePath); 22 String imgStr = Base64Util.encode(imgData); 23 String imgParam = URLEncoder.encode(imgStr, "UTF-8"); 24 25 String param = "id_card_side=" + "front" + "&image=" + imgParam; 26 27 // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。 28 String accessToken = AuthService.getAuth(); 29 30 String result = HttpUtil.post(url, accessToken, param); 31 System.out.println(result); 32 return result; 33 } catch (Exception e) { 34 e.printStackTrace(); 35 } 36 return null; 37 } 38 39 public static void main(String[] args) { 40 Identity.idcard(); 41 } 42 }
LicensePlate.java
1 package text; 2 3 import java.net.URLEncoder; 4 5 /** 6 * 车牌识别 7 */ 8 public class LicensePlate { 9 10 /** 11 * 重要提示代码中所需工具类 12 * FileUtil,Base64Util,HttpUtil,GsonUtils请从 13 * https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72 14 * https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2 15 * https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3 16 * https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3 17 * 下载 18 */ 19 public static String licensePlate() { 20 // 请求url 21 String url = "https://aip.baidubce.com/rest/2.0/ocr/v1/license_plate"; 22 try { 23 // 本地文件路径 24 String filePath = "image/car.jpg"; 25 byte[] imgData = FileUtil.readFileByBytes(filePath); 26 String imgStr = Base64Util.encode(imgData); 27 String imgParam = URLEncoder.encode(imgStr, "UTF-8"); 28 29 String param = "image=" + imgParam; 30 31 // 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。 32 String accessToken = AuthService.getAuth(); 33 34 String result = HttpUtil.post(url, accessToken, param); 35 System.out.println(result); 36 return result; 37 } catch (Exception e) { 38 e.printStackTrace(); 39 } 40 return null; 41 } 42 43 public static void main(String[] args) { 44 LicensePlate.licensePlate(); 45 } 46 }
以上参考于 文字识别OCR