原文:https://blog.csdn.net/tonyfreak/article/details/80748768
一、功能需求
如图所示,上报时不仅可以手动输入车牌号,还允许拍照自动识别车牌,填充到输入框。
二、思路
拟采用百度AI实现该功能(http://ai.baidu.com/docs#/OCR-API/5116ac95)
根据百度的文档描述,初步明确需要的几个参数为:
1、应用的API Key
2、应用的Secret Key
3、access_token
4、图片数据
官方文档给的提示比较混乱,这一点那一点,刚接触的人会觉得比较晕,我按照自己的思路重新整理了一下。
三、步骤
1、先去百度AI后台创建一个应用,获取到相应的两个KEY
https://console.bce.baidu.com/ai/
2、获取access_token
文档:http://ai.baidu.com/docs#/Auth/top
注意:access_token的有效期为30天,需要每30天进行定期更换;
前端代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
后端代码
/**
* 获取百度AI应用数据.
*
* @param map map
* @return message
*/
@CrossOrigin
@RequestMapping(value = "/baidu", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Message getAi(Model map) {
Message message = new Message();
String url = Constants.BAIDU_AI_TOKEN + clientId + "&client_secret=" + clientSecret + "";
String data = HttpUtil.httpRequest(url);
String accessToken = JSONObject.parseObject(data).getString("access_token");
map.addAttribute("token", accessToken);
message.setData(map);
message.setSuccess(Boolean.TRUE);
return message;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
3、图片数据
文档:http://ai.baidu.com/docs#/OCR-API/0d9adafa (车牌识别所需参数格式要求参考的是该文档)
【image】参数
这里的image我采用的是base64编码。
格式文档:http://ai.baidu.com/docs#/OCR-API/0d9adafa
(1)、注意:图片的base64编码是不包含图片头的,如(data:image/jpg;base64,)
在这一步需要前端获取图片,并将图片转成base64编码,js代码如下:
前端代码
$("#file1").change(function () {
var file1 = document.getElementById("file1").files;
file1 = validateUp(file1);
var url = window.URL.createObjectURL(file1[0]);
//转base64
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'),
img2 = new Image;
img2.crossOrigin = 'Anonymous';
img2.onload = function () {
var height = img2.height;
//console.log("========原始高========" + height);
var width = img2.width;
//console.log("========原始宽========" + width);
if (height > width) {
height = img2.width;
width = img2.height;
//console.log("====" + width + "====转换height========" + height + "===" + height + "==转换width======" + width);
}
var scale = width / height;
//console.log("--比例--" + scale);
// 图片宽度压缩
var width1 = img2.width;
if (width < 500) {
width1 = width;
} else if (width < 1000) {
width1 = width / 2;
} else if (width < 2000) {
width1 = width / 4;
} else if (width < 3000) {
width1 = width / 6;
} else if (width < 4000) {
width1 = width / 8;
} else if (width < 5000) {
width1 = width / 10;
}
//console.log("========调整后宽========" + width1);
//console.log("========调整后高========" + parseInt(width1 / scale));
// 创建属性节点
var anw = document.createAttribute("width");
anw.nodeValue = width1;
var anh = document.createAttribute("height");
anh.nodeValue = parseInt(width1 / scale);
canvas.setAttributeNode(anw);
canvas.setAttributeNode(anh);
ctx.drawImage(img2, 0, 0, width1, parseInt(width1 / scale));
var base64 = canvas.toDataURL('image/jpeg', 0.1);
if (base64 != null && base64 != "" && base64 != "undefined") {
var imgData = base64.replace("data:image/jpeg;base64,", "");
//imgData = encodeURI(imgData);
getLicense(imgData);
//console.info("========images========" + JSON.stringify(imgData));
}
canvas = null;
};
img2.src = url;
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
这里取到的【imgData】就不包含头部信息了。
(2)、图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式,当image字段存在时url字段失效
我采用后台去请求接口获取车牌号,所以要将access_token和image传到后台,对image进行urlencode参照的是下图方法:
至此,所需要的4个参数都已准备完毕。
4、后台发起POST请求获取参数
后端代码
/**
* 获取车牌号.
*
* @param base64 base64
* @param token token
* @param map map
* @return message
*/
@CrossOrigin
@RequestMapping(value = "/getLicense", method = RequestMethod.GET, produces = MediaType.APPLICATION_JSON_VALUE)
@ResponseBody
public Message getLicense(@RequestParam(value = "base64") String base64, @RequestParam(value = "token")
String token, Model map) {
Message message = new Message();
try {
String base = HttpUtil.urlEncode("image", "UTF-8") + "=" +
HttpUtil.urlEncode(base64, "UTF-8");
String url = Constants.BAIDU_AI_LICENSE;
String result = HttpUtil.post(url, token, base);
String license = JSONObject.parseObject(result).getJSONObject("words_result").getString("number");
if (!Strings.isNullOrEmpty(license)) {
map.addAttribute("license", license);
message.setData(map);
message.setSuccess(Boolean.TRUE);
} else {
message.setSuccess(Boolean.FALSE);
}
} catch (Exception e) {
message.setSuccess(Boolean.FALSE);
}
return message;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
DEBUG调试看下数据是否拿到:
四、效果展示
五、注意事项:
1、access_token有有效期,需要定期更换。
2、图片大小限制(分辨率、字节数)。
后台发起请求获取车牌号,一张图片从前台传到后台,再调用百度API,相当于传递两次,图片太大的话会造成访问过慢,用户体验不好。但是图片过小、分辨率压缩的过低,又会降低识别成功率。所以这里对处理图片的参数设置需要自己去把握,更好的平衡利弊。
六、资源
HttpUtil下载地址:https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
---------------------
作者:tonyfreak
来源:CSDN
原文:https://blog.csdn.net/tonyfreak/article/details/80748768
版权声明:本文为博主原创文章,转载请附上博文链接!