当前位置:网站首页>Custom implementation of Baidu image recognition (instead of aipocr)
Custom implementation of Baidu image recognition (instead of aipocr)
2022-04-23 16:31:00 【Spilled off】
package com.visy.service;
import com.baidu.aip.util.Base64Util;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.visy.exception.ErrorEnum;
import com.visy.exception.BusinessException;
import com.visy.config.BaiduConfig;
import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/**
* Baidu image recognition custom implementation ( replace AipOcr)
* @author visy.wang
* @date 2022/1/19 9:24
*/
@Slf4j
@Service
public class AipOcrClient {
private static long expireTime = 0L; //token Expiration time stamp
private static String accessToken = null; //token value
@Autowired
private BaiduConfig baiduConfig; // Baidu authentication information , Configure your own apiKey and secretKey
@Autowired
private RestTemplate restTemplate;
//Url Management enumeration
@Getter
@AllArgsConstructor
enum UrlKey {
ACCESS_TOKEN("https://aip.baidubce.com/oauth/2.0/token", " Certification address "),
DRIVING_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/driving_license", " Driver's license identification address "),
VEHICLE_LICENSE("https://aip.baidubce.com/rest/2.0/ocr/v1/vehicle_license", " Driving license identification address ");
private final String url;
private final String desc;
}
/**
* Driver's license identification
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Driver's license identification
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject drivingLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.DRIVING_LICENSE, options);
}
/**
* Identification of driving license
* @param image picture ( Binary system )
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(byte[] image, HashMap<String,String> options){
options.put("image", Base64Util.encode(image));
return request(UrlKey.VEHICLE_LICENSE, options);
}
/**
* Identification of driving license
* @param imageUrl Picture address
* @param options The other parameters
* @return Recognition result
*/
public JSONObject vehicleLicense(String imageUrl, HashMap<String,String> options){
options.put("url", imageUrl);
return request(UrlKey.VEHICLE_LICENSE, options);
}
// belt Token Overdue inspection request, Temporarily unnecessary , The expiration time has been calculated and retrieved before expiration
private JSONObject requestWithTokenCheck(UrlKey urlKey, Map<String,String> options){
JSONObject res = request(urlKey, options);
if(res.has("error_code")){
int errCode = res.getInt("error_code");
if(errCode==110 || errCode==111){
accessToken = null; //Token invalid , Clear and retrieve
return request(urlKey, options);
}
}
return res;
}
/**
* request
* @param urlKey url Address enumeration
* @param options The other parameters
* @return Recognition result
*/
private JSONObject request(UrlKey urlKey, Map<String,String> options){
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);
String url = urlKey.getUrl();
MultiValueMap<String, String> queryStr = getQueryStr(urlKey);
UriComponentsBuilder uriBuilder = UriComponentsBuilder.fromHttpUrl(url).queryParams(queryStr);
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
if(Objects.nonNull(options) && !options.isEmpty()){
options.forEach(formData::add);
}
HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<>(formData, headers);
ResponseEntity<String> res = restTemplate.postForEntity(uriBuilder.toUriString(), request, String.class);
if(!HttpStatus.OK.equals(res.getStatusCode())){
throw buzError(" request was aborted :httpStatus=" + res.getStatusCode());
}
String resBody = res.getBody();
if(StringUtils.isBlank(resBody)){
throw buzError(" The response body is empty ");
}
return new JSONObject(resBody);
}
private MultiValueMap<String, String> getQueryStr(UrlKey urlKey){
MultiValueMap<String, String> queryStr = new LinkedMultiValueMap<>();
if(UrlKey.ACCESS_TOKEN.equals(urlKey)){
queryStr.add("grant_type", "client_credentials");
queryStr.add("client_id", baiduConfig.getApiKey());
queryStr.add("client_secret", baiduConfig.getSecretKey());
}else{
queryStr.add("access_token", getAccessToken()); // Add authentication information
}
return queryStr;
}
/**
* obtain AccessToken
* @return AccessToken
*/
private String getAccessToken(){
long now = System.currentTimeMillis();
if(StringUtils.isNotBlank(accessToken) && now<expireTime){
// There is a cache and it is within the validity period , Use it directly
return accessToken;
}
try{
return getAccessToken(now);
}catch (Exception e){
throw buzError("AccessToken Acquisition failure :" + e.getMessage());
}
}
private String getAccessToken(long now){
log.info(" Retrieving AccessToken...");
JSONObject body = request(UrlKey.ACCESS_TOKEN, null);
if(body.has("error")){
throw buzError(body.getString("error_description"));
}
int tokenExpires = body.getInt("expires_in"); // The period of validity , Unit second , Default 30 God
expireTime = now + (tokenExpires-86400L)*1000L; // advance 1 Days out
accessToken = body.getString("access_token"); // cache token
log.info(" Authentication success , Valid until :{}", new Date(expireTime));
return accessToken;
}
/**
* Throw business exception
* @param errMsg error message
* @return Business exceptions
*/
private BusinessException buzError(String errMsg){
//BusinessException: Custom business exception
return new BusinessException(ErrorEnum.BUSINESS_ERR.getCode(), errMsg);
}
}
package com.visy.config;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author visy.wang
* @date 2022/1/19 9:28
*/
@Data
@Configuration
@ConfigurationProperties(prefix = "baidu")
public class BaiduConfig {
private String appId;
private String apiKey;
private String secretKey;
}
版权声明
本文为[Spilled off]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/04/202204231403162847.html
边栏推荐
- 5分钟NLP:Text-To-Text Transfer Transformer (T5)统一的文本到文本任务模型
- Cloudy data flow? Disaster recovery on cloud? Last value content sharing years ago
- 【Pygame小游戏】10年前风靡全球的手游《愤怒的小鸟》,是如何霸榜的?经典回归......
- The biggest winner is China Telecom. Why do people dislike China Mobile and China Unicom?
- Download and install mongodb
- The most detailed knapsack problem!!!
- Government cloud migration practice: Beiming digital division used hypermotion cloud migration products to implement the cloud migration project for a government unit, and completed the migration of n
- 捡起MATLAB的第(3)天
- Ice -- source code analysis
- Win11/10家庭版禁用Edge的inprivate浏览功能
猜你喜欢

Day 9 static abstract class interface

Method 2 of drawing ROC curve in R language: proc package

The first line and the last two lines are frozen when paging

Day (7) of picking up matlab

Review 2021: how to help customers clear the obstacles in the last mile of going to the cloud?

各大框架都在使用的Unsafe类,到底有多神奇?
欣旺达:HEV和BEV超快充拳头产品大规模出货

Nanny Anaconda installation tutorial

The font of the soft cell changes color

磁盘管理与文件系统
随机推荐
Es common query, sorting and aggregation statements
04 Lua 运算符
JSP learning 1
Win11/10家庭版禁用Edge的inprivate浏览功能
Sail soft calls the method of dynamic parameter transfer and sets parameters in the title
Findstr is not an internal or external command workaround
阿里研发三面,面试官一套组合拳让我当场懵逼
下载并安装MongoDB
GRBL学习(二)
安装及管理程序
Cloud migration practice in the financial industry Ping An financial cloud integrates hypermotion cloud migration solution to provide migration services for customers in the financial industry
Oak-d raspberry pie cloud project [with detailed code]
Gartner 發布新興技術研究:深入洞悉元宇宙
RAID磁盘阵列与RAID5的创建
Creation of RAID disk array and RAID5
What is the experience of using prophet, an open source research tool?
Hyperbdr cloud disaster recovery v3 Release of version 3.0 | upgrade of disaster recovery function and optimization of resource group management function
漫画:什么是IaaS、PaaS、SaaS?
Use if else to judge in sail software - use the title condition to judge
File system read and write performance test practice