
@ -0,0 +1,30 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>com.visual.open.anpr</groupId> |
||||
|
<artifactId>open-anpr-client</artifactId> |
||||
|
<version>1.0.0</version> |
||||
|
|
||||
|
<properties> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>com.alibaba</groupId> |
||||
|
<artifactId>fastjson</artifactId> |
||||
|
<version>1.2.58</version> |
||||
|
</dependency> |
||||
|
<dependency> |
||||
|
<groupId>org.apache.httpcomponents</groupId> |
||||
|
<artifactId>httpclient</artifactId> |
||||
|
<version>4.5</version> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,47 @@ |
|||||
|
package com.visual.open.anpr; |
||||
|
|
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
import com.visual.open.anpr.handle.RecognitionHandler; |
||||
|
|
||||
|
public class PlateRecognition { |
||||
|
/**服务地址**/ |
||||
|
private String serverHost; |
||||
|
/**实例对象**/ |
||||
|
private final static Map<String, PlateRecognition> ins = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
/** |
||||
|
* 构建集合对象 |
||||
|
* @param serverHost 服务地址 |
||||
|
* @return |
||||
|
*/ |
||||
|
private PlateRecognition(String serverHost){ |
||||
|
this.serverHost = serverHost; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建集合对象 |
||||
|
* @param serverHost 服务地址 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static PlateRecognition build (String serverHost){ |
||||
|
String key = serverHost; |
||||
|
if(!ins.containsKey(key)){ |
||||
|
synchronized (PlateRecognition.class){ |
||||
|
if(!ins.containsKey(key)){ |
||||
|
ins.put(key, new PlateRecognition(serverHost)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return ins.get(key); |
||||
|
} |
||||
|
/** |
||||
|
* 人脸比对操作对象 |
||||
|
* @return CollectHandler |
||||
|
*/ |
||||
|
public RecognitionHandler detection(){ |
||||
|
return RecognitionHandler.build(serverHost); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
} |
@ -0,0 +1,12 @@ |
|||||
|
package com.visual.open.anpr.common; |
||||
|
|
||||
|
public class Api { |
||||
|
|
||||
|
public static final String plate_recognition = "/visual/plate/recognition"; |
||||
|
|
||||
|
public static String getUrl(String host, String uri){ |
||||
|
host = host.replaceAll ("/+$", ""); |
||||
|
return host + uri; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,63 @@ |
|||||
|
package com.visual.open.anpr.handle; |
||||
|
|
||||
|
import com.alibaba.fastjson.TypeReference; |
||||
|
import com.visual.open.anpr.common.Api; |
||||
|
import com.visual.open.anpr.http.HttpClient; |
||||
|
import com.visual.open.anpr.model.Recognition; |
||||
|
import com.visual.open.anpr.model.RecognitionRep; |
||||
|
import com.visual.open.anpr.model.RecognitionReq; |
||||
|
import com.visual.open.anpr.model.Response; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
import java.util.concurrent.ConcurrentHashMap; |
||||
|
|
||||
|
public class RecognitionHandler { |
||||
|
|
||||
|
/**服务地址**/ |
||||
|
protected String serverHost; |
||||
|
/**实例对象**/ |
||||
|
private final static Map<String, RecognitionHandler> ins = new ConcurrentHashMap<>(); |
||||
|
|
||||
|
public String getServerHost() { |
||||
|
return serverHost; |
||||
|
} |
||||
|
|
||||
|
public RecognitionHandler setServerHost(String serverHost) { |
||||
|
this.serverHost = serverHost; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 构建车牌检测对象 |
||||
|
* @param serverHost 服务地址 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static RecognitionHandler build(String serverHost){ |
||||
|
String key = serverHost; |
||||
|
if(!ins.containsKey(key)){ |
||||
|
synchronized (RecognitionHandler.class){ |
||||
|
if(!ins.containsKey(key)){ |
||||
|
ins.put(key, new RecognitionHandler().setServerHost(serverHost)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
return ins.get(key); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 车牌检测 |
||||
|
* @param recognition 待检测的数据信息 |
||||
|
* @return 车牌检测结果 |
||||
|
*/ |
||||
|
public Response<List<RecognitionRep>> recognition(Recognition recognition){ |
||||
|
RecognitionReq compareReq = RecognitionReq.build() |
||||
|
.setImage(recognition.getImage()) |
||||
|
.setLimit(recognition.getLimit()); |
||||
|
return HttpClient.post( |
||||
|
Api.getUrl(this.serverHost, Api.plate_recognition), |
||||
|
compareReq, |
||||
|
new TypeReference<Response<List<RecognitionRep>>>() {}); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,207 @@ |
|||||
|
package com.visual.open.anpr.http; |
||||
|
|
||||
|
import com.alibaba.fastjson.TypeReference; |
||||
|
|
||||
|
import com.visual.open.anpr.model.MapParam; |
||||
|
import com.visual.open.anpr.model.Response; |
||||
|
import com.visual.open.anpr.utils.JsonUtil; |
||||
|
import org.apache.http.NameValuePair; |
||||
|
import org.apache.http.client.config.RequestConfig; |
||||
|
import org.apache.http.client.methods.CloseableHttpResponse; |
||||
|
import org.apache.http.client.methods.HttpGet; |
||||
|
import org.apache.http.client.methods.HttpPost; |
||||
|
import org.apache.http.client.utils.URIBuilder; |
||||
|
import org.apache.http.config.Registry; |
||||
|
import org.apache.http.config.RegistryBuilder; |
||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory; |
||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory; |
||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
|
import org.apache.http.entity.StringEntity; |
||||
|
import org.apache.http.impl.client.BasicCookieStore; |
||||
|
import org.apache.http.impl.client.CloseableHttpClient; |
||||
|
import org.apache.http.impl.client.HttpClientBuilder; |
||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
|
import org.apache.http.message.BasicNameValuePair; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
import javax.net.ssl.SSLContext; |
||||
|
import javax.net.ssl.TrustManager; |
||||
|
import javax.net.ssl.X509TrustManager; |
||||
|
import java.io.IOException; |
||||
|
import java.security.cert.CertificateException; |
||||
|
import java.security.cert.X509Certificate; |
||||
|
import java.util.LinkedList; |
||||
|
import java.util.List; |
||||
|
|
||||
|
public class HttpClient { |
||||
|
|
||||
|
/**编码方式*/ |
||||
|
private static final String ENCODING = "UTF-8"; |
||||
|
/**连接超时时间,10秒*/ |
||||
|
public static final int DEFAULT_CONNECT_TIMEOUT = 10 * 1000; |
||||
|
/**socket连接超时时间,10秒*/ |
||||
|
public static final int DEFAULT_READ_TIMEOUT = 10 * 000; |
||||
|
/**请求超时时间,60秒*/ |
||||
|
public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT = 30 * 000; |
||||
|
/**最大连接数,默认为2*/ |
||||
|
private static final int MAX_TOTAL = 8; |
||||
|
/**设置指向特定路由的并发连接总数,默认为2*/ |
||||
|
private static final int MAX_PER_ROUTE = 4; |
||||
|
|
||||
|
private static RequestConfig requestConfig; |
||||
|
private static PoolingHttpClientConnectionManager connectionManager; |
||||
|
private static BasicCookieStore cookieStore; |
||||
|
private static HttpClientBuilder httpBuilder; |
||||
|
private static CloseableHttpClient httpClient; |
||||
|
private static CloseableHttpClient httpsClient; |
||||
|
private static SSLContext sslContext; |
||||
|
|
||||
|
/** |
||||
|
* 创建SSLContext对象,用来绕过https证书认证实现访问。 |
||||
|
*/ |
||||
|
static { |
||||
|
try { |
||||
|
sslContext = SSLContext.getInstance("TLS"); |
||||
|
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
|
||||
|
X509TrustManager tm = new X509TrustManager() { |
||||
|
@Override |
||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) |
||||
|
throws CertificateException { |
||||
|
} |
||||
|
@Override |
||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) |
||||
|
throws CertificateException { |
||||
|
} |
||||
|
@Override |
||||
|
public X509Certificate[] getAcceptedIssuers() { |
||||
|
return null; |
||||
|
} |
||||
|
}; |
||||
|
sslContext.init(null, new TrustManager[] {tm}, null); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化httpclient对象,以及在创建httpclient对象之前的一些自定义配置。 |
||||
|
*/ |
||||
|
static { |
||||
|
// 自定义配置信息
|
||||
|
requestConfig = RequestConfig.custom() |
||||
|
.setSocketTimeout(DEFAULT_READ_TIMEOUT) |
||||
|
.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT) |
||||
|
.setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT) |
||||
|
.build(); |
||||
|
//设置协议http和https对应的处理socket链接工厂的对象
|
||||
|
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create() |
||||
|
.register("http", new PlainConnectionSocketFactory()) |
||||
|
.register("https", new SSLConnectionSocketFactory(sslContext)) |
||||
|
.build(); |
||||
|
connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); |
||||
|
// 设置cookie存储对像,在需要获取cookie信息时,可以使用这个对象。
|
||||
|
cookieStore = new BasicCookieStore(); |
||||
|
// 设置最大连接数
|
||||
|
connectionManager.setMaxTotal(MAX_TOTAL); |
||||
|
// 设置路由并发数
|
||||
|
connectionManager.setDefaultMaxPerRoute(MAX_PER_ROUTE); |
||||
|
httpBuilder = HttpClientBuilder.create(); |
||||
|
httpBuilder.setDefaultRequestConfig(requestConfig); |
||||
|
httpBuilder.setConnectionManager(connectionManager); |
||||
|
httpBuilder.setDefaultCookieStore(cookieStore); |
||||
|
// 实例化http 和 https的对象。
|
||||
|
httpClient = httpBuilder.build(); |
||||
|
httpsClient = httpBuilder.build(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* post请求 |
||||
|
* @param url |
||||
|
* @param data |
||||
|
* @param <T> |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> Response<T> post(String url, Object data) { |
||||
|
return post(url, data, new TypeReference<Response<T>>() {}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* post请求 |
||||
|
* @param url |
||||
|
* @param data |
||||
|
* @param <T> |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> Response<T> post(String url, Object data, TypeReference<Response<T>> type) { |
||||
|
// 创建HTTP对象
|
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
httpPost.addHeader("Content-Type", "application/json;charset=UTF-8"); |
||||
|
// 设置请求头
|
||||
|
if(null != data){ |
||||
|
String json = data instanceof String ? String.valueOf(data) : JsonUtil.toString(data); |
||||
|
StringEntity stringEntity = new StringEntity(json, ENCODING); |
||||
|
stringEntity.setContentEncoding(ENCODING); |
||||
|
httpPost.setEntity(stringEntity); |
||||
|
} |
||||
|
// 创建httpResponse对象
|
||||
|
CloseableHttpClient client = url.toLowerCase().startsWith("https") ? httpsClient : httpClient; |
||||
|
try { |
||||
|
CloseableHttpResponse httpResponse = client.execute(httpPost); |
||||
|
String content = EntityUtils.toString(httpResponse.getEntity(), ENCODING); |
||||
|
return JsonUtil.toEntity(content, type); |
||||
|
} catch (IOException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* get |
||||
|
* @param url |
||||
|
* @param param |
||||
|
* @param <T> |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> Response<T> get(String url, MapParam param) { |
||||
|
return get(url, param, new TypeReference<Response<T>>() {}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* get |
||||
|
* @param url |
||||
|
* @param param |
||||
|
* @param <T> |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> Response<T> get(String url, MapParam param, TypeReference<Response<T>> type) { |
||||
|
try { |
||||
|
//参数构建
|
||||
|
URIBuilder uriBuilder = new URIBuilder(url); |
||||
|
if(null != param && !param.isEmpty()){ |
||||
|
List<NameValuePair> list = new LinkedList<>(); |
||||
|
for(String key : param.keySet()){ |
||||
|
Object value = param.get(key); |
||||
|
if(null == value){ |
||||
|
list.add(new BasicNameValuePair(key, null)); |
||||
|
}else{ |
||||
|
list.add(new BasicNameValuePair(key, String.valueOf(value))); |
||||
|
} |
||||
|
} |
||||
|
uriBuilder.setParameters(list); |
||||
|
} |
||||
|
//构建请求
|
||||
|
HttpGet httpGet = new HttpGet(uriBuilder.build()); |
||||
|
httpGet.setConfig(requestConfig); |
||||
|
httpGet.addHeader("Content-Type", "application/json;charset=UTF-8"); |
||||
|
// 创建httpResponse对象
|
||||
|
CloseableHttpClient client = url.toLowerCase().startsWith("https") ? httpsClient : httpClient; |
||||
|
CloseableHttpResponse httpResponse = client.execute(httpGet); |
||||
|
String content = EntityUtils.toString(httpResponse.getEntity(), ENCODING); |
||||
|
return JsonUtil.toEntity(content, type); |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,4 @@ |
|||||
|
package com.visual.open.anpr.http; |
||||
|
|
||||
|
public class HttpClientResult { |
||||
|
} |
@ -0,0 +1,455 @@ |
|||||
|
package com.visual.open.anpr.http; |
||||
|
|
||||
|
import org.apache.http.NameValuePair; |
||||
|
import org.apache.http.client.config.RequestConfig; |
||||
|
import org.apache.http.client.entity.UrlEncodedFormEntity; |
||||
|
import org.apache.http.client.methods.*; |
||||
|
import org.apache.http.client.utils.URIBuilder; |
||||
|
import org.apache.http.config.Registry; |
||||
|
import org.apache.http.config.RegistryBuilder; |
||||
|
import org.apache.http.conn.socket.ConnectionSocketFactory; |
||||
|
import org.apache.http.conn.socket.PlainConnectionSocketFactory; |
||||
|
import org.apache.http.conn.ssl.SSLConnectionSocketFactory; |
||||
|
import org.apache.http.cookie.Cookie; |
||||
|
import org.apache.http.entity.StringEntity; |
||||
|
import org.apache.http.impl.client.BasicCookieStore; |
||||
|
import org.apache.http.impl.client.CloseableHttpClient; |
||||
|
import org.apache.http.impl.client.HttpClientBuilder; |
||||
|
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; |
||||
|
import org.apache.http.message.BasicNameValuePair; |
||||
|
import org.apache.http.util.EntityUtils; |
||||
|
|
||||
|
import javax.net.ssl.SSLContext; |
||||
|
import javax.net.ssl.TrustManager; |
||||
|
import javax.net.ssl.X509TrustManager; |
||||
|
import java.io.IOException; |
||||
|
import java.io.UnsupportedEncodingException; |
||||
|
import java.security.cert.CertificateException; |
||||
|
import java.security.cert.X509Certificate; |
||||
|
import java.util.*; |
||||
|
|
||||
|
/** |
||||
|
* @Description: httpclient常用方法封装, |
||||
|
* @Author: ggf |
||||
|
* @Date: 2020/06/06 |
||||
|
*/ |
||||
|
public class HttpClientUtils { |
||||
|
/** |
||||
|
* 编码方式 |
||||
|
*/ |
||||
|
private static final String ENCODING = "UTF-8"; |
||||
|
/** |
||||
|
* 连接超时时间,60秒 |
||||
|
*/ |
||||
|
public static final int DEFAULT_CONNECT_TIMEOUT = 6000; |
||||
|
/** |
||||
|
* socket连接超时时间,60秒 |
||||
|
*/ |
||||
|
public static final int DEFAULT_READ_TIMEOUT = 6000; |
||||
|
/** |
||||
|
* 请求超时时间,60秒 |
||||
|
*/ |
||||
|
public static final int DEFAULT_CONNECT_REQUEST_TIMEOUT = 6000; |
||||
|
/** |
||||
|
* 最大连接数,默认为2 |
||||
|
*/ |
||||
|
private static final int MAX_TOTAL = 64; |
||||
|
/** |
||||
|
* 设置指向特定路由的并发连接总数,默认为2 |
||||
|
*/ |
||||
|
private static final int MAX_PER_ROUTE = 32; |
||||
|
|
||||
|
private static RequestConfig requestConfig; |
||||
|
private static PoolingHttpClientConnectionManager connectionManager; |
||||
|
private static BasicCookieStore cookieStore; |
||||
|
private static HttpClientBuilder httpBuilder; |
||||
|
private static CloseableHttpClient httpClient; |
||||
|
private static CloseableHttpClient httpsClient; |
||||
|
private static SSLContext sslContext; |
||||
|
|
||||
|
/** |
||||
|
* 创建SSLContext对象,用来绕过https证书认证实现访问。 |
||||
|
*/ |
||||
|
static { |
||||
|
try { |
||||
|
sslContext = SSLContext.getInstance("TLS"); |
||||
|
// 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
|
||||
|
X509TrustManager tm = new X509TrustManager() { |
||||
|
@Override |
||||
|
public void checkClientTrusted(X509Certificate[] chain, String authType) |
||||
|
throws CertificateException { |
||||
|
} |
||||
|
@Override |
||||
|
public void checkServerTrusted(X509Certificate[] chain, String authType) |
||||
|
throws CertificateException { |
||||
|
} |
||||
|
@Override |
||||
|
public X509Certificate[] getAcceptedIssuers() { |
||||
|
return null; |
||||
|
} |
||||
|
}; |
||||
|
sslContext.init(null, new TrustManager[] {tm}, null); |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 初始化httpclient对象,以及在创建httpclient对象之前的一些自定义配置。 |
||||
|
*/ |
||||
|
static { |
||||
|
// 自定义配置信息
|
||||
|
requestConfig = RequestConfig.custom() |
||||
|
.setSocketTimeout(DEFAULT_READ_TIMEOUT) |
||||
|
.setConnectTimeout(DEFAULT_CONNECT_TIMEOUT) |
||||
|
.setConnectionRequestTimeout(DEFAULT_CONNECT_REQUEST_TIMEOUT) |
||||
|
.build(); |
||||
|
//设置协议http和https对应的处理socket链接工厂的对象
|
||||
|
Registry<ConnectionSocketFactory> socketFactoryRegistry = RegistryBuilder.<ConnectionSocketFactory> create() |
||||
|
.register("http", new PlainConnectionSocketFactory()) |
||||
|
.register("https", new SSLConnectionSocketFactory(sslContext)) |
||||
|
.build(); |
||||
|
connectionManager = new PoolingHttpClientConnectionManager(socketFactoryRegistry); |
||||
|
// 设置cookie存储对像,在需要获取cookie信息时,可以使用这个对象。
|
||||
|
cookieStore = new BasicCookieStore(); |
||||
|
// 设置最大连接数
|
||||
|
connectionManager.setMaxTotal(MAX_TOTAL); |
||||
|
// 设置路由并发数
|
||||
|
connectionManager.setDefaultMaxPerRoute(MAX_PER_ROUTE); |
||||
|
httpBuilder = HttpClientBuilder.create(); |
||||
|
httpBuilder.setDefaultRequestConfig(requestConfig); |
||||
|
httpBuilder.setConnectionManager(connectionManager); |
||||
|
httpBuilder.setDefaultCookieStore(cookieStore); |
||||
|
// 实例化http 和 https的对象。
|
||||
|
httpClient = httpBuilder.build(); |
||||
|
httpsClient = httpBuilder.build(); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装无参数的get请求(http) |
||||
|
* @param url 请求url |
||||
|
* @return 返回对象HttpClientResult |
||||
|
*/ |
||||
|
public static HttpClientResult doGet(String url) { |
||||
|
return doGet(url, false); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装无参get请求,支持https协议 |
||||
|
* @param url 请求url |
||||
|
* @param https 请求的是否是https协议,是:true 否false |
||||
|
* @return |
||||
|
*/ |
||||
|
public static HttpClientResult doGet(String url, boolean https){ |
||||
|
return doGet(url, null, null, https); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装带参数的get请求,支持https协议 |
||||
|
* @param url 请求url |
||||
|
* @param params 请求参数 |
||||
|
* @param https 是否是https协议 |
||||
|
*/ |
||||
|
public static HttpClientResult doGet(String url, Map<String, String> params, boolean https){ |
||||
|
return doGet(url, null, params, https); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装带参数和带请求头信息的GET方法,支持https协议请求 |
||||
|
* @param url 请求url |
||||
|
* @param headers 请求头信息 |
||||
|
* @param params 请求参数 |
||||
|
* @param https 是否使用https协议 |
||||
|
*/ |
||||
|
public static HttpClientResult doGet(String url, Map<String, String> headers, Map<String, String> params, boolean https){ |
||||
|
// 创建HttpGet
|
||||
|
HttpGet httpGet = null; |
||||
|
// 创建httpResponse对象
|
||||
|
CloseableHttpResponse httpResponse = null; |
||||
|
try { |
||||
|
// 创建访问的地址
|
||||
|
URIBuilder uriBuilder = new URIBuilder(url); |
||||
|
if (params != null) { |
||||
|
Set<Map.Entry<String, String>> entrySet = params.entrySet(); |
||||
|
for (Map.Entry<String, String> entry : entrySet) { |
||||
|
uriBuilder.setParameter(entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
// 创建HTTP对象
|
||||
|
httpGet = new HttpGet(uriBuilder.build()); |
||||
|
httpGet.setConfig(requestConfig); |
||||
|
// 设置请求头
|
||||
|
setHeader(headers, httpGet); |
||||
|
// 使用不同的协议进行请求,返回自定义的响应对象
|
||||
|
if (https) { |
||||
|
return getHttpClientResult(httpResponse, httpsClient, httpGet); |
||||
|
} else { |
||||
|
return getHttpClientResult(httpResponse, httpClient, httpGet); |
||||
|
} |
||||
|
} catch (Exception e) { |
||||
|
e.printStackTrace(); |
||||
|
} finally { |
||||
|
// 释放资源
|
||||
|
if (httpGet != null) { |
||||
|
httpGet.releaseConnection(); |
||||
|
} |
||||
|
release(httpResponse); |
||||
|
} |
||||
|
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* POST不带参数,只支持http协议 |
||||
|
* @param url 请求url |
||||
|
*/ |
||||
|
public static HttpClientResult doPost(String url) { |
||||
|
return doPost(url, Boolean.FALSE); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装不带参数的post请求,支持https协议 |
||||
|
* @param url 请求url |
||||
|
* @param https 是否是https协议 |
||||
|
*/ |
||||
|
public static HttpClientResult doPost(String url, boolean https) { |
||||
|
return doPost(url, null, (Map<String, String>)null, https); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 带参数的post请求,支持https协议 |
||||
|
* @param url 请求url |
||||
|
* @param params 请求参数 |
||||
|
* @param https 是否是https协议 |
||||
|
*/ |
||||
|
public static HttpClientResult doPost(String url, Map<String, String> params, boolean https) { |
||||
|
return doPost(url, null, params, https); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 带参数和请求头的POST请求,支持https |
||||
|
* |
||||
|
* @param url 请求url |
||||
|
* @param headers 请求头 |
||||
|
* @param params 请求参数,参数为K=V格式 |
||||
|
* @param https 是否https协议 |
||||
|
*/ |
||||
|
public static HttpClientResult doPost(String url, Map<String, String> headers, Map<String, String> params, boolean https) { |
||||
|
// 创建HTTP对象
|
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
// 设置请求头
|
||||
|
setHeader(headers, httpPost); |
||||
|
// 封装请求参数
|
||||
|
setParam(params, httpPost); |
||||
|
// 创建httpResponse对象
|
||||
|
CloseableHttpResponse httpResponse = null; |
||||
|
try { |
||||
|
if (https) { |
||||
|
return getHttpClientResult(httpResponse, httpsClient, httpPost); |
||||
|
} else { |
||||
|
return getHttpClientResult(httpResponse, httpClient, httpPost); |
||||
|
} |
||||
|
} finally { |
||||
|
httpPost.releaseConnection(); |
||||
|
release(httpResponse); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 带参数、带请求头的POST请求,支持https协议 |
||||
|
* |
||||
|
* @param url 请求url |
||||
|
* @param headers 请求头 |
||||
|
* @param json 请求参数为json格式 |
||||
|
* @param https 是否使用https协议 |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult doPost(String url, Map<String, String> headers, String json, boolean https) { |
||||
|
// 创建HTTP对象
|
||||
|
HttpPost httpPost = new HttpPost(url); |
||||
|
httpPost.setConfig(requestConfig); |
||||
|
// 设置请求头
|
||||
|
setHeader(headers, httpPost); |
||||
|
StringEntity stringEntity = new StringEntity(json, ENCODING); |
||||
|
stringEntity.setContentEncoding(ENCODING); |
||||
|
httpPost.setEntity(stringEntity); |
||||
|
// 创建httpResponse对象
|
||||
|
CloseableHttpResponse httpResponse = null; |
||||
|
try { |
||||
|
if (https) { |
||||
|
return getHttpClientResult(httpResponse, httpsClient, httpPost); |
||||
|
} else { |
||||
|
return getHttpClientResult(httpResponse, httpClient, httpPost); |
||||
|
} |
||||
|
} finally { |
||||
|
httpPost.releaseConnection(); |
||||
|
release(httpResponse); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 发送put请求;不带请求参数 |
||||
|
* |
||||
|
* @param url 请求地址 |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult doPut(String url) { |
||||
|
return doPut(url); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送put请求;带请求参数 |
||||
|
* |
||||
|
* @param url 请求地址 |
||||
|
* @param params 参数集合 |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult doPut(String url, Map<String, String> params) { |
||||
|
HttpPut httpPut = new HttpPut(url); |
||||
|
httpPut.setConfig(requestConfig); |
||||
|
setParam(params, httpPut); |
||||
|
CloseableHttpResponse httpResponse = null; |
||||
|
try { |
||||
|
return getHttpClientResult(httpResponse, httpClient, httpPut); |
||||
|
} finally { |
||||
|
httpPut.releaseConnection(); |
||||
|
release(httpResponse); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送delete请求,不带请求参数 |
||||
|
* |
||||
|
* @param url 请求url |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult doDelete(String url) { |
||||
|
HttpDelete httpDelete = new HttpDelete(url); |
||||
|
httpDelete.setConfig(requestConfig); |
||||
|
CloseableHttpResponse httpResponse = null; |
||||
|
try { |
||||
|
return getHttpClientResult(httpResponse, httpClient, httpDelete); |
||||
|
} finally { |
||||
|
httpDelete.releaseConnection(); |
||||
|
release(httpResponse); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 发送delete请求,带请求参数, 支持https协议 |
||||
|
* |
||||
|
* @param url 请求url |
||||
|
* @param params 请求参数 |
||||
|
* @param https 是否https |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult doDelete(String url, Map<String, String> params, boolean https) { |
||||
|
if (params == null) { |
||||
|
params = new HashMap<String, String>(); |
||||
|
} |
||||
|
params.put("_method", "delete"); |
||||
|
return doPost(url, params, https); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获取cookie信息 |
||||
|
* @return 返回所有cookie集合 |
||||
|
*/ |
||||
|
public static List<Cookie> getCookies() { |
||||
|
return cookieStore.getCookies(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 设置封装请求头 |
||||
|
* |
||||
|
* @param params 头信息 |
||||
|
* @param httpMethod 请求对象 |
||||
|
*/ |
||||
|
public static void setHeader(Map<String, String> params, HttpRequestBase httpMethod) { |
||||
|
// 封装请求头
|
||||
|
if (null != params && !params.isEmpty()) { |
||||
|
Set<Map.Entry<String, String>> entrySet = params.entrySet(); |
||||
|
for (Map.Entry<String, String> entry : entrySet) { |
||||
|
// 设置到请求头到HttpRequestBase对象中
|
||||
|
httpMethod.setHeader(entry.getKey(), entry.getValue()); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 封装请求参数 |
||||
|
* |
||||
|
* @param params 请求参数 |
||||
|
* @param httpMethod 请求方法 |
||||
|
*/ |
||||
|
public static void setParam(Map<String, String> params, HttpEntityEnclosingRequestBase httpMethod) { |
||||
|
// 封装请求参数
|
||||
|
if (null != params && !params.isEmpty()) { |
||||
|
List<NameValuePair> nvps = new ArrayList<NameValuePair>(); |
||||
|
Set<Map.Entry<String, String>> entrySet = params.entrySet(); |
||||
|
for (Map.Entry<String, String> entry : entrySet) { |
||||
|
nvps.add(new BasicNameValuePair(entry.getKey(), entry.getValue())); |
||||
|
} |
||||
|
|
||||
|
UrlEncodedFormEntity entity = null; |
||||
|
try { |
||||
|
entity = new UrlEncodedFormEntity(nvps, ENCODING); |
||||
|
} catch (UnsupportedEncodingException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
// 设置到请求的http对象中
|
||||
|
httpMethod.setEntity(entity); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 获得响应结果 |
||||
|
* |
||||
|
* @param httpResponse 响应对象 |
||||
|
* @param httpClient httpclient对象 |
||||
|
* @param httpMethod 请求方法 |
||||
|
* @return |
||||
|
* @throws Exception |
||||
|
*/ |
||||
|
public static HttpClientResult getHttpClientResult(CloseableHttpResponse httpResponse, CloseableHttpClient httpClient, HttpRequestBase httpMethod) { |
||||
|
try { |
||||
|
// 执行请求
|
||||
|
httpResponse = httpClient.execute(httpMethod); |
||||
|
// 获取返回结果
|
||||
|
if (httpResponse != null && httpResponse.getStatusLine() != null) { |
||||
|
String content = ""; |
||||
|
if (httpResponse.getEntity() != null) { |
||||
|
content = EntityUtils.toString(httpResponse.getEntity(), ENCODING); |
||||
|
} |
||||
|
// return new HttpClientResult(httpResponse.getStatusLine().getStatusCode(), content);
|
||||
|
} |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
// return new HttpClientResult(HttpStatus.SC_INTERNAL_SERVER_ERROR);
|
||||
|
return null; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 释放资源 |
||||
|
* |
||||
|
* @param httpResponse 响应对象 |
||||
|
*/ |
||||
|
public static void release(CloseableHttpResponse httpResponse) { |
||||
|
// 释放资源
|
||||
|
if (httpResponse != null) { |
||||
|
try { |
||||
|
httpResponse.close(); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
@ -0,0 +1,17 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.util.HashMap; |
||||
|
|
||||
|
public class MapParam extends HashMap<String, Object> { |
||||
|
|
||||
|
public static MapParam build(){ |
||||
|
return new MapParam(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public MapParam put(String key, Object value){ |
||||
|
super.put(key, value); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,31 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
public enum PlateColor { |
||||
|
|
||||
|
BLACK("黑色"), |
||||
|
BLUE("蓝色"), |
||||
|
GREEN("绿色"), |
||||
|
WHITE("白色"), |
||||
|
YELLOW("黄色"), |
||||
|
UNKNOWN("未知"); |
||||
|
|
||||
|
private String name; |
||||
|
|
||||
|
PlateColor(String name){ |
||||
|
this.name = name; |
||||
|
} |
||||
|
|
||||
|
public String getName(){ |
||||
|
return this.name; |
||||
|
} |
||||
|
|
||||
|
public static PlateColor valueOfName(String name){ |
||||
|
for (PlateColor item : PlateColor.values()){ |
||||
|
if(item.name.equals(name)){ |
||||
|
return item; |
||||
|
} |
||||
|
} |
||||
|
return UNKNOWN; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,8 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
public enum PlateLayout { |
||||
|
|
||||
|
SINGLE, //单排
|
||||
|
DOUBLE, //双排
|
||||
|
UNKNOWN; //未知
|
||||
|
} |
@ -0,0 +1,66 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class PlateLocation implements Serializable { |
||||
|
/**左上角x坐标**/ |
||||
|
private int x; |
||||
|
/**左上角y坐标**/ |
||||
|
private int y; |
||||
|
/**宽度**/ |
||||
|
private int w; |
||||
|
/**高度**/ |
||||
|
private int h; |
||||
|
|
||||
|
/** |
||||
|
* 构建坐标 |
||||
|
* @param x |
||||
|
* @param y |
||||
|
* @param w |
||||
|
* @param h |
||||
|
* @return |
||||
|
*/ |
||||
|
public static PlateLocation build(int x, int y, int w, int h){ |
||||
|
return new PlateLocation().setX(x).setY(y).setW(w).setH(h); |
||||
|
} |
||||
|
|
||||
|
public static PlateLocation build(float x, float y, float w, float h){ |
||||
|
return new PlateLocation().setX((int) x).setY((int) y).setW((int) w).setH((int) h); |
||||
|
} |
||||
|
|
||||
|
public int getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public PlateLocation setX(int x) { |
||||
|
this.x = x; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public int getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public PlateLocation setY(int y) { |
||||
|
this.y = y; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public int getW() { |
||||
|
return w; |
||||
|
} |
||||
|
|
||||
|
public PlateLocation setW(int w) { |
||||
|
this.w = w; |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public int getH() { |
||||
|
return h; |
||||
|
} |
||||
|
|
||||
|
public PlateLocation setH(int h) { |
||||
|
this.h = h; |
||||
|
return this; |
||||
|
} |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class Recognition<ExtendsVo extends Recognition<ExtendsVo>> implements Serializable { |
||||
|
|
||||
|
/**图像Base64编码值**/ |
||||
|
private String image; |
||||
|
|
||||
|
/**搜索条数:默认5**/ |
||||
|
private Integer limit = 5; |
||||
|
|
||||
|
/** |
||||
|
* 构建比对对象 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static Recognition build(){ |
||||
|
return new Recognition(); |
||||
|
} |
||||
|
|
||||
|
|
||||
|
public String getImage() { |
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
public ExtendsVo setImage(String image) { |
||||
|
this.image = image; |
||||
|
return (ExtendsVo) this; |
||||
|
} |
||||
|
|
||||
|
public Integer getLimit() { |
||||
|
return limit; |
||||
|
} |
||||
|
|
||||
|
public ExtendsVo setLimit(Integer limit) { |
||||
|
this.limit = limit; |
||||
|
return (ExtendsVo) this; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,36 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class RecognitionInfo implements Serializable { |
||||
|
/**车牌布局,单排还是双排**/ |
||||
|
private PlateLayout layout; |
||||
|
/**车牌文本信息**/ |
||||
|
private String plateNo; |
||||
|
/**车牌的颜色信息**/ |
||||
|
private PlateColor plateColor; |
||||
|
|
||||
|
public PlateLayout getLayout() { |
||||
|
return layout; |
||||
|
} |
||||
|
|
||||
|
public void setLayout(PlateLayout layout) { |
||||
|
this.layout = layout; |
||||
|
} |
||||
|
|
||||
|
public String getPlateNo() { |
||||
|
return plateNo; |
||||
|
} |
||||
|
|
||||
|
public void setPlateNo(String plateNo) { |
||||
|
this.plateNo = plateNo; |
||||
|
} |
||||
|
|
||||
|
public PlateColor getPlateColor() { |
||||
|
return plateColor; |
||||
|
} |
||||
|
|
||||
|
public void setPlateColor(PlateColor plateColor) { |
||||
|
this.plateColor = plateColor; |
||||
|
} |
||||
|
} |
@ -0,0 +1,40 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class RecognitionRep implements Serializable { |
||||
|
|
||||
|
/**车牌置信分数**/ |
||||
|
private Float score; |
||||
|
|
||||
|
/**车牌位置信息**/ |
||||
|
private PlateLocation location; |
||||
|
|
||||
|
/**车牌识别信息**/ |
||||
|
private RecognitionInfo recognition; |
||||
|
|
||||
|
public Float getScore() { |
||||
|
return score; |
||||
|
} |
||||
|
|
||||
|
public void setScore(Float score) { |
||||
|
this.score = score; |
||||
|
} |
||||
|
|
||||
|
public PlateLocation getLocation() { |
||||
|
return location; |
||||
|
} |
||||
|
|
||||
|
public void setLocation(PlateLocation location) { |
||||
|
this.location = location; |
||||
|
} |
||||
|
|
||||
|
public RecognitionInfo getRecognition() { |
||||
|
return recognition; |
||||
|
} |
||||
|
|
||||
|
public void setRecognition(RecognitionInfo recognition) { |
||||
|
this.recognition = recognition; |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,13 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
public class RecognitionReq extends Recognition<RecognitionReq>{ |
||||
|
|
||||
|
/** |
||||
|
* 构建比对对象 |
||||
|
* @return |
||||
|
*/ |
||||
|
public static RecognitionReq build(){ |
||||
|
return new RecognitionReq(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,62 @@ |
|||||
|
package com.visual.open.anpr.model; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
/** |
||||
|
* des:接口返回对象 |
||||
|
* @author diven |
||||
|
* @date 上午9:34 2018/7/12 |
||||
|
*/ |
||||
|
public class Response<T> implements Serializable{ |
||||
|
|
||||
|
private static final long serialVersionUID = -6919611972884058300L; |
||||
|
|
||||
|
private Integer code = -1; |
||||
|
private String message; |
||||
|
private T data; |
||||
|
|
||||
|
public Response(){} |
||||
|
|
||||
|
public Response(Integer code, String message, T data) { |
||||
|
if(null != code) { |
||||
|
this.code = code; |
||||
|
} |
||||
|
this.message = message; |
||||
|
this.data = data; |
||||
|
} |
||||
|
|
||||
|
public Integer getCode() { |
||||
|
return code; |
||||
|
} |
||||
|
|
||||
|
public void setCode(Integer code) { |
||||
|
if(null != code){ |
||||
|
this.code = code; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public String getMessage() { |
||||
|
return message; |
||||
|
} |
||||
|
|
||||
|
public void setMessage(String message) { |
||||
|
this.message = message; |
||||
|
} |
||||
|
|
||||
|
public T getData() { |
||||
|
return data; |
||||
|
} |
||||
|
|
||||
|
public void setData(T data) { |
||||
|
this.data = data; |
||||
|
} |
||||
|
|
||||
|
public boolean ok(){ |
||||
|
return new Integer(0).equals(code); |
||||
|
} |
||||
|
|
||||
|
@Override |
||||
|
public String toString() { |
||||
|
return "Response{" + "code=" + code + ", message='" + message + '\'' + ", data=" + data + '}'; |
||||
|
} |
||||
|
} |
@ -0,0 +1,48 @@ |
|||||
|
package com.visual.open.anpr.utils; |
||||
|
|
||||
|
import org.apache.commons.codec.binary.Base64; |
||||
|
|
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.io.FileInputStream; |
||||
|
import java.io.IOException; |
||||
|
import java.io.InputStream; |
||||
|
|
||||
|
public class Base64Util { |
||||
|
|
||||
|
public static String encode(byte[] binaryData) { |
||||
|
byte[] bytes = Base64.encodeBase64(binaryData); |
||||
|
return new String(bytes); |
||||
|
} |
||||
|
|
||||
|
public static String encode(InputStream in) { |
||||
|
// 读取图片字节数组
|
||||
|
try { |
||||
|
ByteArrayOutputStream swapStream = new ByteArrayOutputStream(); |
||||
|
byte[] buff = new byte[100]; |
||||
|
int rc; |
||||
|
while ((rc = in.read(buff, 0, 100)) > 0) { |
||||
|
swapStream.write(buff, 0, rc); |
||||
|
} |
||||
|
return encode(swapStream.toByteArray()); |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} finally { |
||||
|
if (in != null) { |
||||
|
try { |
||||
|
in.close(); |
||||
|
} catch (IOException e) { |
||||
|
e.printStackTrace(); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static String encode(String filePath){ |
||||
|
try { |
||||
|
return encode(new FileInputStream(filePath)); |
||||
|
} catch (Exception e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,128 @@ |
|||||
|
package com.visual.open.anpr.utils; |
||||
|
|
||||
|
import com.alibaba.fastjson.JSON; |
||||
|
import com.alibaba.fastjson.JSONArray; |
||||
|
import com.alibaba.fastjson.JSONObject; |
||||
|
import com.alibaba.fastjson.TypeReference; |
||||
|
import com.alibaba.fastjson.serializer.SerializerFeature; |
||||
|
|
||||
|
import java.util.List; |
||||
|
import java.util.Map; |
||||
|
|
||||
|
public class JsonUtil { |
||||
|
|
||||
|
/** |
||||
|
* 将Bean转化为json字符串 |
||||
|
* |
||||
|
* @param obj bean对象 |
||||
|
* @return json |
||||
|
*/ |
||||
|
public static String toString(Object obj) { |
||||
|
return toString(obj, false, false); |
||||
|
} |
||||
|
|
||||
|
public static String toSimpleString(Object obj) { |
||||
|
return toString(obj, false, true); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将Bean转化为json字符串 |
||||
|
* |
||||
|
* @param obj bean对象 |
||||
|
* @param prettyFormat 是否格式化 |
||||
|
* @return json |
||||
|
*/ |
||||
|
public static String toString(Object obj, boolean prettyFormat, boolean noNull) { |
||||
|
if (prettyFormat) { |
||||
|
if (noNull) { |
||||
|
return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.PrettyFormat); |
||||
|
} else { |
||||
|
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.PrettyFormat); |
||||
|
} |
||||
|
} else { |
||||
|
if (noNull) { |
||||
|
return JSON.toJSONString(obj, SerializerFeature.DisableCircularReferenceDetect); |
||||
|
} else { |
||||
|
return JSON.toJSONString(obj, SerializerFeature.WriteMapNullValue, SerializerFeature.WriteNullListAsEmpty, SerializerFeature.DisableCircularReferenceDetect); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为Entity |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @param clazz Entity class |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> T toEntity(String json, Class<T> clazz) { |
||||
|
return JSON.parseObject(json, clazz); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为Entity |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @param typeReference Entity class |
||||
|
* @return |
||||
|
*/ |
||||
|
public static <T> T toEntity(String json, TypeReference<T> typeReference) { |
||||
|
return JSON.parseObject(json, typeReference); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为Map |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @return Map |
||||
|
*/ |
||||
|
public static Map<String, Object> toMap(String json) { |
||||
|
return JSON.parseObject(json, new TypeReference<Map<String, Object>>() { |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为List<T> |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @param collectionClass 泛型 |
||||
|
* @return list<T> |
||||
|
*/ |
||||
|
public static <T> List<T> toList(String json, Class<T> collectionClass) { |
||||
|
return JSON.parseArray(json, collectionClass); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为List<Map<String, Object>> |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @return list<map> |
||||
|
*/ |
||||
|
public static List<Map<String, Object>> toListMap(String json) { |
||||
|
return JSON.parseObject(json, new TypeReference<List<Map<String, Object>>>() { |
||||
|
}); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为Object |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @return list<map> |
||||
|
*/ |
||||
|
public static JSONObject toJsonObject(String json) { |
||||
|
return JSON.parseObject(json); |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将字符串转换为Array |
||||
|
* |
||||
|
* @param json 数据字符串 |
||||
|
* @return list<map> |
||||
|
*/ |
||||
|
public static JSONArray toJsonArray(String json) { |
||||
|
return JSON.parseArray(json); |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
@ -0,0 +1,38 @@ |
|||||
|
package com.visual.open.anpr.server.domain.extend; |
||||
|
|
||||
|
import io.swagger.annotations.ApiModelProperty; |
||||
|
|
||||
|
import java.io.Serializable; |
||||
|
|
||||
|
public class LocationPoint implements Serializable { |
||||
|
|
||||
|
/**坐标X的值**/ |
||||
|
@ApiModelProperty(value="坐标X的值", position = 1, required = true) |
||||
|
private int x; |
||||
|
/**坐标Y的值**/ |
||||
|
@ApiModelProperty(value="坐标Y的值", position = 2, required = true) |
||||
|
private int y; |
||||
|
|
||||
|
public LocationPoint(){} |
||||
|
|
||||
|
public LocationPoint(float x, float y) { |
||||
|
this.x = (int)x; |
||||
|
this.y = (int)y; |
||||
|
} |
||||
|
|
||||
|
public int getX() { |
||||
|
return x; |
||||
|
} |
||||
|
|
||||
|
public void setX(int x) { |
||||
|
this.x = x; |
||||
|
} |
||||
|
|
||||
|
public int getY() { |
||||
|
return y; |
||||
|
} |
||||
|
|
||||
|
public void setY(int y) { |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
@ -0,0 +1,32 @@ |
|||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||
|
<project xmlns="http://maven.apache.org/POM/4.0.0" |
||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
||||
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> |
||||
|
<modelVersion>4.0.0</modelVersion> |
||||
|
|
||||
|
<groupId>com.visual.open.anpr</groupId> |
||||
|
<artifactId>open-anpr-test</artifactId> |
||||
|
<version>1.0.0</version> |
||||
|
|
||||
|
<properties> |
||||
|
<java.version>1.8</java.version> |
||||
|
<maven.compiler.source>8</maven.compiler.source> |
||||
|
<maven.compiler.target>8</maven.compiler.target> |
||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> |
||||
|
</properties> |
||||
|
|
||||
|
<dependencies> |
||||
|
<dependency> |
||||
|
<groupId>com.visual.open.anpr</groupId> |
||||
|
<artifactId>open-anpr-client</artifactId> |
||||
|
<version>${project.version}</version> |
||||
|
</dependency> |
||||
|
|
||||
|
<dependency> |
||||
|
<groupId>org.openpnp</groupId> |
||||
|
<artifactId>opencv</artifactId> |
||||
|
<version>4.6.0-0</version> |
||||
|
</dependency> |
||||
|
</dependencies> |
||||
|
|
||||
|
</project> |
@ -0,0 +1,65 @@ |
|||||
|
package com.visual.open.anpr.exps; |
||||
|
|
||||
|
import com.visual.open.anpr.PlateRecognition; |
||||
|
import com.visual.open.anpr.model.*; |
||||
|
import com.visual.open.anpr.utils.Base64Util; |
||||
|
import com.visual.open.anpr.utils.DrawImage; |
||||
|
import org.opencv.highgui.HighGui; |
||||
|
|
||||
|
import java.awt.*; |
||||
|
import java.io.File; |
||||
|
import java.util.List; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
public class PlateRecognitionExample { |
||||
|
|
||||
|
static{ nu.pattern.OpenCV.loadShared(); } |
||||
|
//本地开发模式
|
||||
|
public static String serverHost = "http://127.0.0.1:8080"; |
||||
|
//docker部署模式
|
||||
|
//public static String serverHost = "http://127.0.0.1:56790";
|
||||
|
//远程测试服务
|
||||
|
//public static String serverHost = "http://open-anpr.diven.nat300.top";
|
||||
|
|
||||
|
public static PlateRecognition plateRecognition = PlateRecognition.build(serverHost); |
||||
|
|
||||
|
/**搜索*/ |
||||
|
public static void recognition() { |
||||
|
String searchPath = "open-anpr-test/src/main/resources/image"; |
||||
|
File [] files = Objects.requireNonNull(new File(searchPath).listFiles()); |
||||
|
for(int i=0; i< files.length-1; i++){ |
||||
|
File imageA = files[i]; |
||||
|
String imageBase64 = Base64Util.encode(imageA.getAbsolutePath()); |
||||
|
Response<List<RecognitionRep>> response = plateRecognition.detection().recognition( |
||||
|
Recognition.build().setImage(imageBase64).setLimit(5) |
||||
|
); |
||||
|
|
||||
|
DrawImage drawImage = DrawImage.build(imageA.getAbsolutePath()); |
||||
|
if(response.ok()){ |
||||
|
for(RecognitionRep recognitionRep : response.getData()){ |
||||
|
PlateLocation location = recognitionRep.getLocation(); |
||||
|
drawImage.drawRect( |
||||
|
new DrawImage.Rect(location.getX(), location.getY(), location.getW(), location.getH()), 2, Color.RED); |
||||
|
|
||||
|
|
||||
|
RecognitionInfo recognition = recognitionRep.getRecognition(); |
||||
|
int fonSize = Float.valueOf(1.4f * location.getW() / recognition.getPlateNo().length()).intValue(); |
||||
|
drawImage.drawText(recognition.getPlateNo(), |
||||
|
new DrawImage.Point(location.getX(), location.getY()-(int)(fonSize*2.2)), fonSize, Color.RED); |
||||
|
drawImage.drawText((recognition.getLayout() == PlateLayout.SINGLE ? "单排" : "双排") + ":" + recognition.getPlateColor().getName(), |
||||
|
new DrawImage.Point(location.getX(), location.getY()-(int)(fonSize*1.2)), fonSize, Color.RED); |
||||
|
} |
||||
|
} |
||||
|
HighGui.imshow("image", drawImage.toMat()); |
||||
|
HighGui.waitKey(); |
||||
|
} |
||||
|
//退出程序
|
||||
|
System.exit(1); |
||||
|
} |
||||
|
|
||||
|
/**main**/ |
||||
|
public static void main(String[] args) { |
||||
|
recognition(); |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,124 @@ |
|||||
|
package com.visual.open.anpr.utils; |
||||
|
|
||||
|
|
||||
|
import org.opencv.core.CvType; |
||||
|
import org.opencv.core.Mat; |
||||
|
|
||||
|
import javax.imageio.ImageIO; |
||||
|
import java.awt.*; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.awt.image.DataBufferByte; |
||||
|
import java.io.File; |
||||
|
import java.io.IOException; |
||||
|
|
||||
|
|
||||
|
public class DrawImage { |
||||
|
|
||||
|
private BufferedImage image; |
||||
|
|
||||
|
private DrawImage(BufferedImage image){ |
||||
|
this.image = image; |
||||
|
} |
||||
|
|
||||
|
public static DrawImage build(String image){ |
||||
|
try { |
||||
|
return build(ImageIO.read(new File(image))); |
||||
|
} catch (IOException e) { |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static DrawImage build(BufferedImage image){ |
||||
|
return new DrawImage(image); |
||||
|
} |
||||
|
|
||||
|
private static int getLength(String text) { |
||||
|
int textLength = text.length(); |
||||
|
int length = textLength; |
||||
|
for (int i = 0; i < textLength; i++) { |
||||
|
if (String.valueOf(text.charAt(i)).getBytes().length > 1) { |
||||
|
length++; |
||||
|
} |
||||
|
} |
||||
|
return (length % 2 == 0) ? length / 2 : length / 2 + 1; |
||||
|
} |
||||
|
|
||||
|
public DrawImage drawRect(Rect rect, int lineWidth, Color color){ |
||||
|
Graphics2D g = (Graphics2D)image.getGraphics(); |
||||
|
g.setColor(color); |
||||
|
g.setStroke(new BasicStroke(lineWidth)); |
||||
|
g.drawRect(rect.x, rect.y, rect.width, rect.height); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public DrawImage drawText(String text, Point point, int fontSize, Color color){ |
||||
|
Graphics2D g = image.createGraphics(); |
||||
|
g.setColor(color); |
||||
|
g.setFont(new Font("微软雅黑", Font.PLAIN, fontSize)); |
||||
|
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 1)); |
||||
|
int width_1 = fontSize * getLength(text); |
||||
|
int height_1 = fontSize; |
||||
|
int widthDiff = image.getWidth() - width_1; |
||||
|
int heightDiff = image.getHeight() - height_1; |
||||
|
if(point.x < 0){ |
||||
|
point.x = widthDiff / 2; |
||||
|
}else if(point.x > widthDiff){ |
||||
|
point.x = widthDiff; |
||||
|
} |
||||
|
if(point.y < 0){ |
||||
|
point.y = heightDiff / 2; |
||||
|
}else if(point.y > heightDiff){ |
||||
|
point.y = heightDiff; |
||||
|
} |
||||
|
g.drawString(text, point.x, point.y + height_1); |
||||
|
return this; |
||||
|
} |
||||
|
|
||||
|
public Mat toMat(){ |
||||
|
try { |
||||
|
if(image.getType() != BufferedImage.TYPE_3BYTE_BGR){ |
||||
|
BufferedImage temp = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_3BYTE_BGR); |
||||
|
Graphics2D g = temp.createGraphics(); |
||||
|
try { |
||||
|
g.setComposite(AlphaComposite.Src); |
||||
|
g.drawImage(image, 0, 0, null); |
||||
|
} finally { |
||||
|
g.dispose(); |
||||
|
} |
||||
|
image = temp; |
||||
|
} |
||||
|
byte[] pixels = ((DataBufferByte) image.getRaster().getDataBuffer()).getData(); |
||||
|
Mat mat = Mat.eye(image.getHeight(), image.getWidth(), CvType.CV_8UC3); |
||||
|
mat.put(0, 0, pixels); |
||||
|
return mat; |
||||
|
}catch (Exception e){ |
||||
|
throw new RuntimeException(e); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static class Rect{ |
||||
|
public int x; |
||||
|
public int y; |
||||
|
public int width; |
||||
|
public int height; |
||||
|
|
||||
|
public Rect(int x, int y, int width, int height) { |
||||
|
this.x = x; |
||||
|
this.y = y; |
||||
|
this.width = width; |
||||
|
this.height = height; |
||||
|
} |
||||
|
|
||||
|
} |
||||
|
|
||||
|
public static class Point{ |
||||
|
public int x; |
||||
|
public int y; |
||||
|
|
||||
|
public Point(int x, int y) { |
||||
|
this.x = x; |
||||
|
this.y = y; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
} |
@ -0,0 +1,107 @@ |
|||||
|
package com.visual.open.anpr.utils; |
||||
|
|
||||
|
import org.opencv.core.Mat; |
||||
|
import org.opencv.core.Range; |
||||
|
|
||||
|
import javax.imageio.ImageIO; |
||||
|
import java.awt.image.BufferedImage; |
||||
|
import java.io.ByteArrayOutputStream; |
||||
|
import java.util.Base64; |
||||
|
import java.util.Objects; |
||||
|
|
||||
|
public class MatUtil { |
||||
|
|
||||
|
/** |
||||
|
* 将Mat转换为BufferedImage |
||||
|
* @param mat |
||||
|
* @return BufferedImage |
||||
|
*/ |
||||
|
public static BufferedImage matToBufferedImage(Mat mat) { |
||||
|
int dataSize = mat.cols() * mat.rows() * (int) mat.elemSize(); |
||||
|
byte[] data = new byte[dataSize]; |
||||
|
mat.get(0, 0, data); |
||||
|
int type = mat.channels() == 1 ? BufferedImage.TYPE_BYTE_GRAY : BufferedImage.TYPE_3BYTE_BGR; |
||||
|
if (type == BufferedImage.TYPE_3BYTE_BGR) { |
||||
|
for (int i = 0; i < dataSize; i += 3) { |
||||
|
byte blue = data[i + 0]; |
||||
|
data[i + 0] = data[i + 2]; |
||||
|
data[i + 2] = blue; |
||||
|
} |
||||
|
} |
||||
|
BufferedImage image = new BufferedImage(mat.cols(), mat.rows(), type); |
||||
|
image.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), data); |
||||
|
return image; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 将Mat转换为 Base64 |
||||
|
* @param mat |
||||
|
* @return Base64 |
||||
|
*/ |
||||
|
public static String matToBase64(Mat mat) { |
||||
|
ByteArrayOutputStream byteArrayOutputStream = null; |
||||
|
try { |
||||
|
byteArrayOutputStream = new ByteArrayOutputStream(); |
||||
|
ImageIO.write(matToBufferedImage(mat), "jpg", byteArrayOutputStream); |
||||
|
byte[] bytes = byteArrayOutputStream.toByteArray(); |
||||
|
Base64.Encoder encoder = Base64.getMimeEncoder(); |
||||
|
return encoder.encodeToString(Objects.requireNonNull(bytes)); |
||||
|
}catch (Exception e){ |
||||
|
throw new RuntimeException(e); |
||||
|
}finally { |
||||
|
if(null != byteArrayOutputStream){ |
||||
|
try { |
||||
|
byteArrayOutputStream.close(); |
||||
|
} catch (Exception e) {} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public static Mat concat(Mat m1, Mat ...m2){ |
||||
|
Mat mat = m1; |
||||
|
if(null != m2){ |
||||
|
for(Mat m : m2){ |
||||
|
mat = concat(mat, m1); |
||||
|
} |
||||
|
} |
||||
|
return mat; |
||||
|
} |
||||
|
|
||||
|
/** |
||||
|
* 横向拼接两个图像的数据(Mat),该两个图像的类型必须是相同的类型,如:均为CvType.CV_8UC3类型 |
||||
|
* @author bailichun |
||||
|
* @since 2020.02.20 15:00 |
||||
|
* @param m1 要合并的图像1(左图) |
||||
|
* @param m2 要合并的图像2(右图) |
||||
|
* @return 拼接好的Mat图像数据集。其高度等于两个图像中高度较大者的高度;其宽度等于两个图像的宽度之和。类型与两个输入图像相同。 |
||||
|
* @throws Exception 当两个图像数据的类型不同时,抛出异常 |
||||
|
*/ |
||||
|
public static Mat concat(Mat m1, Mat m2){ |
||||
|
if(m1.type() != m2.type()){ |
||||
|
throw new RuntimeException("concat:两个图像数据的类型不同!"); |
||||
|
} |
||||
|
long time = System.currentTimeMillis(); |
||||
|
//宽度为两图的宽度之和
|
||||
|
double w = m1.size().width + m2.size().width; |
||||
|
//高度取两个矩阵中的较大者的高度
|
||||
|
double h = m1.size().height > m2.size().height ? m1.size().height : m2.size().height; |
||||
|
//创建一个大矩阵对象
|
||||
|
Mat des = Mat.zeros((int)h, (int)w, m1.type()); |
||||
|
//在最终的大图上标记一块区域,用于存放复制图1(左图)的数据,大小为从第0列到m1.cols()列
|
||||
|
Mat rectForM1 = des.colRange(new Range(0, m1.cols())); |
||||
|
//标记出位于rectForM1的垂直方向上中间位置的区域,高度为图1的高度,此时该区域的大小已经和图1的大小相同。(用于存放复制图1(左图)的数据)
|
||||
|
int rowOffset1 = (int)(rectForM1.size().height-m1.rows())/2; |
||||
|
rectForM1 = rectForM1.rowRange(rowOffset1, rowOffset1 + m1.rows()); |
||||
|
//在最终的大图上标记一块区域,用于存放复制图2(右图)的数据
|
||||
|
Mat rectForM2 = des.colRange(new Range(m1.cols(), des.cols())); |
||||
|
//标记出位于rectForM2的垂直方向上中间位置的区域,高度为图2的高度,此时该区域的大小已经和图2的大小相同。(用于存放复制图2(右图)的数据)
|
||||
|
int rowOffset2 = (int)(rectForM2.size().height-m2.rows())/2; |
||||
|
rectForM2 = rectForM2.rowRange(rowOffset2, rowOffset2 + m2.rows()); |
||||
|
//将图1拷贝到des的指定区域 rectForM1
|
||||
|
m1.copyTo(rectForM1); |
||||
|
//将图2拷贝到des的指定区域 rectForM2
|
||||
|
m2.copyTo(rectForM2); |
||||
|
return des; |
||||
|
} |
||||
|
|
||||
|
} |
After Width: | Height: | Size: 107 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 40 KiB |
After Width: | Height: | Size: 390 KiB |
After Width: | Height: | Size: 47 KiB |
After Width: | Height: | Size: 64 KiB |
After Width: | Height: | Size: 671 KiB |
After Width: | Height: | Size: 328 KiB |
After Width: | Height: | Size: 382 KiB |
After Width: | Height: | Size: 85 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 999 KiB |
After Width: | Height: | Size: 34 KiB |
After Width: | Height: | Size: 400 KiB |