Browse Source

init

master
diven 2 years ago
parent
commit
7eb1264e0b
  1. 30
      open-anpr-client/pom.xml
  2. 47
      open-anpr-client/src/main/java/com/visual/open/anpr/PlateRecognition.java
  3. 12
      open-anpr-client/src/main/java/com/visual/open/anpr/common/Api.java
  4. 63
      open-anpr-client/src/main/java/com/visual/open/anpr/handle/RecognitionHandler.java
  5. 207
      open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClient.java
  6. 4
      open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClientResult.java
  7. 455
      open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClientUtils.java
  8. 17
      open-anpr-client/src/main/java/com/visual/open/anpr/model/MapParam.java
  9. 31
      open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateColor.java
  10. 8
      open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateLayout.java
  11. 66
      open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateLocation.java
  12. 40
      open-anpr-client/src/main/java/com/visual/open/anpr/model/Recognition.java
  13. 36
      open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionInfo.java
  14. 40
      open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionRep.java
  15. 13
      open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionReq.java
  16. 62
      open-anpr-client/src/main/java/com/visual/open/anpr/model/Response.java
  17. 48
      open-anpr-client/src/main/java/com/visual/open/anpr/utils/Base64Util.java
  18. 128
      open-anpr-client/src/main/java/com/visual/open/anpr/utils/JsonUtil.java
  19. 38
      open-anpr-server/src/main/java/com/visual/open/anpr/server/domain/extend/LocationPoint.java
  20. 102
      open-anpr-server/src/main/java/com/visual/open/anpr/server/domain/extend/PlateLocation.java
  21. 19
      open-anpr-server/src/main/java/com/visual/open/anpr/server/service/impl/PlateServiceImpl.java
  22. 32
      open-anpr-test/pom.xml
  23. 65
      open-anpr-test/src/main/java/com/visual/open/anpr/exps/PlateRecognitionExample.java
  24. 124
      open-anpr-test/src/main/java/com/visual/open/anpr/utils/DrawImage.java
  25. 107
      open-anpr-test/src/main/java/com/visual/open/anpr/utils/MatUtil.java
  26. BIN
      open-anpr-test/src/main/resources/image/image001.jpg
  27. BIN
      open-anpr-test/src/main/resources/image/image002.jpg
  28. BIN
      open-anpr-test/src/main/resources/image/image003.jpg
  29. BIN
      open-anpr-test/src/main/resources/image/image004.jpg
  30. BIN
      open-anpr-test/src/main/resources/image/image005.jpg
  31. BIN
      open-anpr-test/src/main/resources/image/image006.jpg
  32. BIN
      open-anpr-test/src/main/resources/image/image007.png
  33. BIN
      open-anpr-test/src/main/resources/image/image008.png
  34. BIN
      open-anpr-test/src/main/resources/image/image009.jpg
  35. BIN
      open-anpr-test/src/main/resources/image/image010.jpg
  36. BIN
      open-anpr-test/src/main/resources/image/image011.jpg
  37. BIN
      open-anpr-test/src/main/resources/image/image012.jpg
  38. BIN
      open-anpr-test/src/main/resources/image/image013.jpg
  39. BIN
      open-anpr-test/src/main/resources/image/image014.png
  40. 12
      pom.xml

30
open-anpr-client/pom.xml

@ -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>

47
open-anpr-client/src/main/java/com/visual/open/anpr/PlateRecognition.java

@ -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);
}
}

12
open-anpr-client/src/main/java/com/visual/open/anpr/common/Api.java

@ -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;
}
}

63
open-anpr-client/src/main/java/com/visual/open/anpr/handle/RecognitionHandler.java

@ -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>>>() {});
}
}

207
open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClient.java

@ -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);
}
}
}

4
open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClientResult.java

@ -0,0 +1,4 @@
package com.visual.open.anpr.http;
public class HttpClientResult {
}

455
open-anpr-client/src/main/java/com/visual/open/anpr/http/HttpClientUtils.java

@ -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();
}
}
}
}

17
open-anpr-client/src/main/java/com/visual/open/anpr/model/MapParam.java

@ -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;
}
}

31
open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateColor.java

@ -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;
}
}

8
open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateLayout.java

@ -0,0 +1,8 @@
package com.visual.open.anpr.model;
public enum PlateLayout {
SINGLE, //单排
DOUBLE, //双排
UNKNOWN; //未知
}

66
open-anpr-client/src/main/java/com/visual/open/anpr/model/PlateLocation.java

@ -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;
}
}

40
open-anpr-client/src/main/java/com/visual/open/anpr/model/Recognition.java

@ -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;
}
}

36
open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionInfo.java

@ -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;
}
}

40
open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionRep.java

@ -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;
}
}

13
open-anpr-client/src/main/java/com/visual/open/anpr/model/RecognitionReq.java

@ -0,0 +1,13 @@
package com.visual.open.anpr.model;
public class RecognitionReq extends Recognition<RecognitionReq>{
/**
* 构建比对对象
* @return
*/
public static RecognitionReq build(){
return new RecognitionReq();
}
}

62
open-anpr-client/src/main/java/com/visual/open/anpr/model/Response.java

@ -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 + '}';
}
}

48
open-anpr-client/src/main/java/com/visual/open/anpr/utils/Base64Util.java

@ -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);
}
}
}

128
open-anpr-client/src/main/java/com/visual/open/anpr/utils/JsonUtil.java

@ -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);
}
}

38
open-anpr-server/src/main/java/com/visual/open/anpr/server/domain/extend/LocationPoint.java

@ -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;
}
}

102
open-anpr-server/src/main/java/com/visual/open/anpr/server/domain/extend/PlateLocation.java

@ -5,68 +5,82 @@ import io.swagger.annotations.ApiModelProperty;
import java.io.Serializable; import java.io.Serializable;
public class PlateLocation implements Serializable { public class PlateLocation implements Serializable {
/**左上角x坐标**/
@ApiModelProperty(value="左上角x坐标", position = 1, required = true)
private int x;
/**左上角y坐标**/
@ApiModelProperty(value="左上角y坐标", position = 2, required = true)
private int y;
/**宽度**/
@ApiModelProperty(value="车牌宽度", position = 3, required = true)
private int w;
/**高度**/
@ApiModelProperty(value="车牌高度", position = 4, required = true)
private int h;
/** /**左上角坐标值**/
* 构建坐标 @ApiModelProperty(value="左上角坐标值", position = 1, required = true)
* @param x private LocationPoint leftTop;
* @param y /**右上角坐标**/
* @param w @ApiModelProperty(value="右上角坐标", position = 2, required = true)
* @param h private LocationPoint rightTop;
* @return /**右下角坐标**/
*/ @ApiModelProperty(value="右下角坐标", position = 3, required = true)
public static PlateLocation build(int x, int y, int w, int h){ private LocationPoint rightBottom;
return new PlateLocation().setX(x).setY(y).setW(w).setH(h); /**左下角坐标**/
@ApiModelProperty(value="左下角坐标", position = 4, required = true)
private LocationPoint leftBottom;
public LocationPoint getLeftTop() {
return leftTop;
} }
public static PlateLocation build(float x, float y, float w, float h){ public void setLeftTop(LocationPoint leftTop) {
return new PlateLocation().setX((int) x).setY((int) y).setW((int) w).setH((int) h); this.leftTop = leftTop;
} }
public int getX() { public LocationPoint getRightTop() {
return x; return rightTop;
} }
public PlateLocation setX(int x) { public void setRightTop(LocationPoint rightTop) {
this.x = x; this.rightTop = rightTop;
return this;
} }
public int getY() { public LocationPoint getRightBottom() {
return y; return rightBottom;
} }
public PlateLocation setY(int y) { public void setRightBottom(LocationPoint rightBottom) {
this.y = y; this.rightBottom = rightBottom;
return this;
} }
public int getW() { public LocationPoint getLeftBottom() {
return w; return leftBottom;
} }
public PlateLocation setW(int w) { public void setLeftBottom(LocationPoint leftBottom) {
this.w = w; this.leftBottom = leftBottom;
return this;
} }
public int getH() {
return h; /**
* x的最小坐标
* @return
*/
public int minX(){
return Math.min(Math.min(Math.min(leftTop.getX(), rightTop.getX()), rightBottom.getX()), leftBottom.getX());
} }
public PlateLocation setH(int h) { /**
this.h = h; * y的最小坐标
return this; * @return
*/
public int minY(){
return Math.min(Math.min(Math.min(leftTop.getY(), rightTop.getY()), rightBottom.getY()), leftBottom.getY());
}
/**
* x的最大坐标
* @return
*/
public int maxX(){
return Math.max(Math.max(Math.max(leftTop.getX(), rightTop.getX()), rightBottom.getX()), leftBottom.getX());
}
/**
* y的最大坐标
* @return
*/
public int maxY(){
return Math.max(Math.max(Math.max(leftTop.getY(), rightTop.getY()), rightBottom.getY()), leftBottom.getY());
} }
} }

19
open-anpr-server/src/main/java/com/visual/open/anpr/server/service/impl/PlateServiceImpl.java

@ -5,10 +5,7 @@ import com.visual.open.anpr.core.domain.ImageMat;
import com.visual.open.anpr.core.domain.PlateImage; import com.visual.open.anpr.core.domain.PlateImage;
import com.visual.open.anpr.core.domain.PlateInfo; import com.visual.open.anpr.core.domain.PlateInfo;
import com.visual.open.anpr.core.extract.PlateExtractor; import com.visual.open.anpr.core.extract.PlateExtractor;
import com.visual.open.anpr.server.domain.extend.PlateColor; import com.visual.open.anpr.server.domain.extend.*;
import com.visual.open.anpr.server.domain.extend.PlateLayout;
import com.visual.open.anpr.server.domain.extend.PlateLocation;
import com.visual.open.anpr.server.domain.extend.RecognitionInfo;
import com.visual.open.anpr.server.domain.request.PlateInfoReqVo; import com.visual.open.anpr.server.domain.request.PlateInfoReqVo;
import com.visual.open.anpr.server.domain.response.PlateInfoRepVo; import com.visual.open.anpr.server.domain.response.PlateInfoRepVo;
import com.visual.open.anpr.server.service.api.PlateService; import com.visual.open.anpr.server.service.api.PlateService;
@ -44,21 +41,19 @@ public class PlateServiceImpl implements PlateService {
throw new RuntimeException("PlateExtractor extract error"); throw new RuntimeException("PlateExtractor extract error");
} }
//转换模型结果,并输出 //转换模型结果,并输出
System.out.println(plateImage.PlateInfos().size());
List<PlateInfoRepVo> plates = new ArrayList<>(); List<PlateInfoRepVo> plates = new ArrayList<>();
if(null != plateImage.PlateInfos() && !plateImage.PlateInfos().isEmpty()){ if(null != plateImage.PlateInfos() && !plateImage.PlateInfos().isEmpty()){
for(PlateInfo plateInfo : plateImage.PlateInfos()){ for(PlateInfo plateInfo : plateImage.PlateInfos()){
//检测信息 //检测信息
PlateInfoRepVo plate = new PlateInfoRepVo(); PlateInfoRepVo plate = new PlateInfoRepVo();
plate.setScore((float)Math.floor(plateInfo.score * 1000000)/10000); plate.setScore((float)Math.floor(plateInfo.score * 1000000)/10000);
PlateLocation location = PlateLocation.build( PlateLocation location = new PlateLocation();
plateInfo.box.x1(), location.setLeftTop(new LocationPoint(plateInfo.box.leftTop.x, plateInfo.box.leftTop.y));
plateInfo.box.y1(), location.setRightTop(new LocationPoint(plateInfo.box.rightTop.x, plateInfo.box.rightTop.y));
plateInfo.box.x2()-plateInfo.box.x1(), location.setRightBottom(new LocationPoint(plateInfo.box.rightBottom.x, plateInfo.box.rightBottom.y));
plateInfo.box.y2()-plateInfo.box.y1() location.setLeftBottom(new LocationPoint(plateInfo.box.leftBottom.x, plateInfo.box.leftBottom.y));
);
plate.setLocation(location); plate.setLocation(location);
//识别信息 //识别信息
RecognitionInfo recognition = new RecognitionInfo(); RecognitionInfo recognition = new RecognitionInfo();
recognition.setLayout(plateInfo.single ? PlateLayout.SINGLE : PlateLayout.DOUBLE); recognition.setLayout(plateInfo.single ? PlateLayout.SINGLE : PlateLayout.DOUBLE);

32
open-anpr-test/pom.xml

@ -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>

65
open-anpr-test/src/main/java/com/visual/open/anpr/exps/PlateRecognitionExample.java

@ -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();
}
}

124
open-anpr-test/src/main/java/com/visual/open/anpr/utils/DrawImage.java

@ -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;
}
}
}

107
open-anpr-test/src/main/java/com/visual/open/anpr/utils/MatUtil.java

@ -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;
}
}

BIN
open-anpr-test/src/main/resources/image/image001.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 107 KiB

BIN
open-anpr-test/src/main/resources/image/image002.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
open-anpr-test/src/main/resources/image/image003.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

BIN
open-anpr-test/src/main/resources/image/image004.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 390 KiB

BIN
open-anpr-test/src/main/resources/image/image005.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

BIN
open-anpr-test/src/main/resources/image/image006.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 64 KiB

BIN
open-anpr-test/src/main/resources/image/image007.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 671 KiB

BIN
open-anpr-test/src/main/resources/image/image008.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

BIN
open-anpr-test/src/main/resources/image/image009.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 KiB

BIN
open-anpr-test/src/main/resources/image/image010.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

BIN
open-anpr-test/src/main/resources/image/image011.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 29 KiB

BIN
open-anpr-test/src/main/resources/image/image012.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 999 KiB

BIN
open-anpr-test/src/main/resources/image/image013.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 34 KiB

BIN
open-anpr-test/src/main/resources/image/image014.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 400 KiB

12
pom.xml

@ -19,6 +19,8 @@
<modules> <modules>
<module>open-anpr-core</module> <module>open-anpr-core</module>
<module>open-anpr-server</module> <module>open-anpr-server</module>
<module>open-anpr-test</module>
<module>open-anpr-client</module>
</modules> </modules>
<properties> <properties>
@ -41,6 +43,16 @@
<artifactId>open-anpr-core</artifactId> <artifactId>open-anpr-core</artifactId>
<version>${project.version}</version> <version>${project.version}</version>
</dependency> </dependency>
<dependency>
<groupId>com.visual.open.anpr</groupId>
<artifactId>open-anpr-server</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.visual.open.anpr</groupId>
<artifactId>open-anpr-client</artifactId>
<version>${project.version}</version>
</dependency>
<dependency> <dependency>
<groupId>org.openpnp</groupId> <groupId>org.openpnp</groupId>

Loading…
Cancel
Save