1.车牌识别
This commit is contained in:
parent
12ba7d8ff4
commit
001fe17de3
3
.gitignore
vendored
3
.gitignore
vendored
@ -264,4 +264,5 @@ build
|
||||
*/tmp/**.html
|
||||
|
||||
/log
|
||||
.git
|
||||
.git
|
||||
/.codebuddy/rules/编码规则.mdc
|
||||
|
||||
@ -1,39 +1,36 @@
|
||||
package com.heyu.api.controller.car;
|
||||
|
||||
import com.aliyun.ocr20191230.models.RecognizeLicensePlateResponse;
|
||||
import com.aliyun.ocr20191230.models.RecognizeLicensePlateResponseBody;
|
||||
import com.heyu.api.alibaba.handle.common.text.ARecognizeLicensePlateHandle;
|
||||
import com.heyu.api.alibaba.request.common.text.ARecognizeLicensePlateRequest;
|
||||
import com.heyu.api.baidu.handle.traffic.BLicensePlateHandle;
|
||||
import com.heyu.api.baidu.request.traffic.BLicensePlateRequest;
|
||||
import com.heyu.api.baidu.response.traffic.BLicensePlateResp;
|
||||
import com.heyu.api.controller.BaseController;
|
||||
import com.heyu.api.data.annotation.NotIntercept;
|
||||
import com.heyu.api.data.utils.ApiR;
|
||||
import com.heyu.api.data.utils.R;
|
||||
import com.heyu.api.request.car.LicensePlateRecognizeRequest;
|
||||
import com.heyu.api.resp.car.RecognizeLicensePlateResp;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import org.apache.commons.collections.CollectionUtils;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
|
||||
/***
|
||||
* https://next.api.aliyun.com/api/ocr/2019-12-30/RecognizeLicensePlate?useCommon=true&tab=DOC&lang=JAVA&sdkStyle=dara
|
||||
*
|
||||
*车牌识别
|
||||
*
|
||||
* RecognizeLicensePlate
|
||||
*
|
||||
*
|
||||
* 车牌识别能力可以准确识别出图像中车牌位置,输出车牌位置坐标、车牌类型、车牌号码、车牌号码置信度、车牌置信度,共 5 个关键字段信息。
|
||||
*
|
||||
* 车牌识别能力目前支持的地域(Region)有上海和深圳,当您开通服务时选择的是上海地域,推荐使用上海地域的 OSS 链接,对于文件在本地或者非上海地域 OSS 链接的情况,请参见文件 URL 处理。当您开通服务时选择的是深圳地域时,仅支持深圳地域 OSS 链接进行调用。
|
||||
*
|
||||
* 示例值:
|
||||
* http://viapi-test.oss-cn-shanghai.aliyuncs.com/viapi-3.0domepic/ocr/RecognizeLicensePlate/cpsb1.jpg
|
||||
*
|
||||
*
|
||||
*/
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.net.URLEncoder;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 车牌识别(百度OCR)
|
||||
*
|
||||
* 支持识别中国大陆机动车蓝牌、黄牌(单双行)、绿牌、大型新能源(黄绿)、领使馆车牌、警牌、武警牌(单双行)、
|
||||
* 军牌(单双行)、港澳出入境车牌、农用车牌、民航车牌、非机动车车牌(北京地区)的地域编号和车牌号,
|
||||
* 并能同时识别图像中的多张车牌。
|
||||
*
|
||||
* 百度文档:https://console.bce.baidu.com/support/#/api?product=AI&project=文字识别&parent=交通场景OCR&api=rest%2F2.0%2Focr%2Fv1%2Flicense_plate&method=post
|
||||
*/
|
||||
@Slf4j
|
||||
@RestController
|
||||
@RequestMapping("/car/license/plate")
|
||||
@ -41,41 +38,98 @@ import org.springframework.web.bind.annotation.RestController;
|
||||
public class RecognizeLicensePlateController extends BaseController {
|
||||
|
||||
@Autowired
|
||||
private ARecognizeLicensePlateHandle aRecognizeLicensePlateHandle;
|
||||
private BLicensePlateHandle bLicensePlateHandle;
|
||||
|
||||
@PostMapping("/recognize")
|
||||
public R recognize(ARecognizeLicensePlateRequest request) {
|
||||
if (!hasImage(request)) {
|
||||
return R.error("imageUrl和imageBase64不能同时为空");
|
||||
public R recognize(@RequestBody LicensePlateRecognizeRequest request) {
|
||||
if (request == null) {
|
||||
return R.error("请求参数不能为空");
|
||||
}
|
||||
if (isBlank(request.getImageBase64()) && isBlank(request.getImageUrl())) {
|
||||
return R.error("imageBase64和imageUrl不能同时为空");
|
||||
}
|
||||
|
||||
ApiR<RecognizeLicensePlateResponse> aR = aRecognizeLicensePlateHandle.handle(request);
|
||||
if (!isValidAliResponse(aR)) {
|
||||
return R.error(thirdError(aR));
|
||||
BLicensePlateRequest bRequest = toBaiduRequest(request);
|
||||
|
||||
ApiR<BLicensePlateResp> apiR = bLicensePlateHandle.handle(bRequest);
|
||||
if (apiR == null || !apiR.isSuccess() || apiR.getData() == null) {
|
||||
return R.error(thirdError(apiR));
|
||||
}
|
||||
|
||||
RecognizeLicensePlateResponseBody.RecognizeLicensePlateResponseBodyData data =
|
||||
aR.getData().getBody().getData();
|
||||
if (CollectionUtils.isEmpty(data.getPlates())) {
|
||||
BLicensePlateResp bResp = apiR.getData();
|
||||
List<BLicensePlateResp.WordsResultDTO> plates = bResp.getWordsResult();
|
||||
if (CollectionUtils.isEmpty(plates)) {
|
||||
return R.error("未识别到车牌信息");
|
||||
}
|
||||
|
||||
RecognizeLicensePlateResponseBody.RecognizeLicensePlateResponseBodyDataPlates plate =
|
||||
data.getPlates().get(0);
|
||||
// 取第一张车牌
|
||||
BLicensePlateResp.WordsResultDTO plate = plates.get(0);
|
||||
RecognizeLicensePlateResp resp = new RecognizeLicensePlateResp();
|
||||
resp.setConfidence(plate.getConfidence());
|
||||
resp.setPlateTypeConfidence(plate.getPlateTypeConfidence());
|
||||
resp.setPlateType(plate.getPlateType());
|
||||
resp.setPlateNumber(plate.getPlateNumber());
|
||||
resp.setPlateNumber(plate.getNumber());
|
||||
resp.setPlateType(mapPlateColor(plate.getColor()));
|
||||
|
||||
// 百度返回字符级置信度列表,取最小值作为整体置信度(保守策略),平均值作为车牌类型置信度
|
||||
List<Double> probabilities = plate.getProbability();
|
||||
if (CollectionUtils.isNotEmpty(probabilities)) {
|
||||
double minConf = probabilities.stream().mapToDouble(Double::doubleValue).min().orElse(0.0);
|
||||
resp.setConfidence((float) minConf);
|
||||
double avgConf = probabilities.stream().mapToDouble(Double::doubleValue).average().orElse(0.0);
|
||||
resp.setPlateTypeConfidence((float) avgConf);
|
||||
}
|
||||
|
||||
return R.ok().setData(resp);
|
||||
}
|
||||
|
||||
private boolean isValidAliResponse(ApiR<RecognizeLicensePlateResponse> apiR) {
|
||||
return apiR != null
|
||||
&& apiR.isSuccess()
|
||||
&& apiR.getData() != null
|
||||
&& isSuccessStatusCode(apiR.getData().getStatusCode())
|
||||
&& apiR.getData().getBody() != null
|
||||
&& apiR.getData().getBody().getData() != null;
|
||||
private BLicensePlateRequest toBaiduRequest(LicensePlateRecognizeRequest request) {
|
||||
BLicensePlateRequest bRequest = new BLicensePlateRequest();
|
||||
// base64编码后进行urlencode是百度API的要求,因为base64的+/=在form-urlencoded中有特殊含义
|
||||
if (isNotBlank(request.getImageBase64())) {
|
||||
bRequest.setImageBase64(encodeUrl(request.getImageBase64()));
|
||||
}
|
||||
// imageUrl 中可能包含 & 等特殊字符,需URL编码后再传给百度API,否则会被解析为form分隔符
|
||||
if (isNotBlank(request.getImageUrl())) {
|
||||
bRequest.setImageUrl(encodeUrl(request.getImageUrl()));
|
||||
}
|
||||
// detectComplete和detectRisk在BLicensePlateRequest中无默认值,handle的check()要求必须为true/false
|
||||
bRequest.setDetectComplete("false");
|
||||
bRequest.setDetectRisk("false");
|
||||
return bRequest;
|
||||
}
|
||||
|
||||
private String encodeUrl(String url) {
|
||||
try {
|
||||
return URLEncoder.encode(url, "UTF-8");
|
||||
} catch (UnsupportedEncodingException e) {
|
||||
log.error("URL编码失败:{}", url, e);
|
||||
return url;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isNotBlank(String value) {
|
||||
return value != null && value.trim().length() > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将百度车牌颜色映射为中文车牌类型
|
||||
*/
|
||||
private String mapPlateColor(String color) {
|
||||
if (color == null) {
|
||||
return null;
|
||||
}
|
||||
switch (color.toLowerCase()) {
|
||||
case "blue":
|
||||
return "小型汽车";
|
||||
case "green":
|
||||
return "新能源车";
|
||||
case "yellow":
|
||||
return "大型汽车";
|
||||
case "white":
|
||||
return "警车";
|
||||
case "black":
|
||||
return "港澳车";
|
||||
default:
|
||||
return color;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -0,0 +1,27 @@
|
||||
package com.heyu.api.request.car;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
/**
|
||||
* 车牌识别请求参数(百度OCR)
|
||||
*
|
||||
* 支持识别中国大陆机动车蓝牌、黄牌(单双行)、绿牌、大型新能源(黄绿)、领使馆车牌、警牌、武警牌(单双行)、
|
||||
* 军牌(单双行)、港澳出入境车牌、农用车牌、民航车牌
|
||||
*/
|
||||
@Data
|
||||
public class LicensePlateRecognizeRequest {
|
||||
|
||||
/**
|
||||
* 图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M
|
||||
* 支持jpg/jpeg/png/bmp格式
|
||||
* 和url二选一
|
||||
*/
|
||||
private String imageBase64;
|
||||
|
||||
/**
|
||||
* 图片完整URL,URL长度不超过1024字节
|
||||
* 和imageBase64二选一
|
||||
*/
|
||||
private String imageUrl;
|
||||
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user