首先说明一下,本期使用单片机来识别车牌并不是在单片机中进行运算实现车牌识别,而是利用单片机获取图片,之后利用无线模块例如ESP32等将图片上传至云平台,利用一些集成的准确度高的云平台实现车牌识别,因此准确率高并且适用其他的单片机,可以用作需要车辆管理的应用场所。
我们本期利用百度智能云的“文字识别的交通OCR场景”。
在百度智能云中找到文字识别,开通这个服务之后,申请适用额度,并且开通车牌识别的功能。之后我们阅读其API文档。
在车牌识别的文档中,我们得知,我们需要知道access_token这个参数,以及之后的图片数据,图片数据需要使用base64编码的图。前者需要我们调用一个API来获取。
填入我们的密钥之后,就可以获得我们的access_token。接下来我们借助ESP32Cam摄像头来实现车牌识别。
这个摄像头也是我用过的成本比较低,开发较为简单的摄像头,我们用Arduino IDE打开摄像头例程。
const char* ssid = "yi****";const char* password = "***";
// 在全局变量区域添加以下内容const char* API_KEY = "*******";const char* SECRET_KEY = "******";String access_token;
定义我们的连接的Wifi内容还有密钥。
String getAccessToken() { HTTPClient http; WiFiClientSecure client; client.setInsecure(); // 注意:这会跳过SSL证书验证
String url = "https://pic.qr2c.cn/oauth/2.0/token"; url += "?grant_type=client_credentials"; url += "&client_id=" + String(API_KEY); url += "&client_secret=" + String(SECRET_KEY);
http.begin(client, url); int httpCode = http.GET();
String token; if (httpCode == HTTP_CODE_OK) { String payload = http.getString(); DynamicJsonDocument doc(1024); deserializeJson(doc, payload); token = doc["access_token"].as<String>(); } else { Serial.println("获取access token失败"); }
http.end(); return token;}
定义一个函数来获取 access token,方便我们后续使用。
可以看到,我们成功的获取了access_token。
camera_fb_t *fb = esp_camera_fb_get(); if (!fb) { Serial.println("拍摄照片失败"); delay(1000); return; }
String base64Image = base64::encode(fb->buf, fb->len); esp_camera_fb_return(fb);
Serial.println("开始识别车牌..."); String recognitionResult = recognizeLicensePlate(base64Image); Serial.println("识别完成");
之后调用摄像头的函数,将拍到的照片进行base64编码。
String recognizeLicensePlate(String base64Image) { HTTPClient http; WiFiClientSecure client; client.setInsecure(); // 注意:这会跳过SSL证书验证,仅用于测试
String url = "https://pic.qr2c.cn/rest/2.0/ocr/v1/license_plate"; url += "?access_token=" + access_token;
http.begin(client, url); http.addHeader("Content-Type", "application/x-www-form-urlencoded");
String httpRequestData = "image=" + urlEncode(base64Image); int httpResponseCode = http.POST(httpRequestData);
String result; if (httpResponseCode > 0) { result = http.getString(); Serial.println("识别结果: " + result); } else { Serial.println("错误码: " + String(httpResponseCode)); }
http.end(); return result;}
按照官网API的说明,将经过编码之后的图片发送给百度,接收返回的信息。
之后将收到的报文车牌信息提取出来,以及车牌在图片的位置等等,根据官网的API说明,还可以判断车牌颜色,车牌是否被阻挡等等。