整合百度AI实现手机拍照识别车牌号

本文介绍如何使用百度AI平台的OCR技术实现车牌自动识别,包括获取access_token、图片预处理、base64编码及urlencode等关键步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

原文:https://blog.youkuaiyun.com/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天进行定期更换;

前端代码

<script>
        var token = sessionStorage.getItem("accessToken");
        if (token == null || token == '') {
            $.ajax({
                url: "${ctx!}/mobile/index/baidu",
                type: "GET",
                dataType: "JSON",
                data: {},
                success: function (message) {
                    sessionStorage.setItem("accessToken", message.data.token);
                },
                error: function (e) {

                }
            });
        }
    </script>
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 
来源:优快云 
原文:https://blog.youkuaiyun.com/tonyfreak/article/details/80748768 
版权声明:本文为博主原创文章,转载请附上博文链接!

伴随着我国社会经济水平的不断提升,物联网这一产业日益发挥着其巨大的影响力。作为其融入日常生活的前沿应用之一,智能交通给我们带来了前所未有的便利。车牌识别的技术研究一直是智能交通领域的热门方向,已经在固定终端平台上得到了全面的发展。而随着智能手机的逐渐普及,车牌识别系统的便携化、多功能化也将成为其下一步的发展趋势。 本文对车牌识别系统中的图像预处理、车牌定位、字符分割以及字符识别等相关操作过程进行了深入的探讨和研究,继而提出了一套完整的基于Android平台移动终端的车牌识别系统。相关主要内容如下: (1)车牌的预处理及定位 首先对我国车牌的特征作了细致的研究分析,为定位部分能够设定合理的阈值从而准确地定位提供了足够的先验知识基础。预处理阶段主要介绍了相应灰度处理以及二值化采用的方法。根据实际拍摄环境的影响会造成车牌图像光照不均匀和光线过暗等现象,本文提出了一种合理的改进方法,即在进行Otsu二值化处理之前加入基于离散余弦变换的光照补偿校正处理,实验证明能够很好的改善上述现象。在对常用的定位方法进行整理和分析之后,结合移动平台硬件限制的特点,本文提出了一种基于边缘检测和形态学处理结合投影分析的有效快速的定位方法。该方法通过sobel垂直算子对图像边缘进行检测,通过形态学一系列处理运算和合适的筛选将车牌连通区域分离出,达到初步定位的效果,最后结合水平和初值投影的分析,准确地于车牌上下左右边缘处进行切割,从而准确定位出车牌。最后,本文针对手机拍摄车牌照片时存在远近不一,拍摄的照片质量低影响定位效果的情况,实现了基于高斯尺度变换的改进方法。 (2)车牌字符的分割操作 该部分主要是对定位输出的车牌区域图像进行实际意义上的分析是否存在倾斜,根据结果决定是否进行相应的校正工作,然后再逐个分割该区域的众字符。这里本文使用的是一种根据相应字符的边界情况进行倾斜校正的方法,该方法通过提取字符边界划定连线,以计算车牌图像的倾斜角度,对于定位后车牌边框残缺不全的情况有很好的性能。最后,在分析常见的字符分割方法的优缺点基础上,本文研究了一种结合先验知识与垂直投影的字符分割处理方法,该方法通过初步分割与精确分割两步处理,能够达到准确分割七个车牌字符的目的,对字符粘连的现象也有很好的改进。 (3)车牌字符的识别 通过对常用字符识别算法的分析和比较,本文结合了模版匹配简单快速的特点,提出了一种基于使用改进的模版匹配进行字符识别的方法。通过给相应模版加高斯噪声的方法模拟现实拍摄环境中出现的照片模糊等现象,使用多模版进行匹配计算,提高了识别算法的鲁棒性,实验证明,该算法能够有效实时地识别出相应车牌的字符,可行性高。对于相似字符易于造成识别错误的情况,本文又针对相似字符进行差异区域扫描分析,并取得了良好的效果。 (4)基于Android平台的LPRS系统软件的设计 在对Android平台的基础知识以的探究之下,根据前几章所提出的一系列车牌识别的系统步骤,本章将其移植到移动终端上来,实现了一个基于Android平台的车牌识别系统,通过对软件进行了功能测试和分析证明了该系统的有效性,满足一定的实际应用需要。 本文设计完成的车牌识别系统应用于移动终端平台,应用环境有交通警察的日常执法如违章车辆信息的登记上传和非法车辆的稽查,路边人工停车的信息管理,普通市民对违章停车的举证和自助通知移车等,相对于传统固定终端的车牌识别系统节约了硬件成本,促进了物联网技术在智能交通中的发展。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值