update site link and renew iocr.
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### 动物分类识别SDK
|
### 动物分类识别SDK
|
||||||
动物识别sdk,支持7978种动物的分类识别。
|
动物识别sdk,支持7978种动物的分类识别。
|
||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
@ -48,12 +48,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 菜品分类识别SDK
|
### 菜品分类识别SDK
|
||||||
@ -39,7 +39,7 @@
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
@ -47,12 +47,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 特征提取(512维)SDK
|
### 特征提取(512维)SDK
|
||||||
@ -93,7 +93,7 @@ sm.save("models/clip-ViT-B-32/clip-ViT-B-32.pt")
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
@ -103,12 +103,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### BIGGAN 图像自动生成SDK
|
### BIGGAN 图像自动生成SDK
|
||||||
@ -118,7 +118,7 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
@ -126,12 +126,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### 动作驱动 SDK
|
### 动作驱动 SDK
|
||||||
### 不得用于非法用途!
|
### 不得用于非法用途!
|
||||||
@ -43,7 +43,7 @@ build/output/result.gif
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
@ -55,12 +55,12 @@ https://gitee.com/endlesshh/first-order-model-java
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### 风格迁移(预定义4种)SDK
|
### 风格迁移(预定义4种)SDK
|
||||||
风格迁移可以把一张图片转换成另一种风格。本sdk预定义了4种画风:
|
风格迁移可以把一张图片转换成另一种风格。本sdk预定义了4种画风:
|
||||||
@ -38,7 +38,7 @@
|
|||||||
#### 找不到了,后面会有更好的替换
|
#### 找不到了,后面会有更好的替换
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
@ -47,12 +47,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### 超分辨(4倍)SDK
|
### 超分辨(4倍)SDK
|
||||||
提升图片4倍分辨率。
|
提升图片4倍分辨率。
|
||||||
@ -32,12 +32,12 @@
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
## 目录:
|
## 目录:
|
||||||
http://aias.top/
|
https://aias.top/
|
||||||
|
|
||||||
# 图像预处理SDK
|
# 图像预处理SDK
|
||||||
在OCR文字识别的时候,我们得到的图像一般情况下都不是正的,多少都会有一定的倾斜。
|
在OCR文字识别的时候,我们得到的图像一般情况下都不是正的,多少都会有一定的倾斜。
|
||||||
@ -31,10 +31,10 @@ height = 753
|
|||||||
|
|
||||||
### 帮助
|
### 帮助
|
||||||
引擎定制化配置,可以提升首次运行的引擎下载速度,解决外网无法访问或者带宽过低的问题。
|
引擎定制化配置,可以提升首次运行的引擎下载速度,解决外网无法访问或者带宽过低的问题。
|
||||||
[引擎定制化配置](http://aias.top/engine_cpu.html)
|
[引擎定制化配置](https://aias.top/engine_cpu.html)
|
||||||
|
|
||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 人脸对齐 SDK
|
### 人脸对齐 SDK
|
||||||
@ -46,7 +46,7 @@
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
@ -56,12 +56,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 人脸检测SDK
|
### 人脸检测SDK
|
||||||
@ -54,7 +54,7 @@
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
@ -63,12 +63,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 行人检测SDK
|
### 行人检测SDK
|
||||||
@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
|
|
||||||
### 其它帮助信息
|
### 其它帮助信息
|
||||||
http://aias.top/guides.html
|
https://aias.top/guides.html
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
@ -44,12 +44,12 @@ http://aias.top/guides.html
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -20,7 +20,7 @@ import java.nio.file.Paths;
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* 行人检测例子
|
* 行人检测例子
|
||||||
* http://aias.top/
|
* https://aias.top/
|
||||||
* @author Calvin
|
* @author Calvin
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
## 文字识别(OCR)工具箱
|
## 文字识别(OCR)工具箱
|
||||||
文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别,
|
文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别,
|
||||||
@ -156,12 +156,12 @@ https://blog.csdn.net/wsp_1138886114/article/details/83374333
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
|
|
||||||
### 声纹识别
|
### 声纹识别
|
||||||
@ -118,12 +118,12 @@ if __name__ == '__main__':
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
@ -1,5 +1,5 @@
|
|||||||
### 目录:
|
### 目录:
|
||||||
http://aias.top/
|
https://aias.top/
|
||||||
|
|
||||||
|
|
||||||
### 人脸大数据搜索介绍
|
### 人脸大数据搜索介绍
|
||||||
@ -130,7 +130,7 @@ me.calvin.modules.search.tools.MilvusInit.java
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 官网:
|
### 官网:
|
||||||
[官网链接](http://www.aias.top/)
|
[官网链接](https://www.aias.top/)
|
||||||
|
|
||||||
### Git地址:
|
### Git地址:
|
||||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||||
@ -138,12 +138,12 @@ me.calvin.modules.search.tools.MilvusInit.java
|
|||||||
|
|
||||||
|
|
||||||
#### 帮助文档:
|
#### 帮助文档:
|
||||||
- http://aias.top/guides.html
|
- https://aias.top/guides.html
|
||||||
- 1.性能优化常见问题:
|
- 1.性能优化常见问题:
|
||||||
- http://aias.top/AIAS/guides/performance.html
|
- https://aias.top/AIAS/guides/performance.html
|
||||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/engine_config.html
|
- https://aias.top/AIAS/guides/engine_config.html
|
||||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||||
- http://aias.top/AIAS/guides/load_model.html
|
- https://aias.top/AIAS/guides/load_model.html
|
||||||
- 4.Windows环境常见问题:
|
- 4.Windows环境常见问题:
|
||||||
- http://aias.top/AIAS/guides/windows.html
|
- https://aias.top/AIAS/guides/windows.html
|
||||||
|
BIN
8_suite_hub/iocr/ocr-demo/build/opencv/perspective.png
Normal file
After Width: | Height: | Size: 1.3 MiB |
BIN
8_suite_hub/iocr/ocr-demo/build/opencv/result.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
After Width: | Height: | Size: 856 KiB |
BIN
8_suite_hub/iocr/ocr-demo/file/points_result.png
Normal file
After Width: | Height: | Size: 980 KiB |
@ -0,0 +1 @@
|
|||||||
|
<table><thead><tr><td>Methods</td><td>R</td><td>P</td><td>F</td><td>FPS</td></tr></thead><tbody><tr><td>SegLink[26]</td><td>70.0</td><td>86.0</td><td>770</td><td>89</td></tr><tr><td>PixelLink[4j</td><td>73.2</td><td>83.0</td><td>77.8</td><td></td></tr><tr><td>TextSnake18]</td><td>73.9</td><td>83.2</td><td>78.3</td><td>1.1</td></tr><tr><td>TextField[37]</td><td>75.9</td><td>87.4</td><td>81.3</td><td>36</td></tr><tr><td>MSR38]</td><td>76.7</td><td>87.4</td><td>81.7</td><td></td></tr><tr><td>FTSN3]</td><td>77.1</td><td>87.6</td><td>82.0</td><td></td></tr><tr><td>LSE[30]</td><td>81.7</td><td>84.2</td><td>82.9</td><td>一</td></tr><tr><td>CRAFT[2]</td><td>78.2</td><td>88.2</td><td>82.9</td><td>8.6</td></tr><tr><td>MCNJ161</td><td>79</td><td>88</td><td>83</td><td></td></tr><tr><td>ATRR[35]</td><td>82.1</td><td>85.2</td><td>83.6</td><td></td></tr><tr><td>PAN[34]</td><td>83.8</td><td>84.4</td><td>84.1</td><td>30.2</td></tr><tr><td>DB[12]</td><td>79.2</td><td>91.5</td><td>84.9</td><td>32.0</td></tr><tr><td>DRRG141]</td><td>82.30</td><td>88.05</td><td>85.08</td><td></td></tr><tr><td>Ours(SynText)</td><td>80.68</td><td>85.40</td><td>82.97</td><td>12.68</td></tr><tr><td>Ours(MLT-17)</td><td>84.54</td><td>86.62</td><td>85.57</td><td>12.31</td></tr></tbody></table>
|
7
8_suite_hub/iocr/ocr-demo/file/templates.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
[
|
||||||
|
{
|
||||||
|
"uid": "39e6200133bb4755a737fc97cbe188e6",
|
||||||
|
"name": "test",
|
||||||
|
"imageName": "7442ff603d1042d995a64bbcfeb1b1fc.png"
|
||||||
|
}
|
||||||
|
]
|
@ -0,0 +1,130 @@
|
|||||||
|
{
|
||||||
|
"uid": "39e6200133bb4755a737fc97cbe188e6",
|
||||||
|
"name": "test",
|
||||||
|
"imageName": "7442ff603d1042d995a64bbcfeb1b1fc.png",
|
||||||
|
"labelData": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"active": 0,
|
||||||
|
"type": "anchor",
|
||||||
|
"value": "限乘当日当次车",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"x": 308,
|
||||||
|
"y": 558
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 688,
|
||||||
|
"y": 558
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 688,
|
||||||
|
"y": 638
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 308,
|
||||||
|
"y": 638
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 1,
|
||||||
|
"active": 0,
|
||||||
|
"type": "anchor",
|
||||||
|
"value": "中国铁路祝您旅途愉快",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"x": 515,
|
||||||
|
"y": 825
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 998,
|
||||||
|
"y": 825
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 998,
|
||||||
|
"y": 883
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 515,
|
||||||
|
"y": 883
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 2,
|
||||||
|
"active": 0,
|
||||||
|
"type": "rectangle",
|
||||||
|
"value": "南昌站",
|
||||||
|
"field": "start",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"x": 340,
|
||||||
|
"y": 283
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 695,
|
||||||
|
"y": 283
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 695,
|
||||||
|
"y": 378
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 340,
|
||||||
|
"y": 378
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 3,
|
||||||
|
"active": 0,
|
||||||
|
"type": "rectangle",
|
||||||
|
"value": "D6262",
|
||||||
|
"field": "ticket",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"x": 773,
|
||||||
|
"y": 285
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1013,
|
||||||
|
"y": 285
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1013,
|
||||||
|
"y": 375
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 773,
|
||||||
|
"y": 375
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"index": 4,
|
||||||
|
"active": 0,
|
||||||
|
"type": "rectangle",
|
||||||
|
"value": "九江站",
|
||||||
|
"field": "end",
|
||||||
|
"points": [
|
||||||
|
{
|
||||||
|
"x": 1073,
|
||||||
|
"y": 280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1423,
|
||||||
|
"y": 280
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1423,
|
||||||
|
"y": 373
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"x": 1073,
|
||||||
|
"y": 373
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
293
8_suite_hub/iocr/ocr-demo/iocr-demo.iml
Normal file
@ -0,0 +1,293 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="CheckStyle-IDEA-Module">
|
||||||
|
<option name="configuration">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
<facet type="web" name="Web">
|
||||||
|
<configuration>
|
||||||
|
<webroots />
|
||||||
|
<sourceRoots>
|
||||||
|
<root url="file://$MODULE_DIR$/src/main/java" />
|
||||||
|
<root url="file://$MODULE_DIR$/src/main/resources" />
|
||||||
|
</sourceRoots>
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-logging:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-classic:1.2.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ch.qos.logback:logback-core:1.2.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-to-slf4j:2.11.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:jul-to-slf4j:1.7.28" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.9.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.17.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.4" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.16" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.16" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.2.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.28" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.15.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.logging.log4j:log4j-core:2.11.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:api:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:basicdataset:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:model-zoo:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.mxnet:mxnet-engine:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.mxnet:mxnet-native-auto:1.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:5.6.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-engine:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-native-auto:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-model-zoo:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacv-platform:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacv:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-armhf:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-ppc64le:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv-platform:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-armhf:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-ppc64le:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:macosx-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg-platform:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-armhf:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-arm64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-ppc64le:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:macosx-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture-platform:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86_64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-armhf:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-arm64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86_64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394-platform:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-armhf:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-arm64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-ppc64le:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:macosx-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect-platform:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-armhf:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-arm64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-ppc64le:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:macosx-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2-platform:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:macosx-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:windows-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense-platform:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:macosx-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput-platform:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86_64:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus-platform:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-armhf:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-arm64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-ppc64le:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:macosx-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark-platform:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-armhf:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-arm64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-ppc64le:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:macosx-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica-platform:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-armhf:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-arm64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-ppc64le:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:macosx-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract-platform:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-armhf:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-ppc64le:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:macosx-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: gov.nist.math:jama:1.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client:1.19.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.10" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.70" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-starter:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-annotations:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-core:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-ui:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
286
8_suite_hub/iocr/ocr-demo/mvnw
vendored
Normal file
@ -0,0 +1,286 @@
|
|||||||
|
#!/bin/sh
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
# or more contributor license agreements. See the NOTICE file
|
||||||
|
# distributed with this work for additional information
|
||||||
|
# regarding copyright ownership. The ASF licenses this file
|
||||||
|
# to you under the Apache License, Version 2.0 (the
|
||||||
|
# "License"); you may not use this file except in compliance
|
||||||
|
# with the License. You may obtain a copy of the License at
|
||||||
|
#
|
||||||
|
# http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
#
|
||||||
|
# Unless required by applicable law or agreed to in writing,
|
||||||
|
# software distributed under the License is distributed on an
|
||||||
|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
# KIND, either express or implied. See the License for the
|
||||||
|
# specific language governing permissions and limitations
|
||||||
|
# under the License.
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
# Maven2 Start Up Batch script
|
||||||
|
#
|
||||||
|
# Required ENV vars:
|
||||||
|
# ------------------
|
||||||
|
# JAVA_HOME - location of a JDK home dir
|
||||||
|
#
|
||||||
|
# Optional ENV vars
|
||||||
|
# -----------------
|
||||||
|
# M2_HOME - location of maven2's installed home dir
|
||||||
|
# MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
# e.g. to debug Maven itself, use
|
||||||
|
# set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
# MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
if [ -z "$MAVEN_SKIP_RC" ] ; then
|
||||||
|
|
||||||
|
if [ -f /etc/mavenrc ] ; then
|
||||||
|
. /etc/mavenrc
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -f "$HOME/.mavenrc" ] ; then
|
||||||
|
. "$HOME/.mavenrc"
|
||||||
|
fi
|
||||||
|
|
||||||
|
fi
|
||||||
|
|
||||||
|
# OS specific support. $var _must_ be set to either true or false.
|
||||||
|
cygwin=false;
|
||||||
|
darwin=false;
|
||||||
|
mingw=false
|
||||||
|
case "`uname`" in
|
||||||
|
CYGWIN*) cygwin=true ;;
|
||||||
|
MINGW*) mingw=true;;
|
||||||
|
Darwin*) darwin=true
|
||||||
|
# Use /usr/libexec/java_home if available, otherwise fall back to /Library/Java/Home
|
||||||
|
# See https://developer.apple.com/library/mac/qa/qa1170/_index.html
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
if [ -x "/usr/libexec/java_home" ]; then
|
||||||
|
export JAVA_HOME="`/usr/libexec/java_home`"
|
||||||
|
else
|
||||||
|
export JAVA_HOME="/Library/Java/Home"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
if [ -r /etc/gentoo-release ] ; then
|
||||||
|
JAVA_HOME=`java-config --jre-home`
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$M2_HOME" ] ; then
|
||||||
|
## resolve links - $0 may be a link to maven's home
|
||||||
|
PRG="$0"
|
||||||
|
|
||||||
|
# need this for relative symlinks
|
||||||
|
while [ -h "$PRG" ] ; do
|
||||||
|
ls=`ls -ld "$PRG"`
|
||||||
|
link=`expr "$ls" : '.*-> \(.*\)$'`
|
||||||
|
if expr "$link" : '/.*' > /dev/null; then
|
||||||
|
PRG="$link"
|
||||||
|
else
|
||||||
|
PRG="`dirname "$PRG"`/$link"
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
saveddir=`pwd`
|
||||||
|
|
||||||
|
M2_HOME=`dirname "$PRG"`/..
|
||||||
|
|
||||||
|
# make it fully qualified
|
||||||
|
M2_HOME=`cd "$M2_HOME" && pwd`
|
||||||
|
|
||||||
|
cd "$saveddir"
|
||||||
|
# echo Using m2 at $M2_HOME
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Cygwin, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $cygwin ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --unix "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --unix "$CLASSPATH"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
# For Mingw, ensure paths are in UNIX format before anything is touched
|
||||||
|
if $mingw ; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME="`(cd "$M2_HOME"; pwd)`"
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME="`(cd "$JAVA_HOME"; pwd)`"
|
||||||
|
# TODO classpath?
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ]; then
|
||||||
|
javaExecutable="`which javac`"
|
||||||
|
if [ -n "$javaExecutable" ] && ! [ "`expr \"$javaExecutable\" : '\([^ ]*\)'`" = "no" ]; then
|
||||||
|
# readlink(1) is not available as standard on Solaris 10.
|
||||||
|
readLink=`which readlink`
|
||||||
|
if [ ! `expr "$readLink" : '\([^ ]*\)'` = "no" ]; then
|
||||||
|
if $darwin ; then
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaExecutable="`cd \"$javaHome\" && pwd -P`/javac"
|
||||||
|
else
|
||||||
|
javaExecutable="`readlink -f \"$javaExecutable\"`"
|
||||||
|
fi
|
||||||
|
javaHome="`dirname \"$javaExecutable\"`"
|
||||||
|
javaHome=`expr "$javaHome" : '\(.*\)/bin'`
|
||||||
|
JAVA_HOME="$javaHome"
|
||||||
|
export JAVA_HOME
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVACMD" ] ; then
|
||||||
|
if [ -n "$JAVA_HOME" ] ; then
|
||||||
|
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
|
||||||
|
# IBM's JDK on AIX uses strange locations for the executables
|
||||||
|
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||||
|
else
|
||||||
|
JAVACMD="$JAVA_HOME/bin/java"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
JAVACMD="`which java`"
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ ! -x "$JAVACMD" ] ; then
|
||||||
|
echo "Error: JAVA_HOME is not defined correctly." >&2
|
||||||
|
echo " We cannot execute $JAVACMD" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if [ -z "$JAVA_HOME" ] ; then
|
||||||
|
echo "Warning: JAVA_HOME environment variable is not set."
|
||||||
|
fi
|
||||||
|
|
||||||
|
CLASSWORLDS_LAUNCHER=org.codehaus.plexus.classworlds.launcher.Launcher
|
||||||
|
|
||||||
|
# traverses directory structure from process work directory to filesystem root
|
||||||
|
# first directory with .mvn subdirectory is considered project base directory
|
||||||
|
find_maven_basedir() {
|
||||||
|
|
||||||
|
if [ -z "$1" ]
|
||||||
|
then
|
||||||
|
echo "Path not specified to find_maven_basedir"
|
||||||
|
return 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
basedir="$1"
|
||||||
|
wdir="$1"
|
||||||
|
while [ "$wdir" != '/' ] ; do
|
||||||
|
if [ -d "$wdir"/.mvn ] ; then
|
||||||
|
basedir=$wdir
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
# workaround for JBEAP-8937 (on Solaris 10/Sparc)
|
||||||
|
if [ -d "${wdir}" ]; then
|
||||||
|
wdir=`cd "$wdir/.."; pwd`
|
||||||
|
fi
|
||||||
|
# end of workaround
|
||||||
|
done
|
||||||
|
echo "${basedir}"
|
||||||
|
}
|
||||||
|
|
||||||
|
# concatenates all lines of a file
|
||||||
|
concat_lines() {
|
||||||
|
if [ -f "$1" ]; then
|
||||||
|
echo "$(tr -s '\n' ' ' < "$1")"
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
BASE_DIR=`find_maven_basedir "$(pwd)"`
|
||||||
|
if [ -z "$BASE_DIR" ]; then
|
||||||
|
exit 1;
|
||||||
|
fi
|
||||||
|
|
||||||
|
##########################################################################################
|
||||||
|
# Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
# This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
##########################################################################################
|
||||||
|
if [ -r "$BASE_DIR/.mvn/wrapper/maven-wrapper.jar" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found .mvn/wrapper/maven-wrapper.jar"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Couldn't find .mvn/wrapper/maven-wrapper.jar, downloading it ..."
|
||||||
|
fi
|
||||||
|
jarUrl="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
while IFS="=" read key value; do
|
||||||
|
case "$key" in (wrapperUrl) jarUrl="$value"; break ;;
|
||||||
|
esac
|
||||||
|
done < "$BASE_DIR/.mvn/wrapper/maven-wrapper.properties"
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Downloading from: $jarUrl"
|
||||||
|
fi
|
||||||
|
wrapperJarPath="$BASE_DIR/.mvn/wrapper/maven-wrapper.jar"
|
||||||
|
|
||||||
|
if command -v wget > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found wget ... using wget"
|
||||||
|
fi
|
||||||
|
wget "$jarUrl" -O "$wrapperJarPath"
|
||||||
|
elif command -v curl > /dev/null; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Found curl ... using curl"
|
||||||
|
fi
|
||||||
|
curl -o "$wrapperJarPath" "$jarUrl"
|
||||||
|
else
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo "Falling back to using Java to download"
|
||||||
|
fi
|
||||||
|
javaClass="$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.java"
|
||||||
|
if [ -e "$javaClass" ]; then
|
||||||
|
if [ ! -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Compiling MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
# Compiling the Java class
|
||||||
|
("$JAVA_HOME/bin/javac" "$javaClass")
|
||||||
|
fi
|
||||||
|
if [ -e "$BASE_DIR/.mvn/wrapper/MavenWrapperDownloader.class" ]; then
|
||||||
|
# Running the downloader
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo " - Running MavenWrapperDownloader.java ..."
|
||||||
|
fi
|
||||||
|
("$JAVA_HOME/bin/java" -cp .mvn/wrapper MavenWrapperDownloader "$MAVEN_PROJECTBASEDIR")
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
fi
|
||||||
|
##########################################################################################
|
||||||
|
# End of extension
|
||||||
|
##########################################################################################
|
||||||
|
|
||||||
|
export MAVEN_PROJECTBASEDIR=${MAVEN_BASEDIR:-"$BASE_DIR"}
|
||||||
|
if [ "$MVNW_VERBOSE" = true ]; then
|
||||||
|
echo $MAVEN_PROJECTBASEDIR
|
||||||
|
fi
|
||||||
|
MAVEN_OPTS="$(concat_lines "$MAVEN_PROJECTBASEDIR/.mvn/jvm.config") $MAVEN_OPTS"
|
||||||
|
|
||||||
|
# For Cygwin, switch paths to Windows format before running java
|
||||||
|
if $cygwin; then
|
||||||
|
[ -n "$M2_HOME" ] &&
|
||||||
|
M2_HOME=`cygpath --path --windows "$M2_HOME"`
|
||||||
|
[ -n "$JAVA_HOME" ] &&
|
||||||
|
JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
|
||||||
|
[ -n "$CLASSPATH" ] &&
|
||||||
|
CLASSPATH=`cygpath --path --windows "$CLASSPATH"`
|
||||||
|
[ -n "$MAVEN_PROJECTBASEDIR" ] &&
|
||||||
|
MAVEN_PROJECTBASEDIR=`cygpath --path --windows "$MAVEN_PROJECTBASEDIR"`
|
||||||
|
fi
|
||||||
|
|
||||||
|
WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
exec "$JAVACMD" \
|
||||||
|
$MAVEN_OPTS \
|
||||||
|
-classpath "$MAVEN_PROJECTBASEDIR/.mvn/wrapper/maven-wrapper.jar" \
|
||||||
|
"-Dmaven.home=${M2_HOME}" "-Dmaven.multiModuleProjectDirectory=${MAVEN_PROJECTBASEDIR}" \
|
||||||
|
${WRAPPER_LAUNCHER} $MAVEN_CONFIG "$@"
|
161
8_suite_hub/iocr/ocr-demo/mvnw.cmd
vendored
Normal file
@ -0,0 +1,161 @@
|
|||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Licensed to the Apache Software Foundation (ASF) under one
|
||||||
|
@REM or more contributor license agreements. See the NOTICE file
|
||||||
|
@REM distributed with this work for additional information
|
||||||
|
@REM regarding copyright ownership. The ASF licenses this file
|
||||||
|
@REM to you under the Apache License, Version 2.0 (the
|
||||||
|
@REM "License"); you may not use this file except in compliance
|
||||||
|
@REM with the License. You may obtain a copy of the License at
|
||||||
|
@REM
|
||||||
|
@REM http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
@REM
|
||||||
|
@REM Unless required by applicable law or agreed to in writing,
|
||||||
|
@REM software distributed under the License is distributed on an
|
||||||
|
@REM "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||||
|
@REM KIND, either express or implied. See the License for the
|
||||||
|
@REM specific language governing permissions and limitations
|
||||||
|
@REM under the License.
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
@REM Maven2 Start Up Batch script
|
||||||
|
@REM
|
||||||
|
@REM Required ENV vars:
|
||||||
|
@REM JAVA_HOME - location of a JDK home dir
|
||||||
|
@REM
|
||||||
|
@REM Optional ENV vars
|
||||||
|
@REM M2_HOME - location of maven2's installed home dir
|
||||||
|
@REM MAVEN_BATCH_ECHO - set to 'on' to enable the echoing of the batch commands
|
||||||
|
@REM MAVEN_BATCH_PAUSE - set to 'on' to wait for a key stroke before ending
|
||||||
|
@REM MAVEN_OPTS - parameters passed to the Java VM when running Maven
|
||||||
|
@REM e.g. to debug Maven itself, use
|
||||||
|
@REM set MAVEN_OPTS=-Xdebug -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
|
||||||
|
@REM MAVEN_SKIP_RC - flag to disable loading of mavenrc files
|
||||||
|
@REM ----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
@REM Begin all REM lines with '@' in case MAVEN_BATCH_ECHO is 'on'
|
||||||
|
@echo off
|
||||||
|
@REM set title of command window
|
||||||
|
title %0
|
||||||
|
@REM enable echoing my setting MAVEN_BATCH_ECHO to 'on'
|
||||||
|
@if "%MAVEN_BATCH_ECHO%" == "on" echo %MAVEN_BATCH_ECHO%
|
||||||
|
|
||||||
|
@REM set %HOME% to equivalent of $HOME
|
||||||
|
if "%HOME%" == "" (set "HOME=%HOMEDRIVE%%HOMEPATH%")
|
||||||
|
|
||||||
|
@REM Execute a user defined script before this one
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPre
|
||||||
|
@REM check for pre script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_pre.bat" call "%HOME%\mavenrc_pre.bat"
|
||||||
|
if exist "%HOME%\mavenrc_pre.cmd" call "%HOME%\mavenrc_pre.cmd"
|
||||||
|
:skipRcPre
|
||||||
|
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
set ERROR_CODE=0
|
||||||
|
|
||||||
|
@REM To isolate internal variables from possible post scripts, we use another setlocal
|
||||||
|
@setlocal
|
||||||
|
|
||||||
|
@REM ==== START VALIDATION ====
|
||||||
|
if not "%JAVA_HOME%" == "" goto OkJHome
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME not found in your environment. >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
:OkJHome
|
||||||
|
if exist "%JAVA_HOME%\bin\java.exe" goto init
|
||||||
|
|
||||||
|
echo.
|
||||||
|
echo Error: JAVA_HOME is set to an invalid directory. >&2
|
||||||
|
echo JAVA_HOME = "%JAVA_HOME%" >&2
|
||||||
|
echo Please set the JAVA_HOME variable in your environment to match the >&2
|
||||||
|
echo location of your Java installation. >&2
|
||||||
|
echo.
|
||||||
|
goto error
|
||||||
|
|
||||||
|
@REM ==== END VALIDATION ====
|
||||||
|
|
||||||
|
:init
|
||||||
|
|
||||||
|
@REM Find the project base dir, i.e. the directory that contains the folder ".mvn".
|
||||||
|
@REM Fallback to current working directory if not found.
|
||||||
|
|
||||||
|
set MAVEN_PROJECTBASEDIR=%MAVEN_BASEDIR%
|
||||||
|
IF NOT "%MAVEN_PROJECTBASEDIR%"=="" goto endDetectBaseDir
|
||||||
|
|
||||||
|
set EXEC_DIR=%CD%
|
||||||
|
set WDIR=%EXEC_DIR%
|
||||||
|
:findBaseDir
|
||||||
|
IF EXIST "%WDIR%"\.mvn goto baseDirFound
|
||||||
|
cd ..
|
||||||
|
IF "%WDIR%"=="%CD%" goto baseDirNotFound
|
||||||
|
set WDIR=%CD%
|
||||||
|
goto findBaseDir
|
||||||
|
|
||||||
|
:baseDirFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%WDIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
goto endDetectBaseDir
|
||||||
|
|
||||||
|
:baseDirNotFound
|
||||||
|
set MAVEN_PROJECTBASEDIR=%EXEC_DIR%
|
||||||
|
cd "%EXEC_DIR%"
|
||||||
|
|
||||||
|
:endDetectBaseDir
|
||||||
|
|
||||||
|
IF NOT EXIST "%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config" goto endReadAdditionalConfig
|
||||||
|
|
||||||
|
@setlocal EnableExtensions EnableDelayedExpansion
|
||||||
|
for /F "usebackq delims=" %%a in ("%MAVEN_PROJECTBASEDIR%\.mvn\jvm.config") do set JVM_CONFIG_MAVEN_PROPS=!JVM_CONFIG_MAVEN_PROPS! %%a
|
||||||
|
@endlocal & set JVM_CONFIG_MAVEN_PROPS=%JVM_CONFIG_MAVEN_PROPS%
|
||||||
|
|
||||||
|
:endReadAdditionalConfig
|
||||||
|
|
||||||
|
SET MAVEN_JAVA_EXE="%JAVA_HOME%\bin\java.exe"
|
||||||
|
set WRAPPER_JAR="%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.jar"
|
||||||
|
set WRAPPER_LAUNCHER=org.apache.maven.wrapper.MavenWrapperMain
|
||||||
|
|
||||||
|
set DOWNLOAD_URL="https://repo.maven.apache.org/maven2/io/takari/maven-wrapper/0.4.2/maven-wrapper-0.4.2.jar"
|
||||||
|
FOR /F "tokens=1,2 delims==" %%A IN (%MAVEN_PROJECTBASEDIR%\.mvn\wrapper\maven-wrapper.properties) DO (
|
||||||
|
IF "%%A"=="wrapperUrl" SET DOWNLOAD_URL=%%B
|
||||||
|
)
|
||||||
|
|
||||||
|
@REM Extension to allow automatically downloading the maven-wrapper.jar from Maven-central
|
||||||
|
@REM This allows using the maven wrapper in projects that prohibit checking in binary data.
|
||||||
|
if exist %WRAPPER_JAR% (
|
||||||
|
echo Found %WRAPPER_JAR%
|
||||||
|
) else (
|
||||||
|
echo Couldn't find %WRAPPER_JAR%, downloading it ...
|
||||||
|
echo Downloading from: %DOWNLOAD_URL%
|
||||||
|
powershell -Command "(New-Object Net.WebClient).DownloadFile('%DOWNLOAD_URL%', '%WRAPPER_JAR%')"
|
||||||
|
echo Finished downloading %WRAPPER_JAR%
|
||||||
|
)
|
||||||
|
@REM End of extension
|
||||||
|
|
||||||
|
%MAVEN_JAVA_EXE% %JVM_CONFIG_MAVEN_PROPS% %MAVEN_OPTS% %MAVEN_DEBUG_OPTS% -classpath %WRAPPER_JAR% "-Dmaven.multiModuleProjectDirectory=%MAVEN_PROJECTBASEDIR%" %WRAPPER_LAUNCHER% %MAVEN_CONFIG% %*
|
||||||
|
if ERRORLEVEL 1 goto error
|
||||||
|
goto end
|
||||||
|
|
||||||
|
:error
|
||||||
|
set ERROR_CODE=1
|
||||||
|
|
||||||
|
:end
|
||||||
|
@endlocal & set ERROR_CODE=%ERROR_CODE%
|
||||||
|
|
||||||
|
if not "%MAVEN_SKIP_RC%" == "" goto skipRcPost
|
||||||
|
@REM check for post script, once with legacy .bat ending and once with .cmd ending
|
||||||
|
if exist "%HOME%\mavenrc_post.bat" call "%HOME%\mavenrc_post.bat"
|
||||||
|
if exist "%HOME%\mavenrc_post.cmd" call "%HOME%\mavenrc_post.cmd"
|
||||||
|
:skipRcPost
|
||||||
|
|
||||||
|
@REM pause the script if MAVEN_BATCH_PAUSE is set to 'on'
|
||||||
|
if "%MAVEN_BATCH_PAUSE%" == "on" pause
|
||||||
|
|
||||||
|
if "%MAVEN_TERMINATE_CMD%" == "on" exit %ERROR_CODE%
|
||||||
|
|
||||||
|
exit /B %ERROR_CODE%
|
288
8_suite_hub/iocr/ocr-demo/ocr-demo.iml
Normal file
@ -0,0 +1,288 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||||
|
<component name="CheckStyle-IDEA-Module">
|
||||||
|
<option name="configuration">
|
||||||
|
<map />
|
||||||
|
</option>
|
||||||
|
</component>
|
||||||
|
<component name="FacetManager">
|
||||||
|
<facet type="Spring" name="Spring">
|
||||||
|
<configuration />
|
||||||
|
</facet>
|
||||||
|
<facet type="web" name="Web">
|
||||||
|
<configuration>
|
||||||
|
<webroots />
|
||||||
|
<sourceRoots>
|
||||||
|
<root url="file://$MODULE_DIR$/src/main/java" />
|
||||||
|
<root url="file://$MODULE_DIR$/src/main/resources" />
|
||||||
|
</sourceRoots>
|
||||||
|
</configuration>
|
||||||
|
</facet>
|
||||||
|
</component>
|
||||||
|
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||||
|
<output url="file://$MODULE_DIR$/target/classes" />
|
||||||
|
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||||
|
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-context:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-autoconfigure:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.annotation:javax.annotation-api:1.3.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-core:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-jcl:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.yaml:snakeyaml:1.23" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-web:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-json:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-databind:2.9.9.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-core:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jdk8:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.datatype:jackson-datatype-jsr310:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.module:jackson-module-parameter-names:2.9.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-tomcat:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-core:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-el:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.tomcat.embed:tomcat-embed-websocket:9.0.26" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.hibernate.validator:hibernate-validator:6.0.17.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: javax.validation:validation-api:2.0.1.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.jboss.logging:jboss-logging:3.3.3.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-web:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-webmvc:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-expression:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.boot:spring-boot-starter-aop:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-aop:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.aspectj:aspectjweaver:1.9.4" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-starter-test:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework.boot:spring-boot-test-autoconfigure:2.1.9.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: com.jayway.jsonpath:json-path:2.4.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:json-smart:2.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.minidev:accessors-smart:1.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.ow2.asm:asm:5.0.4" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: junit:junit:4.12" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.assertj:assertj-core:3.11.1" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.mockito:mockito-core:2.23.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.bytebuddy:byte-buddy:1.9.16" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: net.bytebuddy:byte-buddy-agent:1.9.16" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.objenesis:objenesis:2.6" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.hamcrest:hamcrest-library:1.3" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.skyscreamer:jsonassert:1.5.0" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: com.vaadin.external.google:android-json:0.0.20131108.vaadin1" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.springframework:spring-test:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" scope="TEST" name="Maven: org.xmlunit:xmlunit-core:2.6.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.data:spring-data-commons:2.1.2.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework:spring-beans:5.1.10.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-lang3:3.12.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.5" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.11.2" level="project" />
|
||||||
|
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.logging.log4j:log4j-core:2.11.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:api:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-compress:1.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:basicdataset:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-csv:1.8" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl:model-zoo:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.mxnet:mxnet-engine:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.mxnet:mxnet-native-auto:1.8.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: net.java.dev.jna:jna:5.6.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-engine:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-native-auto:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: ai.djl.paddlepaddle:paddlepaddle-model-zoo:0.14.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacv-platform:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacv:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-armhf:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-arm64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-ppc64le:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86_64:0.3.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv-platform:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-armhf:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-ppc64le:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:macosx-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg-platform:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-armhf:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-arm64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-ppc64le:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:macosx-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86_64:4.1.3-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture-platform:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86_64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-armhf:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-arm64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86_64:2.13.3.31-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394-platform:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-armhf:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-arm64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-ppc64le:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:macosx-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86_64:2.2.6-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect-platform:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-armhf:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-arm64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-ppc64le:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:macosx-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86_64:0.5.7-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2-platform:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:macosx-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:windows-x86_64:0.2.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense-platform:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:macosx-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86_64:1.12.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput-platform:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86_64:0.200-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus-platform:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-armhf:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-arm64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-ppc64le:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:macosx-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86_64:2.3.1-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark-platform:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-armhf:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-arm64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-ppc64le:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:macosx-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86_64:1.07-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica-platform:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-armhf:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-arm64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-ppc64le:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:macosx-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86_64:1.78.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract-platform:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-armhf:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-arm64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-ppc64le:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:macosx-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86_64:4.1.0-1.5.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: gov.nist.math:jama:1.0.3" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.projectlombok:lombok:1.18.10" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.http-client:google-http-client:1.19.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.code.findbugs:jsr305:1.3.9" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpclient:4.5.10" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.httpcomponents:httpcore:4.4.12" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.alibaba:fastjson:1.2.70" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-starter:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-boot-autoconfigure:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-annotations:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-core:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.javassist:javassist:3.25.0-GA" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-bean-validators:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.github.xiaoymin:knife4j-spring-ui:2.0.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger2:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-spi:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-core:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-schema:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-common:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-spring-web:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.google.guava:guava:20.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml:classmate:1.4.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-core:1.2.0.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.springframework.plugin:spring-plugin-metadata:1.2.0.RELEASE" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.mapstruct:mapstruct:1.2.0.Final" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.springfox:springfox-swagger-ui:2.9.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-annotations:1.5.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: io.swagger:swagger-models:1.5.21" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: com.fasterxml.jackson.core:jackson-annotations:2.9.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-collections:commons-collections:3.2.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.poi:poi:4.0.0" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: commons-codec:commons-codec:1.11" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: org.apache.commons:commons-collections4:4.2" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: dom4j:dom4j:1.6.1" level="project" />
|
||||||
|
<orderEntry type="library" name="Maven: xml-apis:xml-apis:1.4.01" level="project" />
|
||||||
|
</component>
|
||||||
|
</module>
|
BIN
8_suite_hub/iocr/ocr-demo/output/ocr/paddle_OCR_detect.png
Normal file
After Width: | Height: | Size: 1.2 MiB |
248
8_suite_hub/iocr/ocr-demo/pom.xml
Normal file
@ -0,0 +1,248 @@
|
|||||||
|
<?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>
|
||||||
|
<parent>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-parent</artifactId>
|
||||||
|
<version>2.1.9.RELEASE</version>
|
||||||
|
</parent>
|
||||||
|
<groupId>aias</groupId>
|
||||||
|
<artifactId>iocr-demo</artifactId>
|
||||||
|
<version>0.1.0</version>
|
||||||
|
<name>aias-ocr-demo</name>
|
||||||
|
<description>AIAS IOCR Demo Project</description>
|
||||||
|
|
||||||
|
<properties>
|
||||||
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
|
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
|
||||||
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<jna.version>5.6.0</jna.version>
|
||||||
|
<fastjson.version>1.2.70</fastjson.version>
|
||||||
|
<swagger.version>2.9.2</swagger.version>
|
||||||
|
<djl.version>0.14.0</djl.version>
|
||||||
|
</properties>
|
||||||
|
|
||||||
|
<dependencies>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-web</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-aop</artifactId>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-starter-test</artifactId>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.springframework.data</groupId>
|
||||||
|
<artifactId>spring-data-commons</artifactId>
|
||||||
|
<version>2.1.2.RELEASE</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- apache commons -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.8.1</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- Gson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
<artifactId>gson</artifactId>
|
||||||
|
<version>2.8.5</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.logging.log4j</groupId>
|
||||||
|
<artifactId>log4j-slf4j-impl</artifactId>
|
||||||
|
<version>2.15.0</version>
|
||||||
|
</dependency>
|
||||||
|
<!-- DJL -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl</groupId>
|
||||||
|
<artifactId>api</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl</groupId>
|
||||||
|
<artifactId>basicdataset</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl</groupId>
|
||||||
|
<artifactId>model-zoo</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.mxnet</groupId>
|
||||||
|
<artifactId>mxnet-engine</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.mxnet</groupId>
|
||||||
|
<artifactId>mxnet-native-auto</artifactId>
|
||||||
|
<version>1.8.0</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>ai.djl.mxnet</groupId>-->
|
||||||
|
<!-- <artifactId>mxnet-native-mkl</artifactId>-->
|
||||||
|
<!-- <classifier>linux-x86_64</classifier>-->
|
||||||
|
<!-- <scope>runtime</scope>-->
|
||||||
|
<!-- <version>1.8.0</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>net.java.dev.jna</groupId>
|
||||||
|
<artifactId>jna</artifactId>
|
||||||
|
<version>${jna.version}</version> <!-- overrides default spring boot version to comply with DJL -->
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- PaddlePaddle -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.paddlepaddle</groupId>
|
||||||
|
<artifactId>paddlepaddle-engine</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.paddlepaddle</groupId>
|
||||||
|
<artifactId>paddlepaddle-native-auto</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- <dependency>-->
|
||||||
|
<!-- <groupId>ai.djl.paddlepaddle</groupId>-->
|
||||||
|
<!-- <artifactId>paddlepaddle-native-cpu</artifactId>-->
|
||||||
|
<!-- <classifier>linux-x86_64</classifier>-->
|
||||||
|
<!-- <version>2.0.2</version>-->
|
||||||
|
<!-- </dependency>-->
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.paddlepaddle</groupId>
|
||||||
|
<artifactId>paddlepaddle-model-zoo</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>ai.djl.paddlepaddle</groupId>
|
||||||
|
<artifactId>paddlepaddle-model-zoo</artifactId>
|
||||||
|
<version>${djl.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- java cv -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bytedeco</groupId>
|
||||||
|
<artifactId>javacv-platform</artifactId>
|
||||||
|
<version>1.5.1</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>gov.nist.math</groupId>
|
||||||
|
<artifactId>jama</artifactId>
|
||||||
|
<version>1.0.3</version>
|
||||||
|
</dependency>
|
||||||
|
<!--lombok-->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.google.http-client</groupId>
|
||||||
|
<artifactId>google-http-client</artifactId>
|
||||||
|
<version>1.19.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-cli</groupId>
|
||||||
|
<artifactId>commons-cli</artifactId>
|
||||||
|
<version>1.4</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- fastjson -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.alibaba</groupId>
|
||||||
|
<artifactId>fastjson</artifactId>
|
||||||
|
<version>${fastjson.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>com.github.xiaoymin</groupId>
|
||||||
|
<artifactId>knife4j-spring-boot-starter</artifactId>
|
||||||
|
<version>2.0.2</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Swagger UI 相关 -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.springfox</groupId>
|
||||||
|
<artifactId>springfox-swagger2</artifactId>
|
||||||
|
<version>${swagger.version}</version>
|
||||||
|
<exclusions>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
<exclusion>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-models</artifactId>
|
||||||
|
</exclusion>
|
||||||
|
</exclusions>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.springfox</groupId>
|
||||||
|
<artifactId>springfox-swagger-ui</artifactId>
|
||||||
|
<version>${swagger.version}</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-annotations</artifactId>
|
||||||
|
<version>1.5.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.swagger</groupId>
|
||||||
|
<artifactId>swagger-models</artifactId>
|
||||||
|
<version>1.5.21</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.commons</groupId>
|
||||||
|
<artifactId>commons-lang3</artifactId>
|
||||||
|
<version>3.12.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>commons-collections</groupId>
|
||||||
|
<artifactId>commons-collections</artifactId>
|
||||||
|
<version>3.2.2</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.apache.poi</groupId>
|
||||||
|
<artifactId>poi</artifactId>
|
||||||
|
<version>4.0.0</version>
|
||||||
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>dom4j</groupId>
|
||||||
|
<artifactId>dom4j</artifactId>
|
||||||
|
<version>1.6.1</version>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
|
<build>
|
||||||
|
<plugins>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.springframework.boot</groupId>
|
||||||
|
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||||
|
<configuration>
|
||||||
|
<mainClass>me.aias.ocr.MainApplication</mainClass>
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
|
</project>
|
@ -0,0 +1,3 @@
|
|||||||
|
Manifest-Version: 1.0
|
||||||
|
Main-Class: me.aias.ocr.MainApplication
|
||||||
|
|
@ -0,0 +1,16 @@
|
|||||||
|
package me.aias.ocr;
|
||||||
|
|
||||||
|
import org.springframework.boot.SpringApplication;
|
||||||
|
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
|
||||||
|
@SpringBootApplication
|
||||||
|
public class MainApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
SpringApplication.run(MainApplication.class, args);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
package me.aias.ocr.configuration;
|
||||||
|
|
||||||
|
import com.alibaba.fastjson.serializer.SerializerFeature;
|
||||||
|
import com.alibaba.fastjson.support.config.FastJsonConfig;
|
||||||
|
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.http.MediaType;
|
||||||
|
import org.springframework.http.converter.HttpMessageConverter;
|
||||||
|
import org.springframework.http.converter.StringHttpMessageConverter;
|
||||||
|
import org.springframework.web.cors.CorsConfiguration;
|
||||||
|
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
|
||||||
|
import org.springframework.web.filter.CorsFilter;
|
||||||
|
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
|
||||||
|
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
|
||||||
|
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
|
||||||
|
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableWebMvc
|
||||||
|
public class ConfigAdapter implements WebMvcConfigurer {
|
||||||
|
|
||||||
|
// file configuration
|
||||||
|
private final FileProperties properties;
|
||||||
|
|
||||||
|
public ConfigAdapter(FileProperties properties) {
|
||||||
|
this.properties = properties;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public CorsFilter corsFilter() {
|
||||||
|
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
|
||||||
|
CorsConfiguration config = new CorsConfiguration();
|
||||||
|
config.setAllowCredentials(true);
|
||||||
|
config.addAllowedOrigin("*");
|
||||||
|
config.addAllowedHeader("*");
|
||||||
|
config.addAllowedMethod("*");
|
||||||
|
source.registerCorsConfiguration("/**", config);
|
||||||
|
return new CorsFilter(source);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void addResourceHandlers(ResourceHandlerRegistry registry) {
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String pathUtl = "file:" + path.getPath().replace("\\", "/");
|
||||||
|
registry.addResourceHandler("/file/**").addResourceLocations(pathUtl).setCachePeriod(0);
|
||||||
|
registry.addResourceHandler("/file/tables/**").addResourceLocations(pathUtl + "tables/").setCachePeriod(0);
|
||||||
|
registry.addResourceHandler("/file/images/**").addResourceLocations(pathUtl + "images/").setCachePeriod(0);
|
||||||
|
registry.addResourceHandler("/**").addResourceLocations("classpath:/META-INF/resources/").setCachePeriod(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
|
||||||
|
// 使用 fastjson 序列化,会导致 @JsonIgnore 失效,可以使用 @JSONField(serialize = false) 替换
|
||||||
|
FastJsonHttpMessageConverter fastJsonHttpMessageConverter = new FastJsonHttpMessageConverter();
|
||||||
|
List<MediaType> supportMediaTypeList = new ArrayList<>();
|
||||||
|
supportMediaTypeList.add(MediaType.APPLICATION_JSON_UTF8);
|
||||||
|
supportMediaTypeList.add(MediaType.TEXT_HTML);
|
||||||
|
FastJsonConfig config = new FastJsonConfig();
|
||||||
|
config.setDateFormat("yyyy-MM-dd HH:mm:ss");
|
||||||
|
config.setSerializerFeatures(SerializerFeature.DisableCircularReferenceDetect);
|
||||||
|
fastJsonHttpMessageConverter.setFastJsonConfig(config);
|
||||||
|
fastJsonHttpMessageConverter.setSupportedMediaTypes(supportMediaTypeList);
|
||||||
|
fastJsonHttpMessageConverter.setDefaultCharset(StandardCharsets.UTF_8);
|
||||||
|
|
||||||
|
converters.add(fastJsonHttpMessageConverter);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,43 @@
|
|||||||
|
package me.aias.ocr.configuration;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import me.aias.ocr.utils.Constants;
|
||||||
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Data
|
||||||
|
@Configuration
|
||||||
|
@ConfigurationProperties(prefix = "file")
|
||||||
|
public class FileProperties {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File size limitation
|
||||||
|
*/
|
||||||
|
private Long maxSize;
|
||||||
|
|
||||||
|
private ElPath mac;
|
||||||
|
|
||||||
|
private ElPath linux;
|
||||||
|
|
||||||
|
private ElPath windows;
|
||||||
|
|
||||||
|
public ElPath getPath() {
|
||||||
|
String os = System.getProperty("os.name");
|
||||||
|
if (os.toLowerCase().startsWith(Constants.WIN)) {
|
||||||
|
return windows;
|
||||||
|
} else if (os.toLowerCase().startsWith(Constants.MAC)) {
|
||||||
|
return mac;
|
||||||
|
}
|
||||||
|
return linux;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public static class ElPath {
|
||||||
|
|
||||||
|
private String path;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
package me.aias.ocr.configuration;
|
||||||
|
|
||||||
|
import ai.djl.MalformedModelException;
|
||||||
|
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||||
|
import me.aias.ocr.inference.LayoutDetectionModel;
|
||||||
|
import me.aias.ocr.inference.RecognitionModel;
|
||||||
|
import me.aias.ocr.inference.TableDetectionModel;
|
||||||
|
import me.aias.ocr.utils.Constants;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
public class ModelConfiguration {
|
||||||
|
@Value("${model.type}")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Value("${model.table.layout}")
|
||||||
|
private String tableLayout;
|
||||||
|
@Value("${model.table.table-en}")
|
||||||
|
private String table;
|
||||||
|
// mobile model
|
||||||
|
@Value("${model.mobile.det}")
|
||||||
|
private String mobileDet;
|
||||||
|
@Value("${model.mobile.rec}")
|
||||||
|
private String mobileRec;
|
||||||
|
// light model
|
||||||
|
@Value("${model.light.det}")
|
||||||
|
private String lightDet;
|
||||||
|
@Value("${model.light.rec}")
|
||||||
|
private String lightRec;
|
||||||
|
// server model
|
||||||
|
@Value("${model.server.det}")
|
||||||
|
private String serverDet;
|
||||||
|
@Value("${model.server.rec}")
|
||||||
|
private String serverRec;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public RecognitionModel recognitionModel() throws IOException, ModelNotFoundException, MalformedModelException {
|
||||||
|
RecognitionModel recognitionModel = new RecognitionModel();
|
||||||
|
if (StringUtils.isEmpty(type) || type.toLowerCase().equals("mobile")) {
|
||||||
|
recognitionModel.init(mobileDet, mobileRec);
|
||||||
|
} else if (type.toLowerCase().equals("light")) {
|
||||||
|
recognitionModel.init(lightDet, lightRec);
|
||||||
|
} else if (type.toLowerCase().equals("server")) {
|
||||||
|
recognitionModel.init(serverDet, serverRec);
|
||||||
|
} else {
|
||||||
|
recognitionModel.init(mobileDet, mobileRec);
|
||||||
|
}
|
||||||
|
return recognitionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public TableDetectionModel tableDetectionModel() throws IOException, ModelNotFoundException, MalformedModelException {
|
||||||
|
TableDetectionModel tableDetectionModel = new TableDetectionModel();
|
||||||
|
tableDetectionModel.init(table);
|
||||||
|
return tableDetectionModel;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public LayoutDetectionModel layoutDetectionModel() throws IOException, ModelNotFoundException, MalformedModelException {
|
||||||
|
LayoutDetectionModel layoutDetectionModel = new LayoutDetectionModel();
|
||||||
|
layoutDetectionModel.init(tableLayout);
|
||||||
|
return layoutDetectionModel;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2019-2020 Zheng Jie
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package me.aias.ocr.configuration;
|
||||||
|
|
||||||
|
import com.fasterxml.classmate.TypeResolver;
|
||||||
|
import com.google.common.base.Predicates;
|
||||||
|
import io.swagger.annotations.ApiModel;
|
||||||
|
import io.swagger.annotations.ApiModelProperty;
|
||||||
|
import lombok.Data;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.core.Ordered;
|
||||||
|
import org.springframework.data.domain.Pageable;
|
||||||
|
import springfox.documentation.builders.ApiInfoBuilder;
|
||||||
|
import springfox.documentation.builders.ParameterBuilder;
|
||||||
|
import springfox.documentation.builders.PathSelectors;
|
||||||
|
import springfox.documentation.schema.AlternateTypeRule;
|
||||||
|
import springfox.documentation.schema.AlternateTypeRuleConvention;
|
||||||
|
import springfox.documentation.service.ApiInfo;
|
||||||
|
import springfox.documentation.spi.DocumentationType;
|
||||||
|
import springfox.documentation.spring.web.plugins.Docket;
|
||||||
|
import springfox.documentation.swagger2.annotations.EnableSwagger2;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import static com.google.common.collect.Lists.newArrayList;
|
||||||
|
import static springfox.documentation.schema.AlternateTypeRules.newRule;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* api doc.html
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
@EnableSwagger2
|
||||||
|
public class SwaggerConfig {
|
||||||
|
|
||||||
|
|
||||||
|
@Value("${swagger.enabled}")
|
||||||
|
private Boolean enabled;
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public Docket createRestApi() {
|
||||||
|
ParameterBuilder ticketPar = new ParameterBuilder();
|
||||||
|
return new Docket(DocumentationType.SWAGGER_2)
|
||||||
|
.enable(enabled)
|
||||||
|
.apiInfo(apiInfo())
|
||||||
|
.select()
|
||||||
|
.paths(Predicates.not(PathSelectors.regex("/error.*")))
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private ApiInfo apiInfo() {
|
||||||
|
return new ApiInfoBuilder()
|
||||||
|
.description("")
|
||||||
|
.title("接口文档")
|
||||||
|
.version("1.0")
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 将Pageable转换展示在swagger中
|
||||||
|
*/
|
||||||
|
@Configuration
|
||||||
|
class SwaggerDataConfig {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
public AlternateTypeRuleConvention pageableConvention(final TypeResolver resolver) {
|
||||||
|
return new AlternateTypeRuleConvention() {
|
||||||
|
@Override
|
||||||
|
public int getOrder() {
|
||||||
|
return Ordered.HIGHEST_PRECEDENCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public List<AlternateTypeRule> rules() {
|
||||||
|
return newArrayList(newRule(resolver.resolve(Pageable.class), resolver.resolve(Page.class)));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiModel
|
||||||
|
@Data
|
||||||
|
private static class Page {
|
||||||
|
@ApiModelProperty("页码 (0..N)")
|
||||||
|
private Integer page;
|
||||||
|
|
||||||
|
@ApiModelProperty("每页显示的数目")
|
||||||
|
private Integer size;
|
||||||
|
|
||||||
|
@ApiModelProperty("以下列格式排序标准:property[,asc | desc]。 默认排序顺序为升序。 支持多种排序条件:如:id,asc")
|
||||||
|
private List<String> sort;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
package me.aias.ocr.controller;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import me.aias.ocr.configuration.FileProperties;
|
||||||
|
import me.aias.ocr.model.DataBean;
|
||||||
|
import me.aias.ocr.model.ResultBean;
|
||||||
|
import me.aias.ocr.service.InferService;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Api(tags = "通用文字识别")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/inference")
|
||||||
|
public class InferController {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(InferController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private InferService inferService;
|
||||||
|
|
||||||
|
@Value("${server.baseUri}")
|
||||||
|
private String baseUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file configuration
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private FileProperties properties;
|
||||||
|
|
||||||
|
@ApiOperation(value = "通用文字识别-URL")
|
||||||
|
@GetMapping(value = "/generalInfoForImageUrl", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean generalInfoForImageUrl(@RequestParam(value = "url") String url) throws IOException {
|
||||||
|
try {
|
||||||
|
Image image = ImageFactory.getInstance().fromUrl(url);
|
||||||
|
List<DataBean> dataList = inferService.getGeneralInfo(image);
|
||||||
|
return ResultBean.success().add("result", dataList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "通用文字识别-图片")
|
||||||
|
@PostMapping(value = "/generalInfoForImageFile", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean generalInfoForImageFile(@RequestParam(value = "imageFile") MultipartFile imageFile) {
|
||||||
|
try (InputStream inputStream = imageFile.getInputStream()) {
|
||||||
|
String base64Img = Base64.encodeBase64String(imageFile.getBytes());
|
||||||
|
Image image = ImageFactory.getInstance().fromInputStream(inputStream);
|
||||||
|
List<DataBean> dataList = inferService.getGeneralInfo(image);
|
||||||
|
|
||||||
|
return ResultBean.success().add("result", dataList)
|
||||||
|
.add("base64Img", "data:imageName/jpeg;base64," + base64Img);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,248 @@
|
|||||||
|
package me.aias.ocr.controller;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import me.aias.ocr.configuration.FileProperties;
|
||||||
|
import me.aias.ocr.model.DataBean;
|
||||||
|
import me.aias.ocr.model.ResultBean;
|
||||||
|
import me.aias.ocr.service.InferService;
|
||||||
|
import me.aias.ocr.service.TableInferService;
|
||||||
|
import me.aias.ocr.utils.ConvertHtml2Excel;
|
||||||
|
import me.aias.ocr.utils.UUIDUtils;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Api(tags = "表格文字识别")
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/table")
|
||||||
|
public class TableController {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(TableController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TableInferService tableInferService;
|
||||||
|
|
||||||
|
@Value("${server.baseUri}")
|
||||||
|
private String baseUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file configuration
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private FileProperties properties;
|
||||||
|
|
||||||
|
@ApiOperation(value = "单表格文字识别-URL")
|
||||||
|
@GetMapping(value = "/tableInfoForImageUrl")
|
||||||
|
public ResultBean tableInfoForImageUrl(@RequestParam(value = "url") String url) {
|
||||||
|
try {
|
||||||
|
Image image = ImageFactory.getInstance().fromUrl(url);
|
||||||
|
String tableHtml = tableInferService.getTableHtml(image);
|
||||||
|
// 创建一个Excel文件
|
||||||
|
tableHtml = tableHtml.replace("<html><body>", "");
|
||||||
|
tableHtml = tableHtml.replace("</body></html>", "");
|
||||||
|
HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(tableHtml);
|
||||||
|
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/") + "tables/";
|
||||||
|
//Check & create file path
|
||||||
|
Path filePath = Paths.get(fileRelativePath);
|
||||||
|
File file = filePath.toFile();
|
||||||
|
if (!file.exists() && !file.isDirectory()) {
|
||||||
|
file.mkdir();
|
||||||
|
}
|
||||||
|
String fileId = UUIDUtils.getUUID();
|
||||||
|
workbook.write(new File(fileRelativePath + fileId + ".xls"));
|
||||||
|
|
||||||
|
try (OutputStreamWriter out = new OutputStreamWriter(
|
||||||
|
new FileOutputStream(fileRelativePath + fileId + ".html"), "UTF-8")) {
|
||||||
|
out.write(tableHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
String excelUri = baseUri + File.separator + fileRelativePath + fileId + ".xls";
|
||||||
|
String htmlUri = baseUri + File.separator + fileRelativePath + fileId + ".html";
|
||||||
|
|
||||||
|
Map<String, String> map = new ConcurrentHashMap<>();
|
||||||
|
map.put("excelUri", excelUri);
|
||||||
|
map.put("htmlUri", htmlUri);
|
||||||
|
map.put("html", tableHtml);
|
||||||
|
return ResultBean.success().add("result", map);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "单表格文字识别-图片")
|
||||||
|
@PostMapping("/tableInfoForImageFile")
|
||||||
|
public ResultBean tableInfoForImageFile(@RequestParam(value = "imageFile") MultipartFile imageFile) {
|
||||||
|
try (InputStream inputStream = imageFile.getInputStream()) {
|
||||||
|
String base64Img = Base64.encodeBase64String(imageFile.getBytes());
|
||||||
|
Image image = ImageFactory.getInstance().fromInputStream(inputStream);
|
||||||
|
String tableHtml = tableInferService.getTableHtml(image);
|
||||||
|
// 创建一个Excel文件
|
||||||
|
tableHtml = tableHtml.replace("<html><body>", "");
|
||||||
|
tableHtml = tableHtml.replace("</body></html>", "");
|
||||||
|
HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(tableHtml);
|
||||||
|
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/") + "tables/";
|
||||||
|
//Check & create file path
|
||||||
|
Path filePath = Paths.get(fileRelativePath);
|
||||||
|
File file = filePath.toFile();
|
||||||
|
if (!file.exists() && !file.isDirectory()) {
|
||||||
|
file.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
String fileId = UUIDUtils.getUUID();
|
||||||
|
workbook.write(new File(fileRelativePath + fileId + ".xls"));
|
||||||
|
|
||||||
|
try (OutputStreamWriter out = new OutputStreamWriter(
|
||||||
|
new FileOutputStream(fileRelativePath + fileId + ".html"), "UTF-8")) {
|
||||||
|
out.write(tableHtml);
|
||||||
|
}
|
||||||
|
|
||||||
|
String excelUri = baseUri + File.separator + fileRelativePath + fileId + ".xls";
|
||||||
|
String htmlUri = baseUri + File.separator + fileRelativePath + fileId + ".html";
|
||||||
|
|
||||||
|
Map<String, String> map = new ConcurrentHashMap<>();
|
||||||
|
map.put("excelUri", excelUri);
|
||||||
|
map.put("htmlUri", htmlUri);
|
||||||
|
map.put("html", tableHtml);
|
||||||
|
|
||||||
|
return ResultBean.success().add("result", map)
|
||||||
|
.add("base64Img", "data:imageName/jpeg;base64," + base64Img);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "表单表格自动检测文字识别-URL")
|
||||||
|
@GetMapping(value = "/autoTableInfoForImageUrl")
|
||||||
|
public ResultBean autoTableInfoForImageUrl(@RequestParam(value = "url") String url) {
|
||||||
|
try {
|
||||||
|
Image image = ImageFactory.getInstance().fromUrl(url);
|
||||||
|
List<String> tableHtmlList = tableInferService.getTableHtmlList(image);
|
||||||
|
List<HSSFWorkbook> workbookList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String tableHtml : tableHtmlList) {
|
||||||
|
tableHtml = tableHtml.replace("<html><body>", "");
|
||||||
|
tableHtml = tableHtml.replace("</body></html>", "");
|
||||||
|
// Create workbook for each table
|
||||||
|
HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(tableHtml);
|
||||||
|
workbookList.add(workbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/") + "tables/";
|
||||||
|
//Check & create file path
|
||||||
|
Path filePath = Paths.get(fileRelativePath);
|
||||||
|
File file = filePath.toFile();
|
||||||
|
if (!file.exists() && !file.isDirectory()) {
|
||||||
|
file.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> uriList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < tableHtmlList.size(); i++) {
|
||||||
|
String fileId = UUIDUtils.getUUID();
|
||||||
|
HSSFWorkbook workbook = workbookList.get(i);
|
||||||
|
workbook.write(new File(fileRelativePath + fileId + ".xls"));
|
||||||
|
String tableHtml = tableHtmlList.get(i);
|
||||||
|
try (OutputStreamWriter out = new OutputStreamWriter(
|
||||||
|
new FileOutputStream(fileRelativePath + fileId + ".html"), "UTF-8")) {
|
||||||
|
out.write(tableHtml);
|
||||||
|
}
|
||||||
|
String excelUri = baseUri + File.separator + fileRelativePath + fileId + ".xls";
|
||||||
|
String htmlUri = baseUri + File.separator + fileRelativePath + fileId + ".html";
|
||||||
|
Map<String, String> map = new ConcurrentHashMap<>();
|
||||||
|
map.put("excelUri", excelUri);
|
||||||
|
map.put("htmlUri", htmlUri);
|
||||||
|
map.put("html", tableHtml);
|
||||||
|
uriList.add(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultBean.success().add("result", uriList);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "表单表格自动检测文字识别-URL")
|
||||||
|
@PostMapping("/autoTableInfoForImageFile")
|
||||||
|
public ResultBean autoTableInfoForImageFile(@RequestParam(value = "imageFile") MultipartFile imageFile) {
|
||||||
|
try (InputStream inputStream = imageFile.getInputStream()) {
|
||||||
|
String base64Img = Base64.encodeBase64String(imageFile.getBytes());
|
||||||
|
Image image = ImageFactory.getInstance().fromInputStream(inputStream);
|
||||||
|
|
||||||
|
List<String> tableHtmlList = tableInferService.getTableHtmlList(image);
|
||||||
|
List<HSSFWorkbook> workbookList = new ArrayList<>();
|
||||||
|
|
||||||
|
for (String tableHtml : tableHtmlList) {
|
||||||
|
tableHtml = tableHtml.replace("<html><body>", "");
|
||||||
|
tableHtml = tableHtml.replace("</body></html>", "");
|
||||||
|
// Create workbook for each table
|
||||||
|
HSSFWorkbook workbook = ConvertHtml2Excel.table2Excel(tableHtml);
|
||||||
|
workbookList.add(workbook);
|
||||||
|
}
|
||||||
|
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/") + "tables/";
|
||||||
|
//Check & create file path
|
||||||
|
Path filePath = Paths.get(fileRelativePath);
|
||||||
|
File file = filePath.toFile();
|
||||||
|
if (!file.exists() && !file.isDirectory()) {
|
||||||
|
file.mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Map<String, String>> uriList = new ArrayList<>();
|
||||||
|
for (int i = 0; i < tableHtmlList.size(); i++) {
|
||||||
|
String fileId = UUIDUtils.getUUID();
|
||||||
|
HSSFWorkbook workbook = workbookList.get(i);
|
||||||
|
workbook.write(new File(fileRelativePath + fileId + ".xls"));
|
||||||
|
String tableHtml = tableHtmlList.get(i);
|
||||||
|
|
||||||
|
|
||||||
|
try (OutputStreamWriter out = new OutputStreamWriter(
|
||||||
|
new FileOutputStream(fileRelativePath + fileId + ".html"), "UTF-8")) {
|
||||||
|
out.write(tableHtml);
|
||||||
|
}
|
||||||
|
String excelUri = baseUri + File.separator + fileRelativePath + fileId + ".xls";
|
||||||
|
String htmlUri = baseUri + File.separator + fileRelativePath + fileId + ".html";
|
||||||
|
Map<String, String> map = new ConcurrentHashMap<>();
|
||||||
|
map.put("excelUri", excelUri);
|
||||||
|
map.put("htmlUri", htmlUri);
|
||||||
|
map.put("html", tableHtml);
|
||||||
|
uriList.add(map);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ResultBean.success().add("result", uriList).add("base64Img", "data:imageName/jpeg;base64," + base64Img);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,181 @@
|
|||||||
|
package me.aias.ocr.controller;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import io.swagger.annotations.Api;
|
||||||
|
import io.swagger.annotations.ApiOperation;
|
||||||
|
import me.aias.ocr.configuration.FileProperties;
|
||||||
|
import me.aias.ocr.model.LabelDTO;
|
||||||
|
import me.aias.ocr.model.ResultBean;
|
||||||
|
import me.aias.ocr.model.TemplateBean;
|
||||||
|
import me.aias.ocr.service.TemplateService;
|
||||||
|
import me.aias.ocr.utils.FileUtils;
|
||||||
|
import me.aias.ocr.utils.UUIDUtils;
|
||||||
|
import org.apache.commons.codec.binary.Base64;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
import org.springframework.web.bind.annotation.*;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Api(tags = "自定义模版文字识别")
|
||||||
|
@RestController
|
||||||
|
@Configuration
|
||||||
|
@RequestMapping("/template")
|
||||||
|
public class TemplateController {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(TemplateController.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TemplateService ocrTemplateService;
|
||||||
|
|
||||||
|
@Value("${server.baseUri}")
|
||||||
|
private String baseUri;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件配置
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private FileProperties properties;
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取模版")
|
||||||
|
@GetMapping(value = "/getTemplate", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean getTemplate(@RequestParam(value = "uid") String uid) {
|
||||||
|
try {
|
||||||
|
TemplateBean templateBean = ocrTemplateService.getTemplate(uid);
|
||||||
|
return ResultBean.success().add("result", templateBean);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "获取模版列表")
|
||||||
|
@GetMapping(value = "/getTemplates", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean getTemplatesList() {
|
||||||
|
try {
|
||||||
|
return ResultBean.success().add("result", ocrTemplateService.getTemplateList());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "更新模板信息")
|
||||||
|
@PostMapping(value = "/updateTemplate", consumes = "application/json;charset=utf-8")
|
||||||
|
public ResultBean updateTemplate(@RequestBody TemplateBean templateBean) {
|
||||||
|
try {
|
||||||
|
ocrTemplateService.updateTemplate(templateBean);
|
||||||
|
return ResultBean.success();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "删除模板")
|
||||||
|
@PostMapping(value = "/removeTemplate", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean removeTemplate(@RequestParam(value = "uid") String uid) {
|
||||||
|
try {
|
||||||
|
ocrTemplateService.removeTemplate(uid);
|
||||||
|
return ResultBean.success();
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "识别标注字段")
|
||||||
|
@PostMapping(value = "/getLabelData", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean getLabelData(@RequestBody LabelDTO labelDTO) {
|
||||||
|
try {
|
||||||
|
String result = ocrTemplateService.getLabelData(labelDTO.getUid(), labelDTO.getLabelData());
|
||||||
|
logger.info("LabelData: " + result);
|
||||||
|
return ResultBean.success().add("result", result);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "创建模板")
|
||||||
|
@PostMapping(value = "/addTemplate")
|
||||||
|
public ResultBean addTemplate(@RequestParam(value = "name") String name, @RequestParam(value = "imageFile") MultipartFile imageFile) {
|
||||||
|
try {
|
||||||
|
// 要上传的目标文件存放路径
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String imagePath = path.getPath().replace("\\", "/") + "images/";
|
||||||
|
FileUtils.checkAndCreatePath(imagePath);
|
||||||
|
String templatePath = path.getPath().replace("\\", "/") + "templates/";
|
||||||
|
FileUtils.checkAndCreatePath(templatePath);
|
||||||
|
|
||||||
|
TemplateBean templateBean = new TemplateBean();
|
||||||
|
String uid = UUIDUtils.getUUID();
|
||||||
|
templateBean.setUid(uid);
|
||||||
|
//image/jpg' || 'image/jpeg' || 'image/png'
|
||||||
|
String suffix = FileUtils.getSuffix(imageFile.getOriginalFilename());
|
||||||
|
if (!suffix.equalsIgnoreCase(".jpg") && !suffix.equalsIgnoreCase(".jpeg") && !suffix.equalsIgnoreCase(".png")) {
|
||||||
|
return ResultBean.failure().add("errors", "Image format should be JPG(JPEG) or PNG!");
|
||||||
|
}
|
||||||
|
String imageName = FileUtils.getFileName(imageFile.getOriginalFilename());
|
||||||
|
templateBean.setImageName(imageName);
|
||||||
|
templateBean.setName(name);
|
||||||
|
|
||||||
|
logger.info("Template name:" + name);
|
||||||
|
// String imageUri = baseUri + File.separator + fileRelativePath + fileName;
|
||||||
|
|
||||||
|
if (FileUtils.upload(imageFile, imagePath, imageName)) {
|
||||||
|
ocrTemplateService.addTemplate(templateBean);
|
||||||
|
return ResultBean.success().add("result", templateBean);
|
||||||
|
} else {
|
||||||
|
return ResultBean.failure();
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "模版文字识别-URL")
|
||||||
|
@GetMapping(value = "/infoForImageUrl", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean infoForImageUrl(@RequestParam(value = "uid") String uid, @RequestParam(value = "url") String url) {
|
||||||
|
try {
|
||||||
|
Image image = ImageFactory.getInstance().fromUrl(url);
|
||||||
|
TemplateBean templateBean = ocrTemplateService.getTemplate(uid);
|
||||||
|
Map<String, String> hashMap = ocrTemplateService.getImageInfo(templateBean, image);
|
||||||
|
return ResultBean.success().add("result", hashMap);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@ApiOperation(value = "模版文字识别-图片")
|
||||||
|
@PostMapping(value = "/infoForImageFile", produces = "application/json;charset=utf-8")
|
||||||
|
public ResultBean infoForImageFile(@RequestParam(value = "uid") String uid, @RequestParam(value = "imageFile") MultipartFile imageFile) {
|
||||||
|
try (InputStream inputStream = imageFile.getInputStream()) {
|
||||||
|
String base64Img = Base64.encodeBase64String(imageFile.getBytes());
|
||||||
|
TemplateBean templateBean = ocrTemplateService.getTemplate(uid);
|
||||||
|
Image image = ImageFactory.getInstance().fromInputStream(inputStream);
|
||||||
|
Map<String, String> hashMap = ocrTemplateService.getImageInfo(templateBean, image);
|
||||||
|
|
||||||
|
return ResultBean.success().add("result", hashMap)
|
||||||
|
.add("base64Img", "data:imageName/jpeg;base64," + base64Img);
|
||||||
|
} catch (Exception e) {
|
||||||
|
logger.error(e.getMessage());
|
||||||
|
e.printStackTrace();
|
||||||
|
return ResultBean.failure().add("errors", e.getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,57 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.Device;
|
||||||
|
import ai.djl.MalformedModelException;
|
||||||
|
import ai.djl.inference.Predictor;
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.repository.zoo.Criteria;
|
||||||
|
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||||
|
import ai.djl.repository.zoo.ModelZoo;
|
||||||
|
import ai.djl.repository.zoo.ZooModel;
|
||||||
|
import ai.djl.training.util.ProgressBar;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.TableResult;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 20, 2021
|
||||||
|
*/
|
||||||
|
public final class LayoutDetectionModel {
|
||||||
|
|
||||||
|
private ZooModel<Image, DetectedObjects> model;
|
||||||
|
private Predictor<Image, DetectedObjects> predictor;
|
||||||
|
|
||||||
|
public void init(String layoutUri) throws MalformedModelException, ModelNotFoundException, IOException {
|
||||||
|
this.model = ModelZoo.loadModel(detectCriteria(layoutUri));
|
||||||
|
this.predictor = model.newPredictor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
this.model.close();
|
||||||
|
this.predictor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetectedObjects predict(Image image) throws TranslateException {
|
||||||
|
return predictor.predict(image);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria<Image, DetectedObjects> detectCriteria(String layoutUri) {
|
||||||
|
Criteria<Image, DetectedObjects> criteria =
|
||||||
|
Criteria.builder()
|
||||||
|
.optEngine("PaddlePaddle")
|
||||||
|
.setTypes(Image.class, DetectedObjects.class)
|
||||||
|
.optModelUrls(layoutUri)
|
||||||
|
// .optDevice(Device.cpu())
|
||||||
|
.optTranslator(new LayoutDetectionTranslator())
|
||||||
|
.optProgress(new ProgressBar())
|
||||||
|
.build();
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,104 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.modality.cv.util.NDImageUtils;
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDList;
|
||||||
|
import ai.djl.ndarray.types.DataType;
|
||||||
|
import ai.djl.translate.Batchifier;
|
||||||
|
import ai.djl.translate.Translator;
|
||||||
|
import ai.djl.translate.TranslatorContext;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class LayoutDetectionTranslator implements Translator<Image, DetectedObjects> {
|
||||||
|
|
||||||
|
private int width;
|
||||||
|
private int height;
|
||||||
|
|
||||||
|
public LayoutDetectionTranslator() {}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public DetectedObjects processOutput(TranslatorContext ctx, NDList list) {
|
||||||
|
NDArray result = list.get(0); // np_boxes
|
||||||
|
long rows = result.size(0);
|
||||||
|
|
||||||
|
List<BoundingBox> boxes = new ArrayList<>();
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
List<Double> probs = new ArrayList<>();
|
||||||
|
|
||||||
|
for (long i = 0; i < rows; i++) {
|
||||||
|
NDArray row = result.get(i);
|
||||||
|
float[] array = row.toFloatArray();
|
||||||
|
if (array[1] <= 0.5 || array[0] <= -1) continue;
|
||||||
|
int clsid = (int) array[0];
|
||||||
|
double score = array[1];
|
||||||
|
String name = "";
|
||||||
|
switch (clsid) {
|
||||||
|
case 0:
|
||||||
|
name = "Text";
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
name = "Title";
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
name = "List";
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
name = "Table";
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
name = "Figure";
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
name = "Unknown";
|
||||||
|
}
|
||||||
|
|
||||||
|
float x = array[2] / width;
|
||||||
|
float y = array[3] / height;
|
||||||
|
float w = (array[4] - array[2]) / width;
|
||||||
|
float h = (array[5] - array[3]) / height;
|
||||||
|
|
||||||
|
Rectangle rect = new Rectangle(x, y, w, h);
|
||||||
|
boxes.add(rect);
|
||||||
|
names.add(name);
|
||||||
|
probs.add(score);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new DetectedObjects(names, probs, boxes);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NDList processInput(TranslatorContext ctx, Image input) {
|
||||||
|
NDArray img = input.toNDArray(ctx.getNDManager());
|
||||||
|
width = input.getWidth();
|
||||||
|
height = input.getHeight();
|
||||||
|
|
||||||
|
img = NDImageUtils.resize(img, 640, 640);
|
||||||
|
img = img.transpose(2, 0, 1).div(255);
|
||||||
|
img =
|
||||||
|
NDImageUtils.normalize(
|
||||||
|
img, new float[] {0.485f, 0.456f, 0.406f}, new float[] {0.229f, 0.224f, 0.225f});
|
||||||
|
img = img.expandDims(0);
|
||||||
|
|
||||||
|
NDArray scale_factor = ctx.getNDManager().create(new float[] {640f / height, 640f / width});
|
||||||
|
scale_factor = scale_factor.toType(DataType.FLOAT32, false);
|
||||||
|
scale_factor = scale_factor.expandDims(0);
|
||||||
|
|
||||||
|
NDArray im_shape = ctx.getNDManager().create(new float[] {640f, 640f});
|
||||||
|
im_shape = im_shape.toType(DataType.FLOAT32, false);
|
||||||
|
im_shape = im_shape.expandDims(0);
|
||||||
|
|
||||||
|
// im_shape, imageName, scale_factor
|
||||||
|
return new NDList(im_shape, img, scale_factor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Batchifier getBatchifier() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,170 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.LabelBean;
|
||||||
|
import me.aias.ocr.utils.*;
|
||||||
|
import org.bytedeco.javacv.Java2DFrameUtils;
|
||||||
|
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Point2f;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public class PerspectiveRecogition {
|
||||||
|
public static Map<String, String> recognize(NDManager manager, BufferedImage templateImg, RecognitionModel recognitionModel, Image image, List<LabelBean> anchorlabels, List<LabelBean> contentLabels, String fileRelativePath, String distance, boolean save) throws TranslateException {
|
||||||
|
|
||||||
|
// 锚点识别区 - 计算中心点坐标,用于透视变换
|
||||||
|
for (int i = 0; i < anchorlabels.size(); i++) {
|
||||||
|
List<me.aias.ocr.model.Point> points = anchorlabels.get(i).getPoints();
|
||||||
|
anchorlabels.get(i).setCenterPoint(PointUtils.getCenterPoint(points));
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文本检测区
|
||||||
|
List<LabelBean> detectedTexts = new ArrayList<>();
|
||||||
|
DetectedObjects textDetections = recognitionModel.predict(image);
|
||||||
|
List<DetectedObjects.DetectedObject> dt_boxes = textDetections.items();
|
||||||
|
for (DetectedObjects.DetectedObject item : dt_boxes) {
|
||||||
|
LabelBean labelBean = new LabelBean();
|
||||||
|
List<me.aias.ocr.model.Point> points = new ArrayList<>();
|
||||||
|
labelBean.setValue(item.getClassName());
|
||||||
|
Rectangle rectangle = item.getBoundingBox().getBounds();
|
||||||
|
|
||||||
|
Iterable<ai.djl.modality.cv.output.Point> pathIterator = rectangle.getPath();
|
||||||
|
for (Iterator iter = pathIterator.iterator(); iter.hasNext(); ) {
|
||||||
|
me.aias.ocr.model.Point point = new me.aias.ocr.model.Point();
|
||||||
|
ai.djl.modality.cv.output.Point djlPoint = (ai.djl.modality.cv.output.Point) iter.next();
|
||||||
|
point.setX((int) (djlPoint.getX() * image.getWidth()));
|
||||||
|
point.setY((int) (djlPoint.getY() * image.getHeight()));
|
||||||
|
points.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
labelBean.setPoints(points);
|
||||||
|
labelBean.setCenterPoint(PointUtils.getCenterPoint(points));
|
||||||
|
detectedTexts.add(labelBean);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<ai.djl.modality.cv.output.Point> srcPoints = new ArrayList<>();
|
||||||
|
List<ai.djl.modality.cv.output.Point> dstPoints = new ArrayList<>();
|
||||||
|
for (int i = 0; i < anchorlabels.size(); i++) {
|
||||||
|
String anchorText = anchorlabels.get(i).getValue();
|
||||||
|
for (int j = 0; j < detectedTexts.size(); j++) {
|
||||||
|
String detectedText = detectedTexts.get(j).getValue();
|
||||||
|
if (detectedText.equals(anchorText)) {
|
||||||
|
double x = anchorlabels.get(i).getCenterPoint().getX();
|
||||||
|
double y = anchorlabels.get(i).getCenterPoint().getY();
|
||||||
|
ai.djl.modality.cv.output.Point point = new ai.djl.modality.cv.output.Point(x, y);
|
||||||
|
srcPoints.add(point);
|
||||||
|
|
||||||
|
x = detectedTexts.get(j).getCenterPoint().getX();
|
||||||
|
y = detectedTexts.get(j).getCenterPoint().getY();
|
||||||
|
point = new ai.djl.modality.cv.output.Point(x, y);
|
||||||
|
dstPoints.add(point);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Point2f srcPoint2f = null;
|
||||||
|
Point2f dstPoint2f = null;
|
||||||
|
Mat warp_mat = null;
|
||||||
|
|
||||||
|
if (dstPoints.size() == 3) {
|
||||||
|
srcPoint2f = NDArrayUtils.toOpenCVPoint2f(srcPoints, 3);
|
||||||
|
dstPoint2f = NDArrayUtils.toOpenCVPoint2f(dstPoints, 3);
|
||||||
|
//3点仿射变换
|
||||||
|
warp_mat = opencv_imgproc.getAffineTransform(srcPoint2f.position(0), dstPoint2f.position(0));
|
||||||
|
} else if (dstPoints.size() >= 4) {
|
||||||
|
srcPoint2f = NDArrayUtils.toOpenCVPoint2f(srcPoints, 4);
|
||||||
|
dstPoint2f = NDArrayUtils.toOpenCVPoint2f(dstPoints, 4);
|
||||||
|
//4点透视变换
|
||||||
|
warp_mat = opencv_imgproc.getPerspectiveTransform(srcPoint2f.position(0), dstPoint2f.position(0));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (dstPoints.size() >= 3 && save) {
|
||||||
|
// 模板图片透视变换,跟上传图片对齐
|
||||||
|
Mat mat = Java2DFrameUtils.toMat(templateImg);
|
||||||
|
if (dstPoints.size() == 3) { //3点仿射变换
|
||||||
|
mat = OpenCVUtils.affineTransform(mat, srcPoint2f, dstPoint2f);
|
||||||
|
templateImg = Java2DFrameUtils.toBufferedImage(mat);
|
||||||
|
DJLImageUtils.saveImage(templateImg, "affineTransform.png", fileRelativePath);
|
||||||
|
} else if (dstPoints.size() >= 4) { //4点透视变换
|
||||||
|
mat = OpenCVUtils.perspectiveTransform(mat, srcPoint2f, dstPoint2f);
|
||||||
|
templateImg = Java2DFrameUtils.toBufferedImage(mat);
|
||||||
|
DJLImageUtils.saveImage(templateImg, "perspectiveTransform.png", fileRelativePath);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 内容识别区 - 计算中心点坐标,用于距离计算
|
||||||
|
for (int i = 0; i < contentLabels.size(); i++) {
|
||||||
|
List<me.aias.ocr.model.Point> points = contentLabels.get(i).getPoints();
|
||||||
|
|
||||||
|
//根据变换矩阵,对所有点坐标进行坐标变换
|
||||||
|
if (dstPoints.size() >= 3) {
|
||||||
|
points = PointUtils.transformPoints(manager, warp_mat, points);
|
||||||
|
}
|
||||||
|
ai.djl.modality.cv.output.Point point = PointUtils.getCenterPoint(points);
|
||||||
|
|
||||||
|
if (dstPoints.size() < 3) { //无坐标变换,则将坐标归一化(坐标变为占整张图片的百分比)
|
||||||
|
double x = point.getX() / templateImg.getHeight();
|
||||||
|
double y = point.getY() / templateImg.getWidth();
|
||||||
|
ai.djl.modality.cv.output.Point djlPoint = new ai.djl.modality.cv.output.Point(x, y);
|
||||||
|
contentLabels.get(i).setCenterPoint(djlPoint);
|
||||||
|
} else {
|
||||||
|
contentLabels.get(i).setCenterPoint(point);
|
||||||
|
}
|
||||||
|
if (save) {
|
||||||
|
Color c = new Color(0, 255, 0);
|
||||||
|
DJLImageUtils.drawImageRect((BufferedImage) image.getWrappedImage(), (int) point.getX(), (int) point.getY(), 4, 4, c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 文本检测区 - 中心点坐标根据透视变换矩阵进行坐标变换
|
||||||
|
for (int i = 0; i < detectedTexts.size(); i++) {
|
||||||
|
List<me.aias.ocr.model.Point> points = detectedTexts.get(i).getPoints();
|
||||||
|
ai.djl.modality.cv.output.Point point = PointUtils.getCenterPoint(points);
|
||||||
|
|
||||||
|
if (dstPoints.size() < 3) { //无坐标变换,则将坐标归一化(坐标变为占整张图片的百分比)
|
||||||
|
double x = point.getX() / image.getHeight();
|
||||||
|
double y = point.getY() / image.getWidth();
|
||||||
|
ai.djl.modality.cv.output.Point djlPoint = new ai.djl.modality.cv.output.Point(x, y);
|
||||||
|
detectedTexts.get(i).setCenterPoint(djlPoint);
|
||||||
|
} else {
|
||||||
|
detectedTexts.get(i).setCenterPoint(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
DJLImageUtils.drawImageRect((BufferedImage) image.getWrappedImage(), (int) point.getX(), (int) point.getY(), 4, 4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Map<String, String> hashMap = new ConcurrentHashMap<>();
|
||||||
|
if (distance.equalsIgnoreCase("IOU")) {
|
||||||
|
hashMap = DistanceUtils.iou(contentLabels, detectedTexts);
|
||||||
|
} else {
|
||||||
|
hashMap = DistanceUtils.l2Distance(contentLabels, detectedTexts);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
// 保存图
|
||||||
|
DJLImageUtils.saveImage((BufferedImage) image.getWrappedImage(), "points_result.png", fileRelativePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.Model;
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.util.NDImageUtils;
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDList;
|
||||||
|
import ai.djl.translate.Batchifier;
|
||||||
|
import ai.djl.translate.Translator;
|
||||||
|
import ai.djl.translate.TranslatorContext;
|
||||||
|
import ai.djl.util.Utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public class PpWordRecognitionTranslator implements Translator<Image, String> {
|
||||||
|
|
||||||
|
private List<String> table;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(TranslatorContext ctx) throws IOException {
|
||||||
|
Model model = ctx.getModel();
|
||||||
|
// ppocr_keys_v1.txt
|
||||||
|
try (InputStream is = model.getArtifact("ppocr_keys_v1.txt").openStream()) {
|
||||||
|
table = Utils.readLines(is, true);
|
||||||
|
table.add(0, "blank");
|
||||||
|
table.add("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String processOutput(TranslatorContext ctx, NDList list) throws IOException {
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
NDArray tokens = list.singletonOrThrow();
|
||||||
|
long[] indices = tokens.get(0).argMax(1).toLongArray();
|
||||||
|
int lastIdx = 0;
|
||||||
|
for (int i = 0; i < indices.length; i++) {
|
||||||
|
if (indices[i] > 0 && !(i > 0 && indices[i] == lastIdx)) {
|
||||||
|
sb.append(table.get((int) indices[i]));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NDList processInput(TranslatorContext ctx, Image input) {
|
||||||
|
NDArray img = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
|
||||||
|
// int[] hw = resize32(input.getHeight(), input.getWidth());
|
||||||
|
|
||||||
|
int h = input.getHeight();
|
||||||
|
int w = input.getWidth();
|
||||||
|
float ratio = (float) w / (float) h;
|
||||||
|
int resized_w = (int) (Math.ceil(32 * ratio));
|
||||||
|
|
||||||
|
// img = NDImageUtils.resize(img, hw[1], hw[0]);
|
||||||
|
img = NDImageUtils.resize(img, resized_w, 32);
|
||||||
|
|
||||||
|
img = NDImageUtils.toTensor(img).sub(0.5f).div(0.5f);
|
||||||
|
|
||||||
|
img = img.expandDims(0);
|
||||||
|
return new NDList(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Batchifier getBatchifier() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int[] resize32(double h, double w) {
|
||||||
|
double h32Ratio = h / 32d;
|
||||||
|
double w32 = w / h32Ratio;
|
||||||
|
int w32Ratio = (int) Math.round(w32 / 32d);
|
||||||
|
return new int[]{32, w32Ratio * 32}; // height: 32 (fixed), width: 32 * N
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,147 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.Device;
|
||||||
|
import ai.djl.MalformedModelException;
|
||||||
|
import ai.djl.ModelException;
|
||||||
|
import ai.djl.inference.Predictor;
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.modality.cv.util.NDImageUtils;
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import ai.djl.paddlepaddle.zoo.cv.objectdetection.PpWordDetectionTranslator;
|
||||||
|
import ai.djl.repository.zoo.Criteria;
|
||||||
|
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||||
|
import ai.djl.repository.zoo.ModelZoo;
|
||||||
|
import ai.djl.repository.zoo.ZooModel;
|
||||||
|
import ai.djl.training.util.ProgressBar;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.TableResult;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public final class RecognitionModel {
|
||||||
|
private ZooModel<Image, DetectedObjects> detectionModel;
|
||||||
|
private ZooModel<Image, String> recognitionModel;
|
||||||
|
private Predictor<Image, String> recognizer;
|
||||||
|
private Predictor<Image, DetectedObjects> detector;
|
||||||
|
|
||||||
|
public void init(String detUri, String recUri) throws MalformedModelException, ModelNotFoundException, IOException {
|
||||||
|
this.detectionModel = ModelZoo.loadModel(detectCriteria(detUri));
|
||||||
|
this.recognitionModel = ModelZoo.loadModel(recognizeCriteria(recUri));
|
||||||
|
this.recognizer = recognitionModel.newPredictor();
|
||||||
|
this.detector = detectionModel.newPredictor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
this.detectionModel.close();
|
||||||
|
this.recognitionModel.close();
|
||||||
|
this.recognizer.close();
|
||||||
|
this.detector.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String predictSingleLineText(Image image)
|
||||||
|
throws TranslateException {
|
||||||
|
String text = recognizer.predict(image);
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
public DetectedObjects predict(Image image)
|
||||||
|
throws TranslateException {
|
||||||
|
DetectedObjects detections = detector.predict(image);
|
||||||
|
List<DetectedObjects.DetectedObject> boxes = detections.items();
|
||||||
|
List<String> names = new ArrayList<>();
|
||||||
|
List<Double> prob = new ArrayList<>();
|
||||||
|
List<BoundingBox> rect = new ArrayList<>();
|
||||||
|
for (int i = 0; i < boxes.size(); i++) {
|
||||||
|
Image subImg = getSubImage(image, boxes.get(i).getBoundingBox());
|
||||||
|
if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
|
||||||
|
subImg = rotateImg(subImg);
|
||||||
|
}
|
||||||
|
String name = recognizer.predict(subImg);
|
||||||
|
System.out.println(name);
|
||||||
|
names.add(name);
|
||||||
|
prob.add(-1.0);
|
||||||
|
rect.add(boxes.get(i).getBoundingBox());
|
||||||
|
}
|
||||||
|
DetectedObjects detectedObjects = new DetectedObjects(names, prob, rect);
|
||||||
|
return detectedObjects;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria<Image, DetectedObjects> detectCriteria(String detUri) {
|
||||||
|
Criteria<Image, DetectedObjects> criteria =
|
||||||
|
Criteria.builder()
|
||||||
|
.optEngine("PaddlePaddle")
|
||||||
|
.setTypes(Image.class, DetectedObjects.class)
|
||||||
|
.optModelUrls(detUri)
|
||||||
|
// .optDevice(Device.cpu())
|
||||||
|
.optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap<String, String>()))
|
||||||
|
.optProgress(new ProgressBar())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria<Image, String> recognizeCriteria(String recUri) {
|
||||||
|
Criteria<Image, String> criteria =
|
||||||
|
Criteria.builder()
|
||||||
|
.optEngine("PaddlePaddle")
|
||||||
|
.setTypes(Image.class, String.class)
|
||||||
|
.optModelUrls(recUri)
|
||||||
|
// .optDevice(Device.cpu())
|
||||||
|
.optProgress(new ProgressBar())
|
||||||
|
.optTranslator(new PpWordRecognitionTranslator())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image getSubImage(Image img, BoundingBox box) {
|
||||||
|
Rectangle rect = box.getBounds();
|
||||||
|
double[] extended = extendRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
|
||||||
|
int width = img.getWidth();
|
||||||
|
int height = img.getHeight();
|
||||||
|
int[] recovered = {
|
||||||
|
(int) (extended[0] * width),
|
||||||
|
(int) (extended[1] * height),
|
||||||
|
(int) (extended[2] * width),
|
||||||
|
(int) (extended[3] * height)
|
||||||
|
};
|
||||||
|
return img.getSubImage(recovered[0], recovered[1], recovered[2], recovered[3]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private double[] extendRect(double xmin, double ymin, double width, double height) {
|
||||||
|
double centerx = xmin + width / 2;
|
||||||
|
double centery = ymin + height / 2;
|
||||||
|
if (width > height) {
|
||||||
|
width += height * 2.0;
|
||||||
|
height *= 3.0;
|
||||||
|
} else {
|
||||||
|
height += width * 2.0;
|
||||||
|
width *= 3.0;
|
||||||
|
}
|
||||||
|
double newX = centerx - width / 2 < 0 ? 0 : centerx - width / 2;
|
||||||
|
double newY = centery - height / 2 < 0 ? 0 : centery - height / 2;
|
||||||
|
double newWidth = newX + width > 1 ? 1 - newX : width;
|
||||||
|
double newHeight = newY + height > 1 ? 1 - newY : height;
|
||||||
|
return new double[]{newX, newY, newWidth, newHeight};
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image rotateImg(Image image) {
|
||||||
|
try (NDManager manager = NDManager.newBaseManager()) {
|
||||||
|
NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), 1);
|
||||||
|
return ImageFactory.getInstance().fromNDArray(rotated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,249 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.Device;
|
||||||
|
import ai.djl.MalformedModelException;
|
||||||
|
import ai.djl.inference.Predictor;
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.repository.zoo.Criteria;
|
||||||
|
import ai.djl.repository.zoo.ModelNotFoundException;
|
||||||
|
import ai.djl.repository.zoo.ModelZoo;
|
||||||
|
import ai.djl.repository.zoo.ZooModel;
|
||||||
|
import ai.djl.training.util.ProgressBar;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.TableResult;
|
||||||
|
import org.apache.commons.collections.CollectionUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.tuple.Pair;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public final class TableDetectionModel {
|
||||||
|
private ZooModel<Image, TableResult> model;
|
||||||
|
private Predictor<Image, TableResult> predictor;
|
||||||
|
|
||||||
|
public void init(String tableUri) throws MalformedModelException, ModelNotFoundException, IOException {
|
||||||
|
this.model = ModelZoo.loadModel(detectCriteria(tableUri));
|
||||||
|
this.predictor = model.newPredictor();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close() {
|
||||||
|
this.model.close();
|
||||||
|
this.predictor.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTableHtml(Image image, DetectedObjects textDetections) throws TranslateException {
|
||||||
|
// Table cell detection
|
||||||
|
TableResult tableResult = predictor.predict(image);
|
||||||
|
List<BoundingBox> cells = tableResult.getBoxes();
|
||||||
|
|
||||||
|
List<DetectedObjects.DetectedObject> dt_boxes = textDetections.items();
|
||||||
|
|
||||||
|
// 获取 Cell 与 文本检测框 的对应关系(1:N)。
|
||||||
|
Map<Integer, List<Integer>> matched = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
for (int i = 0; i < dt_boxes.size(); i++) {
|
||||||
|
DetectedObjects.DetectedObject item = dt_boxes.get(i);
|
||||||
|
Rectangle textBounds = item.getBoundingBox().getBounds();
|
||||||
|
int[] box_1 = rectXYXY(textBounds, image.getWidth(), image.getHeight());
|
||||||
|
// 获取两两cell之间的L1距离和 1- IOU
|
||||||
|
List<Pair<Float, Float>> distances = new ArrayList<>();
|
||||||
|
for (BoundingBox cell : cells) {
|
||||||
|
Rectangle cellBounds = cell.getBounds();
|
||||||
|
int[] box_2 = rectXYXY(cellBounds, image.getWidth(), image.getHeight());
|
||||||
|
float distance = distance(box_1, box_2);
|
||||||
|
float iou = 1 - compute_iou(box_1, box_2);
|
||||||
|
distances.add(Pair.of(distance, iou));
|
||||||
|
}
|
||||||
|
// 根据距离和IOU挑选最"近"的cell
|
||||||
|
Pair<Float, Float> nearest = sorted(distances);
|
||||||
|
|
||||||
|
// 获取最小距离对应的下标id,也等价于cell的下标id (distances列表是根据遍历cells生成的)
|
||||||
|
int id = 0;
|
||||||
|
for (int idx = 0; idx < distances.size(); idx++) {
|
||||||
|
Pair<Float, Float> current = distances.get(idx);
|
||||||
|
if (current.getLeft().floatValue() == nearest.getLeft().floatValue()
|
||||||
|
&& current.getRight().floatValue() == nearest.getRight().floatValue()) {
|
||||||
|
id = idx;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!matched.containsKey(id)) {
|
||||||
|
List<Integer> textIds = new ArrayList<>();
|
||||||
|
textIds.add(i);
|
||||||
|
// cell id, text id list (dt_boxes index list)
|
||||||
|
matched.put(id, textIds);
|
||||||
|
} else {
|
||||||
|
matched.get(id).add(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> cell_contents = new ArrayList<>();
|
||||||
|
List<Double> probs = new ArrayList<>();
|
||||||
|
for (int i = 0; i < cells.size(); i++) {
|
||||||
|
List<Integer> textIds = matched.get(i);
|
||||||
|
List<String> contents = new ArrayList<>();
|
||||||
|
String content = "";
|
||||||
|
if (textIds != null) {
|
||||||
|
for (Integer id : textIds) {
|
||||||
|
DetectedObjects.DetectedObject item = dt_boxes.get(id);
|
||||||
|
contents.add(item.getClassName());
|
||||||
|
}
|
||||||
|
content = StringUtils.join(contents, " ");
|
||||||
|
}
|
||||||
|
|
||||||
|
cell_contents.add(content);
|
||||||
|
probs.add(-1.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> pred_structures = tableResult.getStructure_str_list();
|
||||||
|
return getPredHtml(pred_structures, cell_contents);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generate table html
|
||||||
|
*
|
||||||
|
* @param pred_structures
|
||||||
|
* @param cell_contents
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private String getPredHtml(List<String> pred_structures, List<String> cell_contents) {
|
||||||
|
StringBuffer html = new StringBuffer();
|
||||||
|
int td_index = 0;
|
||||||
|
for (String tag : pred_structures) {
|
||||||
|
if (tag.contains("</td>")) {
|
||||||
|
String content = cell_contents.get(td_index);
|
||||||
|
html.append(content);
|
||||||
|
td_index++;
|
||||||
|
}
|
||||||
|
html.append(tag);
|
||||||
|
}
|
||||||
|
|
||||||
|
return html.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Criteria<Image, TableResult> detectCriteria(String tableUri) {
|
||||||
|
|
||||||
|
Criteria<Image, TableResult> criteria =
|
||||||
|
Criteria.builder()
|
||||||
|
.optEngine("PaddlePaddle")
|
||||||
|
.setTypes(Image.class, TableResult.class)
|
||||||
|
.optModelUrls(tableUri)
|
||||||
|
// .optDevice(Device.cpu())
|
||||||
|
.optOption("removePass", "repeated_fc_relu_fuse_pass")
|
||||||
|
.optTranslator(new TableStructTranslator(new ConcurrentHashMap<String, String>()))
|
||||||
|
.optProgress(new ProgressBar())
|
||||||
|
.build();
|
||||||
|
|
||||||
|
return criteria;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate L1 distance
|
||||||
|
*
|
||||||
|
* @param box_1
|
||||||
|
* @param box_2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int distance(int[] box_1, int[] box_2) {
|
||||||
|
int x1 = box_1[0];
|
||||||
|
int y1 = box_1[1];
|
||||||
|
int x2 = box_1[2];
|
||||||
|
int y2 = box_1[3];
|
||||||
|
int x3 = box_2[0];
|
||||||
|
int y3 = box_2[1];
|
||||||
|
int x4 = box_2[2];
|
||||||
|
int y4 = box_2[3];
|
||||||
|
int dis = Math.abs(x3 - x1) + Math.abs(y3 - y1) + Math.abs(x4 - x2) + Math.abs(y4 - y2);
|
||||||
|
int dis_2 = Math.abs(x3 - x1) + Math.abs(y3 - y1);
|
||||||
|
int dis_3 = Math.abs(x4 - x2) + Math.abs(y4 - y2);
|
||||||
|
return dis + Math.min(dis_2, dis_3);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get absolute coordinations
|
||||||
|
*
|
||||||
|
* @param rect
|
||||||
|
* @param width
|
||||||
|
* @param height
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private int[] rectXYXY(Rectangle rect, int width, int height) {
|
||||||
|
int left = Math.max((int) (width * rect.getX()), 0);
|
||||||
|
int top = Math.max((int) (height * rect.getY()), 0);
|
||||||
|
int right = Math.min((int) (width * (rect.getX() + rect.getWidth())), width - 1);
|
||||||
|
int bottom = Math.min((int) (height * (rect.getY() + rect.getHeight())), height - 1);
|
||||||
|
return new int[]{left, top, right, bottom};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* computing IoU
|
||||||
|
*
|
||||||
|
* @param rec1: (y0, x0, y1, x1), which reflects (top, left, bottom, right)
|
||||||
|
* @param rec2: (y0, x0, y1, x1)
|
||||||
|
* @return scala value of IoU
|
||||||
|
*/
|
||||||
|
private float compute_iou(int[] rec1, int[] rec2) {
|
||||||
|
// computing area of each rectangles
|
||||||
|
int S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1]);
|
||||||
|
int S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1]);
|
||||||
|
|
||||||
|
// computing the sum_area
|
||||||
|
int sum_area = S_rec1 + S_rec2;
|
||||||
|
|
||||||
|
// find the each edge of intersect rectangle
|
||||||
|
int left_line = Math.max(rec1[1], rec2[1]);
|
||||||
|
int right_line = Math.min(rec1[3], rec2[3]);
|
||||||
|
int top_line = Math.max(rec1[0], rec2[0]);
|
||||||
|
int bottom_line = Math.min(rec1[2], rec2[2]);
|
||||||
|
|
||||||
|
// judge if there is an intersect
|
||||||
|
if (left_line >= right_line || top_line >= bottom_line) {
|
||||||
|
return 0.0f;
|
||||||
|
} else {
|
||||||
|
float intersect = (right_line - left_line) * (bottom_line - top_line);
|
||||||
|
return (intersect / (sum_area - intersect)) * 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Distance sorted
|
||||||
|
*
|
||||||
|
* @param distances
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private Pair<Float, Float> sorted(List<Pair<Float, Float>> distances) {
|
||||||
|
Comparator<Pair<Float, Float>> comparator =
|
||||||
|
new Comparator<Pair<Float, Float>>() {
|
||||||
|
@Override
|
||||||
|
public int compare(Pair<Float, Float> a1, Pair<Float, Float> a2) {
|
||||||
|
// order by IoU first
|
||||||
|
if (a1.getRight().floatValue() > a2.getRight().floatValue()) {
|
||||||
|
return 1;
|
||||||
|
} else if (a1.getRight().floatValue() == a2.getRight().floatValue()) {
|
||||||
|
// Then order by L1 distance
|
||||||
|
if (a1.getLeft().floatValue() > a2.getLeft().floatValue()) {
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Sort distances
|
||||||
|
List<Pair<Float, Float>> newDistances = new ArrayList<>();
|
||||||
|
CollectionUtils.addAll(newDistances, new Object[distances.size()]);
|
||||||
|
Collections.copy(newDistances, distances);
|
||||||
|
Collections.sort(newDistances, comparator);
|
||||||
|
return newDistances.get(0);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,247 @@
|
|||||||
|
package me.aias.ocr.inference;
|
||||||
|
|
||||||
|
import ai.djl.Model;
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.modality.cv.util.NDImageUtils;
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDArrays;
|
||||||
|
import ai.djl.ndarray.NDList;
|
||||||
|
import ai.djl.ndarray.index.NDIndex;
|
||||||
|
import ai.djl.ndarray.types.DataType;
|
||||||
|
import ai.djl.ndarray.types.Shape;
|
||||||
|
import ai.djl.translate.Batchifier;
|
||||||
|
import ai.djl.translate.Translator;
|
||||||
|
import ai.djl.translate.TranslatorContext;
|
||||||
|
import ai.djl.util.Utils;
|
||||||
|
import me.aias.ocr.model.TableResult;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
public class TableStructTranslator implements Translator<Image, TableResult> {
|
||||||
|
|
||||||
|
private final int maxLength;
|
||||||
|
private int height;
|
||||||
|
private int width;
|
||||||
|
private float xScale = 1.0f;
|
||||||
|
private float yScale = 1.0f;
|
||||||
|
|
||||||
|
public TableStructTranslator(Map<String, ?> arguments) {
|
||||||
|
maxLength =
|
||||||
|
arguments.containsKey("maxLength")
|
||||||
|
? Integer.parseInt(arguments.get("maxLength").toString())
|
||||||
|
: 488;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<String, String> dict_idx_character = new ConcurrentHashMap<>();
|
||||||
|
private Map<String, String> dict_character_idx = new ConcurrentHashMap<>();
|
||||||
|
private Map<String, String> dict_idx_elem = new ConcurrentHashMap<>();
|
||||||
|
private Map<String, String> dict_elem_idx = new ConcurrentHashMap<>();
|
||||||
|
private String beg_str = "sos";
|
||||||
|
private String end_str = "eos";
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void prepare(TranslatorContext ctx) throws IOException {
|
||||||
|
Model model = ctx.getModel();
|
||||||
|
// ppocr_keys_v1.txt
|
||||||
|
try (InputStream is = model.getArtifact("table_structure_dict.txt").openStream()) {
|
||||||
|
List<String> lines = Utils.readLines(is, false);
|
||||||
|
String[] substr = lines.get(0).trim().split("\\t");
|
||||||
|
int characterNum = Integer.parseInt(substr[0]);
|
||||||
|
int elemNum = Integer.parseInt(substr[1]);
|
||||||
|
|
||||||
|
List<String> listCharacter = new ArrayList<>();
|
||||||
|
List<String> listElem = new ArrayList<>();
|
||||||
|
for (int i = 1; i < 1 + characterNum; i++) {
|
||||||
|
listCharacter.add(lines.get(i).trim());
|
||||||
|
}
|
||||||
|
for (int i = 1 + characterNum; i < 1 + characterNum + elemNum; i++) {
|
||||||
|
listElem.add(lines.get(i).trim());
|
||||||
|
}
|
||||||
|
listCharacter.add(0, beg_str);
|
||||||
|
listCharacter.add(end_str);
|
||||||
|
listElem.add(0, beg_str);
|
||||||
|
listElem.add(end_str);
|
||||||
|
|
||||||
|
for (int i = 0; i < listCharacter.size(); i++) {
|
||||||
|
dict_idx_character.put("" + i, listCharacter.get(i));
|
||||||
|
dict_character_idx.put(listCharacter.get(i), "" + i);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < listElem.size(); i++) {
|
||||||
|
dict_idx_elem.put("" + i, listElem.get(i));
|
||||||
|
dict_elem_idx.put(listElem.get(i), "" + i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public NDList processInput(TranslatorContext ctx, Image input) {
|
||||||
|
NDArray img = input.toNDArray(ctx.getNDManager(), Image.Flag.COLOR);
|
||||||
|
height = input.getHeight();
|
||||||
|
width = input.getWidth();
|
||||||
|
|
||||||
|
// img = ResizeTableImage(img, height, width, maxLength);
|
||||||
|
// img = PaddingTableImage(ctx, img, maxLength);
|
||||||
|
|
||||||
|
img = NDImageUtils.resize(img, 488, 488);
|
||||||
|
|
||||||
|
// img = NDImageUtils.toTensor(img);
|
||||||
|
img = img.transpose(2, 0, 1).div(255).flip(0);
|
||||||
|
img =
|
||||||
|
NDImageUtils.normalize(
|
||||||
|
img, new float[] {0.485f, 0.456f, 0.406f}, new float[] {0.229f, 0.224f, 0.225f});
|
||||||
|
|
||||||
|
img = img.expandDims(0);
|
||||||
|
return new NDList(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public TableResult processOutput(TranslatorContext ctx, NDList list) {
|
||||||
|
NDArray locPreds = list.get(0);
|
||||||
|
NDArray structureProbs = list.get(1);
|
||||||
|
NDArray structure_idx = structureProbs.argMax(2);
|
||||||
|
NDArray structure_probs = structureProbs.max(new int[] {2});
|
||||||
|
|
||||||
|
List<List<String>> result_list = new ArrayList<>();
|
||||||
|
List<List<String>> result_pos_list = new ArrayList<>();
|
||||||
|
List<List<String>> result_score_list = new ArrayList<>();
|
||||||
|
List<List<String>> result_elem_idx_list = new ArrayList<>();
|
||||||
|
List<String> res_html_code_list = new ArrayList<>();
|
||||||
|
List<NDArray> res_loc_list = new ArrayList<>();
|
||||||
|
|
||||||
|
// get ignored tokens
|
||||||
|
int beg_idx = Integer.parseInt(dict_elem_idx.get(beg_str));
|
||||||
|
int end_idx = Integer.parseInt(dict_elem_idx.get(end_str));
|
||||||
|
|
||||||
|
long batch_size = structure_idx.size(0); // len(text_index)
|
||||||
|
for (int batch_idx = 0; batch_idx < batch_size; batch_idx++) {
|
||||||
|
List<String> char_list = new ArrayList<>();
|
||||||
|
List<String> elem_pos_list = new ArrayList<>();
|
||||||
|
List<String> elem_idx_list = new ArrayList<>();
|
||||||
|
List<String> score_list = new ArrayList<>();
|
||||||
|
|
||||||
|
long len = structure_idx.get(batch_idx).size();
|
||||||
|
for (int idx = 0; idx < len; idx++) {
|
||||||
|
int tmp_elem_idx = (int) structure_idx.get(batch_idx).get(idx).toLongArray()[0];
|
||||||
|
if (idx > 0 && tmp_elem_idx == end_idx) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (tmp_elem_idx == beg_idx || tmp_elem_idx == end_idx) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
char_list.add(dict_idx_elem.get("" + tmp_elem_idx));
|
||||||
|
elem_pos_list.add("" + idx);
|
||||||
|
score_list.add("" + structure_probs.get(batch_idx, idx).toFloatArray()[0]);
|
||||||
|
elem_idx_list.add("" + tmp_elem_idx);
|
||||||
|
}
|
||||||
|
|
||||||
|
result_list.add(char_list); // structure_str
|
||||||
|
result_pos_list.add(elem_pos_list);
|
||||||
|
result_score_list.add(score_list);
|
||||||
|
result_elem_idx_list.add(elem_idx_list);
|
||||||
|
}
|
||||||
|
|
||||||
|
int batch_num = result_list.size();
|
||||||
|
for (int bno = 0; bno < batch_num; bno++) {
|
||||||
|
NDList res_loc = new NDList();
|
||||||
|
int len = result_list.get(bno).size();
|
||||||
|
for (int sno = 0; sno < len; sno++) {
|
||||||
|
String text = result_list.get(bno).get(sno);
|
||||||
|
if (text.equals("<td>") || text.equals("<td")) {
|
||||||
|
int pos = Integer.parseInt(result_pos_list.get(bno).get(sno));
|
||||||
|
res_loc.add(locPreds.get(bno, pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String res_html_code = StringUtils.join(result_list.get(bno), "");
|
||||||
|
res_html_code_list.add(res_html_code);
|
||||||
|
NDArray array = NDArrays.stack(res_loc);
|
||||||
|
res_loc_list.add(array);
|
||||||
|
}
|
||||||
|
|
||||||
|
// structure_str_list result_list
|
||||||
|
// res_loc res_loc_list
|
||||||
|
List<BoundingBox> boxes = new ArrayList<>();
|
||||||
|
|
||||||
|
long rows = res_loc_list.get(0).size(0);
|
||||||
|
for (int rno = 0; rno < rows; rno++) {
|
||||||
|
float[] arr = res_loc_list.get(0).get(rno).toFloatArray();
|
||||||
|
Rectangle rect = new Rectangle(arr[0], arr[1], (arr[2] - arr[0]), (arr[3] - arr[1]));
|
||||||
|
boxes.add(rect);
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> structure_str_list = result_list.get(0);
|
||||||
|
structure_str_list.add(0, "<table>");
|
||||||
|
structure_str_list.add(0, "<body>");
|
||||||
|
structure_str_list.add(0, "<html>");
|
||||||
|
structure_str_list.add("</table>");
|
||||||
|
structure_str_list.add("</body>");
|
||||||
|
structure_str_list.add("</html>");
|
||||||
|
|
||||||
|
TableResult result = new TableResult(structure_str_list, boxes);
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Batchifier getBatchifier() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NDArray ResizeTableImage(NDArray img, int height, int width, int maxLen) {
|
||||||
|
int localMax = Math.max(height, width);
|
||||||
|
float ratio = maxLen * 1.0f / localMax;
|
||||||
|
int resize_h = (int) (height * ratio);
|
||||||
|
int resize_w = (int) (width * ratio);
|
||||||
|
if(width > height){
|
||||||
|
xScale = 1.0f;
|
||||||
|
yScale = ratio;
|
||||||
|
} else{
|
||||||
|
xScale = ratio;
|
||||||
|
yScale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
img = NDImageUtils.resize(img, resize_w, resize_h);
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
private NDArray PaddingTableImage(TranslatorContext ctx, NDArray img, int maxLen) {
|
||||||
|
|
||||||
|
Image srcImg = ImageFactory.getInstance().fromNDArray(img.duplicate());
|
||||||
|
saveImage(srcImg, "img.png", "build/output");
|
||||||
|
|
||||||
|
NDArray paddingImg = ctx.getNDManager().zeros(new Shape(maxLen, maxLen, 3), DataType.UINT8);
|
||||||
|
// NDManager manager = NDManager.newBaseManager();
|
||||||
|
// NDArray paddingImg = manager.zeros(new Shape(maxLen, maxLen, 3), DataType.UINT8);
|
||||||
|
paddingImg.set(
|
||||||
|
new NDIndex("0:" + img.getShape().get(0) + ",0:" + img.getShape().get(1) + ",:"), img);
|
||||||
|
Image image = ImageFactory.getInstance().fromNDArray(paddingImg);
|
||||||
|
|
||||||
|
saveImage(image, "paddingImg.png", "build/output");
|
||||||
|
|
||||||
|
return paddingImg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveImage(Image img, String name, String path) {
|
||||||
|
Path outputDir = Paths.get(path);
|
||||||
|
Path imagePath = outputDir.resolve(name);
|
||||||
|
// OpenJDK 不能保存 jpg 图片的 alpha channel
|
||||||
|
try {
|
||||||
|
img.save(Files.newOutputStream(imagePath), "png");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,37 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
public class CrossRangeCellMeta {
|
||||||
|
public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) {
|
||||||
|
super();
|
||||||
|
this.firstRowIndex = firstRowIndex;
|
||||||
|
this.firstColIndex = firstColIndex;
|
||||||
|
this.rowSpan = rowSpan;
|
||||||
|
this.colSpan = colSpan;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int firstRowIndex;
|
||||||
|
private int firstColIndex;
|
||||||
|
private int rowSpan;// 跨越行数
|
||||||
|
private int colSpan;// 跨越列数
|
||||||
|
|
||||||
|
public int getFirstRow() {
|
||||||
|
return firstRowIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastRow() {
|
||||||
|
return firstRowIndex + rowSpan - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getFirstCol() {
|
||||||
|
return firstColIndex;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getLastCol() {
|
||||||
|
return firstColIndex + colSpan - 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getColSpan(){
|
||||||
|
return colSpan;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,10 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class DataBean {
|
||||||
|
private String value;
|
||||||
|
private List<Point> points;
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LabelBean {
|
||||||
|
private int index;
|
||||||
|
private int active;
|
||||||
|
private String type;
|
||||||
|
private String value;
|
||||||
|
private String field;
|
||||||
|
private List<Point> points;
|
||||||
|
private ai.djl.modality.cv.output.Point centerPoint;
|
||||||
|
}
|
@ -0,0 +1,11 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class LabelDTO {
|
||||||
|
private String uid;
|
||||||
|
private LabelBean labelData;
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class Point {
|
||||||
|
private int x;
|
||||||
|
private int y;
|
||||||
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class ResultBean<T> implements Serializable {
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
private int code;
|
||||||
|
private String value;
|
||||||
|
private Map<String, Object> data = new HashMap<String, Object>();
|
||||||
|
|
||||||
|
public static ResultBean success() {
|
||||||
|
ResultBean rb = new ResultBean();
|
||||||
|
rb.setCode(0);
|
||||||
|
rb.setValue("Success");
|
||||||
|
return rb;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ResultBean failure() {
|
||||||
|
ResultBean msg = new ResultBean();
|
||||||
|
msg.setCode(-1);
|
||||||
|
msg.setValue("Failure");
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultBean() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public ResultBean add(String key, Object value) {
|
||||||
|
this.getData().put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TableResult {
|
||||||
|
private List<String> structure_str_list;
|
||||||
|
private List<BoundingBox> boxes;
|
||||||
|
|
||||||
|
public TableResult(List<String> structure_str_list, List<BoundingBox> boxes) {
|
||||||
|
this.structure_str_list = structure_str_list;
|
||||||
|
this.boxes = boxes;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
package me.aias.ocr.model;
|
||||||
|
|
||||||
|
import lombok.Data;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
@Data
|
||||||
|
public class TemplateBean {
|
||||||
|
private String uid;
|
||||||
|
private String name;
|
||||||
|
private String imageName;
|
||||||
|
List<LabelBean> labelData;
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package me.aias.ocr.service;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.DataBean;
|
||||||
|
import me.aias.ocr.model.TemplateBean;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public interface InferService {
|
||||||
|
List<DataBean> getGeneralInfo(Image image) throws TranslateException;
|
||||||
|
}
|
@ -0,0 +1,16 @@
|
|||||||
|
package me.aias.ocr.service;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.DataBean;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public interface TableInferService {
|
||||||
|
String getTableHtml(Image image) throws TranslateException;
|
||||||
|
List<String> getTableHtmlList(Image image) throws TranslateException;
|
||||||
|
}
|
@ -0,0 +1,31 @@
|
|||||||
|
package me.aias.ocr.service;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.model.LabelBean;
|
||||||
|
import me.aias.ocr.model.TemplateBean;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public interface TemplateService {
|
||||||
|
Map<String, String> getImageInfo(TemplateBean templateBean, Image image) throws TranslateException, IOException;
|
||||||
|
|
||||||
|
List<TemplateBean> getTemplateList();
|
||||||
|
|
||||||
|
TemplateBean getTemplate(String uid) throws IOException;
|
||||||
|
|
||||||
|
void addTemplate(TemplateBean templateBean) throws IOException;
|
||||||
|
|
||||||
|
void updateTemplate(TemplateBean templateBean) throws IOException;
|
||||||
|
|
||||||
|
void removeTemplate(String uid) throws IOException;
|
||||||
|
|
||||||
|
String getLabelData(String uid, LabelBean labelData) throws IOException, TranslateException;
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package me.aias.ocr.service.impl;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import me.aias.ocr.inference.LayoutDetectionModel;
|
||||||
|
import me.aias.ocr.inference.PerspectiveRecogition;
|
||||||
|
import me.aias.ocr.inference.RecognitionModel;
|
||||||
|
import me.aias.ocr.inference.TableDetectionModel;
|
||||||
|
import me.aias.ocr.model.*;
|
||||||
|
import me.aias.ocr.service.InferService;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class InferServiceImpl implements InferService {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(InferServiceImpl.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RecognitionModel recognitionModel;
|
||||||
|
|
||||||
|
public List<DataBean> getGeneralInfo(Image image) throws TranslateException {
|
||||||
|
List<DataBean> dataList = new ArrayList<>();
|
||||||
|
DetectedObjects detectedObjects = recognitionModel.predict(image);
|
||||||
|
List<DetectedObjects.DetectedObject> list = detectedObjects.items();
|
||||||
|
for (DetectedObjects.DetectedObject result : list) {
|
||||||
|
DataBean dataBean = new DataBean();
|
||||||
|
List<Point> points = new ArrayList<>();
|
||||||
|
String className = result.getClassName();
|
||||||
|
dataBean.setValue(className);
|
||||||
|
BoundingBox box = result.getBoundingBox();
|
||||||
|
Rectangle rectangle = box.getBounds();
|
||||||
|
|
||||||
|
Iterable<ai.djl.modality.cv.output.Point> pathIterator = rectangle.getPath();
|
||||||
|
for (Iterator iter = pathIterator.iterator(); iter.hasNext(); ) {
|
||||||
|
Point point = new Point();
|
||||||
|
ai.djl.modality.cv.output.Point djlPoint = (ai.djl.modality.cv.output.Point) iter.next();
|
||||||
|
point.setX((int) (djlPoint.getX() * image.getWidth()));
|
||||||
|
point.setY((int) (djlPoint.getY() * image.getHeight()));
|
||||||
|
points.add(point);
|
||||||
|
}
|
||||||
|
|
||||||
|
dataBean.setPoints(points);
|
||||||
|
dataList.add(dataBean);
|
||||||
|
}
|
||||||
|
return dataList;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,77 @@
|
|||||||
|
package me.aias.ocr.service.impl;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.output.BoundingBox;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
import ai.djl.modality.cv.output.Rectangle;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import me.aias.ocr.inference.LayoutDetectionModel;
|
||||||
|
import me.aias.ocr.inference.RecognitionModel;
|
||||||
|
import me.aias.ocr.inference.TableDetectionModel;
|
||||||
|
import me.aias.ocr.model.DataBean;
|
||||||
|
import me.aias.ocr.model.Point;
|
||||||
|
import me.aias.ocr.service.InferService;
|
||||||
|
import me.aias.ocr.service.TableInferService;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TableInferServiceImpl implements TableInferService {
|
||||||
|
private Logger logger = LoggerFactory.getLogger(TableInferServiceImpl.class);
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private RecognitionModel recognitionModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private TableDetectionModel tableDetectionModel;
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private LayoutDetectionModel layoutDetectionModel;
|
||||||
|
|
||||||
|
public String getTableHtml(Image image) throws TranslateException {
|
||||||
|
DetectedObjects textDetections = recognitionModel.predict(image);
|
||||||
|
String tableHtml = tableDetectionModel.getTableHtml(image, textDetections);
|
||||||
|
return tableHtml;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<String> getTableHtmlList(Image image) throws TranslateException {
|
||||||
|
List<String> tableHtmlList = new ArrayList<>();
|
||||||
|
DetectedObjects layoutDetections = layoutDetectionModel.predict(image);
|
||||||
|
|
||||||
|
List<DetectedObjects.DetectedObject> boxes = layoutDetections.items();
|
||||||
|
for (int i = 0; i < boxes.size(); i++) {
|
||||||
|
// TODO 模型需优化, 页面出现多个表不准,但是当前可以用于表单中一个表格自动检测识别
|
||||||
|
if (boxes.get(i).getClassName().equals("Table")) {
|
||||||
|
Image subImage = getSubImage(image, boxes.get(i).getBoundingBox());
|
||||||
|
// 表格单元检测
|
||||||
|
DetectedObjects textDetections = recognitionModel.predict(subImage);
|
||||||
|
String tableHtml = tableDetectionModel.getTableHtml(subImage, textDetections);
|
||||||
|
tableHtmlList.add(tableHtml);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return tableHtmlList;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Image getSubImage(Image img, BoundingBox box) {
|
||||||
|
Rectangle rect = box.getBounds();
|
||||||
|
int width = img.getWidth();
|
||||||
|
int height = img.getHeight();
|
||||||
|
int[] recovered = {
|
||||||
|
(int) (rect.getX() * width),
|
||||||
|
(int) (rect.getY() * height),
|
||||||
|
(int) (rect.getWidth() * width),
|
||||||
|
(int) (rect.getHeight() * height)
|
||||||
|
};
|
||||||
|
return img.getSubImage(recovered[0], recovered[1], recovered[2], recovered[3]);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,209 @@
|
|||||||
|
package me.aias.ocr.service.impl;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import ai.djl.translate.TranslateException;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import com.google.gson.reflect.TypeToken;
|
||||||
|
import me.aias.ocr.configuration.FileProperties;
|
||||||
|
import me.aias.ocr.inference.PerspectiveRecogition;
|
||||||
|
import me.aias.ocr.inference.RecognitionModel;
|
||||||
|
import me.aias.ocr.model.LabelBean;
|
||||||
|
import me.aias.ocr.model.TemplateBean;
|
||||||
|
import me.aias.ocr.service.TemplateService;
|
||||||
|
import me.aias.ocr.utils.FileUtils;
|
||||||
|
import me.aias.ocr.utils.PointUtils;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.slf4j.Logger;
|
||||||
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.BeanUtils;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.beans.factory.annotation.Value;
|
||||||
|
import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
@Service
|
||||||
|
public class TemplateServiceImpl implements TemplateService {
|
||||||
|
private static final String TEMPLATE_LIST_FILE = "templates.json";
|
||||||
|
private Logger logger = LoggerFactory.getLogger(TemplateServiceImpl.class);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* file configuration
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private FileProperties properties;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ocr recognition model
|
||||||
|
*/
|
||||||
|
@Autowired
|
||||||
|
private RecognitionModel recognitionModel;
|
||||||
|
|
||||||
|
@Value("${model.type}")
|
||||||
|
private String type;
|
||||||
|
|
||||||
|
@Value("${image.debug}")
|
||||||
|
private boolean debug;
|
||||||
|
|
||||||
|
@Value("${distance.type}")
|
||||||
|
private String distance;
|
||||||
|
|
||||||
|
public Map<String, String> getImageInfo(TemplateBean templateBean, Image image) throws TranslateException, IOException {
|
||||||
|
List<LabelBean> anchorlabels = getLabelDataByType(templateBean.getLabelData(), "anchor");
|
||||||
|
List<LabelBean> contentLabels = getLabelDataByType(templateBean.getLabelData(), "rectangle");
|
||||||
|
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
BufferedImage templateImg = ImageIO.read(new File(fileRelativePath + "images/" + templateBean.getImageName()));
|
||||||
|
|
||||||
|
try (NDManager manager = NDManager.newBaseManager()) {
|
||||||
|
Map<String, String> hashMap = PerspectiveRecogition.recognize(manager, templateImg, recognitionModel, image, anchorlabels, contentLabels, fileRelativePath, distance, debug);
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<TemplateBean> getTemplateList() {
|
||||||
|
List<TemplateBean> templateList = null;
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
String json = null;
|
||||||
|
try {
|
||||||
|
json = FileUtils.readFile(fileRelativePath, TEMPLATE_LIST_FILE);
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
if (!StringUtils.isBlank(json)) {
|
||||||
|
templateList = new Gson().fromJson(json, new TypeToken<List<TemplateBean>>() {
|
||||||
|
}.getType());
|
||||||
|
} else {
|
||||||
|
templateList = new ArrayList<>();
|
||||||
|
}
|
||||||
|
return templateList;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取模板
|
||||||
|
*
|
||||||
|
* @param uid
|
||||||
|
*/
|
||||||
|
public TemplateBean getTemplate(String uid) throws IOException {
|
||||||
|
TemplateBean template = null;
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/") + "templates/";
|
||||||
|
String json = FileUtils.readFile(fileRelativePath, uid + ".json");
|
||||||
|
if (!StringUtils.isBlank(json)) {
|
||||||
|
template = new Gson().fromJson(json, new TypeToken<TemplateBean>() {
|
||||||
|
}.getType());
|
||||||
|
}
|
||||||
|
return template;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 新增模板
|
||||||
|
*
|
||||||
|
* @param templateBean
|
||||||
|
*/
|
||||||
|
public synchronized void addTemplate(TemplateBean templateBean) throws IOException {
|
||||||
|
List<TemplateBean> templateList = getTemplateList();
|
||||||
|
templateBean.setLabelData(null);
|
||||||
|
templateList.add(templateBean);
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
String json = gson.toJson(templateList);
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
// 保存模版列表数据
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
FileUtils.saveFile(fileRelativePath, TEMPLATE_LIST_FILE, json);
|
||||||
|
// 保存模版数据
|
||||||
|
json = gson.toJson(templateBean);
|
||||||
|
FileUtils.saveFile(fileRelativePath + "templates/", templateBean.getUid() + ".json", json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 更新模板
|
||||||
|
*
|
||||||
|
* @param templateBean
|
||||||
|
*/
|
||||||
|
public synchronized void updateTemplate(TemplateBean templateBean) throws IOException {
|
||||||
|
List<TemplateBean> templateList = getTemplateList();
|
||||||
|
for (TemplateBean item : templateList) {
|
||||||
|
if (item.getUid().equals(templateBean.getUid())) {
|
||||||
|
BeanUtils.copyProperties(templateBean, item);
|
||||||
|
item.setLabelData(null);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
String json = gson.toJson(templateList);
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
// 保存模版列表数据
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
FileUtils.saveFile(fileRelativePath, TEMPLATE_LIST_FILE, json);
|
||||||
|
// 保存模版数据
|
||||||
|
json = gson.toJson(templateBean);
|
||||||
|
FileUtils.saveFile(fileRelativePath + "templates/", templateBean.getUid() + ".json", json);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除模板
|
||||||
|
*
|
||||||
|
* @param uid
|
||||||
|
*/
|
||||||
|
public synchronized void removeTemplate(String uid) throws IOException {
|
||||||
|
List<TemplateBean> templateList = getTemplateList();
|
||||||
|
for (int i = 0; i < templateList.size(); i++) {
|
||||||
|
if (templateList.get(i).getUid().equals(uid)) {
|
||||||
|
templateList.remove(i);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||||
|
String json = gson.toJson(templateList);
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
// 保存模版列表数据
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
FileUtils.saveFile(fileRelativePath, TEMPLATE_LIST_FILE, json);
|
||||||
|
// 删除模版数据
|
||||||
|
FileUtils.removeFile(fileRelativePath + "templates/", uid + ".json");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public String getLabelData(String uid, LabelBean labelData) throws IOException, TranslateException {
|
||||||
|
TemplateBean template = getTemplate(uid);
|
||||||
|
FileProperties.ElPath path = properties.getPath();
|
||||||
|
String fileRelativePath = path.getPath().replace("\\", "/");
|
||||||
|
BufferedImage img = ImageIO.read(new File(fileRelativePath + "images/" + template.getImageName()));
|
||||||
|
Image image = ImageFactory.getInstance().fromImage(img);
|
||||||
|
// int x = labelData.getPoints().get(0).getX();
|
||||||
|
// int y = labelData.getPoints().get(0).getY();
|
||||||
|
// int w = labelData.getPoints().get(1).getX() - labelData.getPoints().get(0).getX();
|
||||||
|
// int h = labelData.getPoints().get(3).getY() - labelData.getPoints().get(0).getY();
|
||||||
|
int[] rect = PointUtils.rectXYWH(labelData.getPoints());
|
||||||
|
Image subImage = image.getSubImage(rect[0], rect[1], rect[2], rect[3]);
|
||||||
|
String result = recognitionModel.predictSingleLineText(subImage);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<LabelBean> getLabelDataByType(List<LabelBean> labelData, String type) {
|
||||||
|
List<LabelBean> labels = new ArrayList<>();
|
||||||
|
for (int i = 0; i < labelData.size(); i++) {
|
||||||
|
if (labelData.get(i).getType().equals(type)) {
|
||||||
|
labels.add(labelData.get(i));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return labels;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,22 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public class Constants {
|
||||||
|
/**
|
||||||
|
* win systems
|
||||||
|
*/
|
||||||
|
public static final String WIN = "win";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac system
|
||||||
|
*/
|
||||||
|
public static final String MAC = "mac";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* mac system
|
||||||
|
*/
|
||||||
|
public static final String LINUX = "linux";
|
||||||
|
}
|
@ -0,0 +1,236 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import me.aias.ocr.model.CrossRangeCellMeta;
|
||||||
|
import org.apache.commons.lang3.StringUtils;
|
||||||
|
import org.apache.commons.lang3.math.NumberUtils;
|
||||||
|
import org.apache.poi.hssf.usermodel.*;
|
||||||
|
import org.apache.poi.ss.usermodel.BorderStyle;
|
||||||
|
import org.apache.poi.ss.usermodel.CellType;
|
||||||
|
import org.apache.poi.ss.usermodel.HorizontalAlignment;
|
||||||
|
import org.apache.poi.ss.usermodel.VerticalAlignment;
|
||||||
|
import org.apache.poi.ss.util.CellRangeAddress;
|
||||||
|
import org.dom4j.Document;
|
||||||
|
import org.dom4j.DocumentException;
|
||||||
|
import org.dom4j.DocumentHelper;
|
||||||
|
import org.dom4j.Element;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @Auther: xiaoqiang
|
||||||
|
* @Date: 2020/12/9 9:16
|
||||||
|
* @Description:
|
||||||
|
*/
|
||||||
|
public class ConvertHtml2Excel {
|
||||||
|
/**
|
||||||
|
* html表格转excel
|
||||||
|
*
|
||||||
|
* @param tableHtml 如
|
||||||
|
* <table>
|
||||||
|
* ..
|
||||||
|
* </table>
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static HSSFWorkbook table2Excel(String tableHtml) {
|
||||||
|
HSSFWorkbook wb = new HSSFWorkbook();
|
||||||
|
HSSFSheet sheet = wb.createSheet();
|
||||||
|
List<CrossRangeCellMeta> crossRowEleMetaLs = new ArrayList<>();
|
||||||
|
int rowIndex = 0;
|
||||||
|
try {
|
||||||
|
Document data = DocumentHelper.parseText(tableHtml);
|
||||||
|
// 生成表头
|
||||||
|
Element thead = data.getRootElement().element("thead");
|
||||||
|
HSSFCellStyle titleStyle = getTitleStyle(wb);
|
||||||
|
int ls=0;//列数
|
||||||
|
if (thead != null) {
|
||||||
|
List<Element> trLs = thead.elements("tr");
|
||||||
|
for (Element trEle : trLs) {
|
||||||
|
HSSFRow row = sheet.createRow(rowIndex);
|
||||||
|
List<Element> thLs = trEle.elements("td");
|
||||||
|
ls=thLs.size();
|
||||||
|
makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
|
||||||
|
rowIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 生成表体
|
||||||
|
Element tbody = data.getRootElement().element("tbody");
|
||||||
|
HSSFCellStyle contentStyle = getContentStyle(wb);
|
||||||
|
if (tbody != null) {
|
||||||
|
List<Element> trLs = tbody.elements("tr");
|
||||||
|
for (Element trEle : trLs) {
|
||||||
|
HSSFRow row = sheet.createRow(rowIndex);
|
||||||
|
List<Element> thLs = trEle.elements("th");
|
||||||
|
int cellIndex = makeRowCell(thLs, rowIndex, row, 0, titleStyle, crossRowEleMetaLs);
|
||||||
|
List<Element> tdLs = trEle.elements("td");
|
||||||
|
makeRowCell(tdLs, rowIndex, row, cellIndex, contentStyle, crossRowEleMetaLs);
|
||||||
|
rowIndex++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// 合并表头
|
||||||
|
for (CrossRangeCellMeta crcm : crossRowEleMetaLs) {
|
||||||
|
sheet.addMergedRegion(new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()));
|
||||||
|
setRegionStyle(sheet, new CellRangeAddress(crcm.getFirstRow(), crcm.getLastRow(), crcm.getFirstCol(), crcm.getLastCol()),titleStyle);
|
||||||
|
}
|
||||||
|
for(int i=0;i<sheet.getRow(0).getPhysicalNumberOfCells();i++){
|
||||||
|
sheet.autoSizeColumn(i, true);//设置列宽
|
||||||
|
if(sheet.getColumnWidth(i)<255*256){
|
||||||
|
sheet.setColumnWidth(i, sheet.getColumnWidth(i) < 9000 ? 9000 : sheet.getColumnWidth(i));
|
||||||
|
}else{
|
||||||
|
sheet.setColumnWidth(i, 15000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (DocumentException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return wb;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生产行内容
|
||||||
|
*
|
||||||
|
* @return 最后一列的cell index
|
||||||
|
*/
|
||||||
|
/**
|
||||||
|
* @param tdLs th或者td集合
|
||||||
|
* @param rowIndex 行号
|
||||||
|
* @param row POI行对象
|
||||||
|
* @param startCellIndex
|
||||||
|
* @param cellStyle 样式
|
||||||
|
* @param crossRowEleMetaLs 跨行元数据集合
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static int makeRowCell(List<Element> tdLs, int rowIndex, HSSFRow row, int startCellIndex, HSSFCellStyle cellStyle,
|
||||||
|
List<CrossRangeCellMeta> crossRowEleMetaLs) {
|
||||||
|
int i = startCellIndex;
|
||||||
|
for (int eleIndex = 0; eleIndex < tdLs.size(); i++, eleIndex++) {
|
||||||
|
int captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
|
||||||
|
while (captureCellSize > 0) {
|
||||||
|
for (int j = 0; j < captureCellSize; j++) {// 当前行跨列处理(补单元格)
|
||||||
|
row.createCell(i);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
captureCellSize = getCaptureCellSize(rowIndex, i, crossRowEleMetaLs);
|
||||||
|
}
|
||||||
|
Element thEle = tdLs.get(eleIndex);
|
||||||
|
String val = thEle.getTextTrim();
|
||||||
|
if (StringUtils.isBlank(val)) {
|
||||||
|
Element e = thEle.element("a");
|
||||||
|
if (e != null) {
|
||||||
|
val = e.getTextTrim();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
HSSFCell c = row.createCell(i);
|
||||||
|
if (NumberUtils.isNumber(val)) {
|
||||||
|
c.setCellValue(Double.parseDouble(val));
|
||||||
|
c.setCellType(CellType.NUMERIC);
|
||||||
|
} else {
|
||||||
|
c.setCellValue(val);
|
||||||
|
}
|
||||||
|
int rowSpan = NumberUtils.toInt(thEle.attributeValue("rowspan"), 1);
|
||||||
|
int colSpan = NumberUtils.toInt(thEle.attributeValue("colspan"), 1);
|
||||||
|
c.setCellStyle(cellStyle);
|
||||||
|
if (rowSpan > 1 || colSpan > 1) { // 存在跨行或跨列
|
||||||
|
crossRowEleMetaLs.add(new CrossRangeCellMeta(rowIndex, i, rowSpan, colSpan));
|
||||||
|
}
|
||||||
|
if (colSpan > 1) {// 当前行跨列处理(补单元格)
|
||||||
|
for (int j = 1; j < colSpan; j++) {
|
||||||
|
i++;
|
||||||
|
row.createCell(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 设置合并单元格的边框样式
|
||||||
|
*
|
||||||
|
* @param sheet
|
||||||
|
* @param region
|
||||||
|
* @param cs
|
||||||
|
*/
|
||||||
|
public static void setRegionStyle(HSSFSheet sheet, CellRangeAddress region, HSSFCellStyle cs) {
|
||||||
|
for (int i = region.getFirstRow(); i <= region.getLastRow(); i++) {
|
||||||
|
HSSFRow row = sheet.getRow(i);
|
||||||
|
for (int j = region.getFirstColumn(); j <= region.getLastColumn(); j++) {
|
||||||
|
HSSFCell cell = row.getCell(j);
|
||||||
|
cell.setCellStyle(cs);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得因rowSpan占据的单元格
|
||||||
|
*
|
||||||
|
* @param rowIndex 行号
|
||||||
|
* @param colIndex 列号
|
||||||
|
* @param crossRowEleMetaLs 跨行列元数据
|
||||||
|
* @return 当前行在某列需要占据单元格
|
||||||
|
*/
|
||||||
|
private static int getCaptureCellSize(int rowIndex, int colIndex, List<CrossRangeCellMeta> crossRowEleMetaLs) {
|
||||||
|
int captureCellSize = 0;
|
||||||
|
for (CrossRangeCellMeta crossRangeCellMeta : crossRowEleMetaLs) {
|
||||||
|
if (crossRangeCellMeta.getFirstRow() < rowIndex && crossRangeCellMeta.getLastRow() >= rowIndex) {
|
||||||
|
if (crossRangeCellMeta.getFirstCol() <= colIndex && crossRangeCellMeta.getLastCol() >= colIndex) {
|
||||||
|
captureCellSize = crossRangeCellMeta.getLastCol() - colIndex + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return captureCellSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得标题样式
|
||||||
|
*
|
||||||
|
* @param workbook
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static HSSFCellStyle getTitleStyle(HSSFWorkbook workbook) {
|
||||||
|
//short titlebackgroundcolor = IndexedColors.GREY_25_PERCENT.index;
|
||||||
|
short fontSize = 12;
|
||||||
|
String fontName = "宋体";
|
||||||
|
HSSFCellStyle style = workbook.createCellStyle();
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);
|
||||||
|
style.setBorderBottom(BorderStyle.THIN); //下边框
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);//左边框
|
||||||
|
style.setBorderTop(BorderStyle.THIN);//上边框
|
||||||
|
style.setBorderRight(BorderStyle.THIN);//右边框
|
||||||
|
//style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
|
||||||
|
//style.setFillForegroundColor(titlebackgroundcolor);// 背景色
|
||||||
|
|
||||||
|
HSSFFont font = workbook.createFont();
|
||||||
|
font.setFontName(fontName);
|
||||||
|
font.setFontHeightInPoints(fontSize);
|
||||||
|
font.setBold(true);
|
||||||
|
style.setFont(font);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获得内容样式
|
||||||
|
*
|
||||||
|
* @param wb
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
private static HSSFCellStyle getContentStyle(HSSFWorkbook wb) {
|
||||||
|
short fontSize = 12;
|
||||||
|
String fontName = "宋体";
|
||||||
|
HSSFCellStyle style = wb.createCellStyle();
|
||||||
|
style.setBorderBottom(BorderStyle.THIN); //下边框
|
||||||
|
style.setBorderLeft(BorderStyle.THIN);//左边框
|
||||||
|
style.setBorderTop(BorderStyle.THIN);//上边框
|
||||||
|
style.setBorderRight(BorderStyle.THIN);//右边框
|
||||||
|
HSSFFont font = wb.createFont();
|
||||||
|
font.setFontName(fontName);
|
||||||
|
font.setFontHeightInPoints(fontSize);
|
||||||
|
style.setFont(font);
|
||||||
|
style.setAlignment(HorizontalAlignment.CENTER);//水平居中
|
||||||
|
style.setVerticalAlignment(VerticalAlignment.CENTER);//垂直居中
|
||||||
|
style.setWrapText(true);
|
||||||
|
return style;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,98 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import ai.djl.modality.cv.Image;
|
||||||
|
import ai.djl.modality.cv.ImageFactory;
|
||||||
|
import ai.djl.modality.cv.output.DetectedObjects;
|
||||||
|
|
||||||
|
import java.awt.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
|
||||||
|
public class DJLImageUtils {
|
||||||
|
|
||||||
|
public static Image bufferedImage2DJLImage(BufferedImage img) {
|
||||||
|
return ImageFactory.getInstance().fromImage(img);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveImage(BufferedImage img, String name, String path) {
|
||||||
|
Image djlImg = ImageFactory.getInstance().fromImage(img); // 支持多种图片格式,自动适配
|
||||||
|
Path outputDir = Paths.get(path);
|
||||||
|
Path imagePath = outputDir.resolve(name);
|
||||||
|
// OpenJDK 不能保存 jpg 图片的 alpha channel
|
||||||
|
try {
|
||||||
|
djlImg.save(Files.newOutputStream(imagePath), "png");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveDJLImage(Image img, String name, String path) {
|
||||||
|
Path outputDir = Paths.get(path);
|
||||||
|
Path imagePath = outputDir.resolve(name);
|
||||||
|
// OpenJDK 不能保存 jpg 图片的 alpha channel
|
||||||
|
try {
|
||||||
|
img.save(Files.newOutputStream(imagePath), "png");
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveBoundingBoxImage(
|
||||||
|
Image img, DetectedObjects detection, String name, String path) throws IOException {
|
||||||
|
// Make imageName copy with alpha channel because original imageName was jpg
|
||||||
|
img.drawBoundingBoxes(detection);
|
||||||
|
Path outputDir = Paths.get(path);
|
||||||
|
Files.createDirectories(outputDir);
|
||||||
|
Path imagePath = outputDir.resolve(name);
|
||||||
|
// OpenJDK can't save jpg with alpha channel
|
||||||
|
img.save(Files.newOutputStream(imagePath), "png");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawImageRect(BufferedImage image, int x, int y, int width, int height) {
|
||||||
|
// 将绘制图像转换为Graphics2D
|
||||||
|
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||||
|
try {
|
||||||
|
g.setColor(new Color(246, 96, 0));
|
||||||
|
// 声明画笔属性 :粗 细(单位像素)末端无修饰 折线处呈尖角
|
||||||
|
BasicStroke bStroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||||
|
g.setStroke(bStroke);
|
||||||
|
g.drawRect(x, y, width, height);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawImageRect(
|
||||||
|
BufferedImage image, int x, int y, int width, int height, Color c) {
|
||||||
|
// 将绘制图像转换为Graphics2D
|
||||||
|
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||||
|
try {
|
||||||
|
g.setColor(c);
|
||||||
|
// 声明画笔属性 :粗 细(单位像素)末端无修饰 折线处呈尖角
|
||||||
|
BasicStroke bStroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER);
|
||||||
|
g.setStroke(bStroke);
|
||||||
|
g.drawRect(x, y, width, height);
|
||||||
|
|
||||||
|
} finally {
|
||||||
|
g.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void drawImageText(BufferedImage image, String text) {
|
||||||
|
Graphics graphics = image.getGraphics();
|
||||||
|
int fontSize = 100;
|
||||||
|
Font font = new Font("楷体", Font.PLAIN, fontSize);
|
||||||
|
try {
|
||||||
|
graphics.setFont(font);
|
||||||
|
graphics.setColor(new Color(246, 96, 0));
|
||||||
|
int strWidth = graphics.getFontMetrics().stringWidth(text);
|
||||||
|
graphics.drawString(text, fontSize - (strWidth / 2), fontSize + 30);
|
||||||
|
} finally {
|
||||||
|
graphics.dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,110 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import me.aias.ocr.model.LabelBean;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public class DistanceUtils {
|
||||||
|
/**
|
||||||
|
* Calculate L2 distance
|
||||||
|
*
|
||||||
|
* @param contentLabels 内容识别区
|
||||||
|
* @param detectedTexts 文本检测区
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, String> l2Distance(List<LabelBean> contentLabels, List<LabelBean> detectedTexts) {
|
||||||
|
Map<String, String> hashMap = new ConcurrentHashMap<>();
|
||||||
|
for (int i = 0; i < contentLabels.size(); i++) {
|
||||||
|
String field = contentLabels.get(i).getField();
|
||||||
|
double minDistance = Double.MAX_VALUE;
|
||||||
|
String value = "";
|
||||||
|
for (int j = 0; j < detectedTexts.size(); j++) {
|
||||||
|
double dis = l2Distance(contentLabels.get(i).getCenterPoint(), detectedTexts.get(j).getCenterPoint());
|
||||||
|
if (dis < minDistance) {
|
||||||
|
minDistance = dis;
|
||||||
|
value = detectedTexts.get(j).getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(field + " : " + value);
|
||||||
|
hashMap.put(field, value);
|
||||||
|
}
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate iou
|
||||||
|
*
|
||||||
|
* @param contentLabels 内容识别区
|
||||||
|
* @param detectedTexts 文本检测区
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static Map<String, String> iou(List<LabelBean> contentLabels, List<LabelBean> detectedTexts) {
|
||||||
|
Map<String, String> hashMap = new ConcurrentHashMap<>();
|
||||||
|
for (int i = 0; i < contentLabels.size(); i++) {
|
||||||
|
String field = contentLabels.get(i).getField();
|
||||||
|
double maxIOU = 0d;
|
||||||
|
String value = "";
|
||||||
|
int[] box_1 = PointUtils.rectXYXY(contentLabels.get(i).getPoints());
|
||||||
|
for (int j = 0; j < detectedTexts.size(); j++) {
|
||||||
|
int[] box_2 = PointUtils.rectXYXY(detectedTexts.get(j).getPoints());
|
||||||
|
double iou = compute_iou(box_1, box_2);
|
||||||
|
if (iou > maxIOU) {
|
||||||
|
maxIOU = iou;
|
||||||
|
value = detectedTexts.get(j).getValue();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
System.out.println(field + " : " + value);
|
||||||
|
hashMap.put(field, value);
|
||||||
|
}
|
||||||
|
return hashMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculate L2 distance
|
||||||
|
*
|
||||||
|
* @param point1
|
||||||
|
* @param point2
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static double l2Distance(ai.djl.modality.cv.output.Point point1, ai.djl.modality.cv.output.Point point2) {
|
||||||
|
double partX = Math.pow((point1.getX() - point2.getX()), 2);
|
||||||
|
double partY = Math.pow((point1.getY() - point2.getY()), 2);
|
||||||
|
return Math.sqrt(partX + partY);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* computing IoU
|
||||||
|
*
|
||||||
|
* @param rec1: (y0, x0, y1, x1), which reflects (top, left, bottom, right)
|
||||||
|
* @param rec2: (y0, x0, y1, x1)
|
||||||
|
* @return scala value of IoU
|
||||||
|
*/
|
||||||
|
public static float compute_iou(int[] rec1, int[] rec2) {
|
||||||
|
// computing area of each rectangles
|
||||||
|
int S_rec1 = (rec1[2] - rec1[0]) * (rec1[3] - rec1[1]);
|
||||||
|
int S_rec2 = (rec2[2] - rec2[0]) * (rec2[3] - rec2[1]);
|
||||||
|
|
||||||
|
// computing the sum_area
|
||||||
|
int sum_area = S_rec1 + S_rec2;
|
||||||
|
|
||||||
|
// find the each edge of intersect rectangle
|
||||||
|
int left_line = Math.max(rec1[1], rec2[1]);
|
||||||
|
int right_line = Math.min(rec1[3], rec2[3]);
|
||||||
|
int top_line = Math.max(rec1[0], rec2[0]);
|
||||||
|
int bottom_line = Math.min(rec1[2], rec2[2]);
|
||||||
|
|
||||||
|
// judge if there is an intersect
|
||||||
|
if (left_line >= right_line || top_line >= bottom_line) {
|
||||||
|
return 0.0f;
|
||||||
|
} else {
|
||||||
|
float intersect = (right_line - left_line) * (bottom_line - top_line);
|
||||||
|
return (intersect / (sum_area - intersect)) * 1.0f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,131 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import ai.djl.util.Utils;
|
||||||
|
import com.google.gson.Gson;
|
||||||
|
import com.google.gson.GsonBuilder;
|
||||||
|
import me.aias.ocr.configuration.FileProperties;
|
||||||
|
import org.apache.commons.compress.utils.FileNameUtils;
|
||||||
|
import org.springframework.web.multipart.MultipartFile;
|
||||||
|
|
||||||
|
import java.io.*;
|
||||||
|
import java.nio.file.Path;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 文件上传工具包
|
||||||
|
*/
|
||||||
|
public class FileUtils {
|
||||||
|
/**
|
||||||
|
* @param file 文件
|
||||||
|
* @param path 文件存放路径
|
||||||
|
* @param fileName 源文件名
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static boolean upload(MultipartFile file, String path, String fileName) {
|
||||||
|
// 生成新的文件名
|
||||||
|
//String realPath = path + "/" + FileNameUtils.getFileName(fileName);
|
||||||
|
Path filePath = Paths.get(path + fileName);
|
||||||
|
File dest = filePath.toAbsolutePath().toFile();
|
||||||
|
|
||||||
|
//判断文件父目录是否存在
|
||||||
|
if (!dest.getParentFile().exists()) {
|
||||||
|
dest.getParentFile().mkdir();
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
//保存文件
|
||||||
|
file.transferTo(dest);
|
||||||
|
return true;
|
||||||
|
} catch (IllegalStateException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
} catch (IOException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取文件后缀
|
||||||
|
*
|
||||||
|
* @param fileName
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getSuffix(String fileName) {
|
||||||
|
return fileName.substring(fileName.lastIndexOf("."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成新的文件名
|
||||||
|
*
|
||||||
|
* @param fileOriginName 源文件名
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String getFileName(String fileOriginName) {
|
||||||
|
return UUIDUtils.getUUID() + getSuffix(fileOriginName);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 读取json文件
|
||||||
|
*
|
||||||
|
* @param path 文件路径信息
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static String readFile(String path, String fileName) throws IOException {
|
||||||
|
StringBuilder json = new StringBuilder();
|
||||||
|
Path filePath = Paths.get(path + fileName);
|
||||||
|
List<String> lines = Utils.readLines(filePath, true);
|
||||||
|
lines.stream()
|
||||||
|
.filter(line -> (line != null && line != ""))
|
||||||
|
.forEach(
|
||||||
|
line -> {
|
||||||
|
json.append(line);
|
||||||
|
});
|
||||||
|
|
||||||
|
return json.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 保存json文件
|
||||||
|
*
|
||||||
|
* @param path 文件路径信息
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @param json json信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static void saveFile(String path, String fileName, String json) throws IOException {
|
||||||
|
Path filePath = Paths.get(path + fileName);
|
||||||
|
try (PrintStream ps = new PrintStream(new FileOutputStream(filePath.toFile()))) {
|
||||||
|
ps.print(json);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 删除json文件
|
||||||
|
*
|
||||||
|
* @param path 文件路径信息
|
||||||
|
* @param fileName 文件名
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static void removeFile(String path, String fileName) {
|
||||||
|
Path filePath = Paths.get(path + fileName);
|
||||||
|
filePath.toFile().delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check & create file path
|
||||||
|
*
|
||||||
|
* @param fileRelativePath 文件路径信息
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static void checkAndCreatePath(String fileRelativePath) {
|
||||||
|
//Check & create file path
|
||||||
|
Path filePath = Paths.get(fileRelativePath).toAbsolutePath();
|
||||||
|
File file = filePath.toFile();
|
||||||
|
if (!file.exists() && !file.isDirectory()) {
|
||||||
|
file.mkdirs();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,66 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import me.aias.ocr.model.Point;
|
||||||
|
import org.bytedeco.javacpp.indexer.DoubleRawIndexer;
|
||||||
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Point2f;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class NDArrayUtils {
|
||||||
|
// NDArray 转 opencv_core.Mat
|
||||||
|
public static Mat toOpenCVMat(NDArray points, int rows, int cols) {
|
||||||
|
double[] doubleArray = points.toDoubleArray();
|
||||||
|
// CV_32F = FloatRawIndexer
|
||||||
|
// CV_64F = DoubleRawIndexer
|
||||||
|
Mat mat = new Mat(rows, cols, opencv_core.CV_64F);
|
||||||
|
|
||||||
|
DoubleRawIndexer ldIdx = mat.createIndexer();
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
ldIdx.put(i, j, doubleArray[i * cols + j]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ldIdx.release();
|
||||||
|
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NDArray 转 opencv_core.Point2f
|
||||||
|
public static Point2f toOpenCVPoint2f(NDArray points, int rows) {
|
||||||
|
double[] doubleArray = points.toDoubleArray();
|
||||||
|
Point2f points2f = new Point2f(rows);
|
||||||
|
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
points2f.position(i).x((float) doubleArray[i * 2]).y((float) doubleArray[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return points2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Double array 转 opencv_core.Point2f
|
||||||
|
public static Point2f toOpenCVPoint2f(double[] doubleArray, int rows) {
|
||||||
|
Point2f points2f = new Point2f(rows);
|
||||||
|
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
points2f.position(i).x((float) doubleArray[i * 2]).y((float) doubleArray[i * 2 + 1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return points2f;
|
||||||
|
}
|
||||||
|
|
||||||
|
// list 转 opencv_core.Point2f
|
||||||
|
public static Point2f toOpenCVPoint2f(List<ai.djl.modality.cv.output.Point> points, int rows) {
|
||||||
|
Point2f points2f = new Point2f(points.size());
|
||||||
|
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
ai.djl.modality.cv.output.Point point = points.get(i);
|
||||||
|
points2f.position(i).x((float) point.getX()).y((float) point.getY());
|
||||||
|
}
|
||||||
|
|
||||||
|
return points2f;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import org.bytedeco.javacpp.indexer.DoubleRawIndexer;
|
||||||
|
import org.bytedeco.opencv.global.opencv_core;
|
||||||
|
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||||
|
import org.bytedeco.opencv.opencv_core.CvMat;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Point2f;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Point2fVector;
|
||||||
|
|
||||||
|
import java.nio.FloatBuffer;
|
||||||
|
|
||||||
|
import static org.bytedeco.opencv.global.opencv_calib3d.findHomography;
|
||||||
|
import static org.bytedeco.opencv.global.opencv_core.cvCreateMat;
|
||||||
|
|
||||||
|
|
||||||
|
public class OpenCVUtils {
|
||||||
|
|
||||||
|
public static Mat affineTransform(
|
||||||
|
Mat src, Point2f srcPoints, Point2f dstPoints) {
|
||||||
|
Mat dst = src.clone();
|
||||||
|
// https://github.com/bytedeco/javacv/issues/788
|
||||||
|
Mat warp_mat = opencv_imgproc.getAffineTransform(srcPoints.position(0), dstPoints.position(0));
|
||||||
|
opencv_imgproc.warpAffine(src, dst, warp_mat, dst.size());
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat perspectiveTransform(
|
||||||
|
Mat src, Point2f srcPoints, Point2f dstPoints) {
|
||||||
|
Mat dst = src.clone();
|
||||||
|
Mat warp_mat = opencv_imgproc.getPerspectiveTransform(srcPoints.position(0), dstPoints.position(0));
|
||||||
|
opencv_imgproc.warpPerspective(src, dst, warp_mat, dst.size());
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat getHomography(Mat src, double[] srcPoints, double[] dstPoints) {
|
||||||
|
Mat dst = src.clone();
|
||||||
|
Mat warp_mat = createHomography(srcPoints, dstPoints);
|
||||||
|
opencv_imgproc.warpPerspective(src, dst, warp_mat, dst.size());
|
||||||
|
return dst;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat createHomography(double[] src, double[] dst) {
|
||||||
|
CvMat srcPoints;
|
||||||
|
CvMat dstPoints;
|
||||||
|
int nbPoints = src.length / 2;
|
||||||
|
Mat homography;
|
||||||
|
|
||||||
|
srcPoints = cvCreateMat(2, nbPoints, opencv_core.CV_32FC1);
|
||||||
|
dstPoints = cvCreateMat(2, nbPoints, opencv_core.CV_32FC1);
|
||||||
|
Mat newSvdMat = new Mat(2, 3, opencv_core.CV_32FC1);
|
||||||
|
|
||||||
|
// homography = cvCreateMat(3, 3, opencv_core.CV_32FC1);
|
||||||
|
for (int i = 0; i < nbPoints; i++) {
|
||||||
|
srcPoints.put(i, src[2 * i]);
|
||||||
|
srcPoints.put(i + nbPoints, src[2 * i + 1]);
|
||||||
|
dstPoints.put(i, dst[2 * i]);
|
||||||
|
dstPoints.put(i + nbPoints, dst[2 * i + 1]);
|
||||||
|
}
|
||||||
|
homography = findHomography(returnMat(srcPoints), returnMat(dstPoints));
|
||||||
|
return homography;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Mat returnMat(CvMat mtx) {
|
||||||
|
double valor;
|
||||||
|
final int rows = mtx.rows();
|
||||||
|
final int cols = mtx.cols();
|
||||||
|
Mat mat = new Mat(rows, cols, opencv_core.CV_64F);
|
||||||
|
final int step = mtx.step() / 4;
|
||||||
|
FloatBuffer buf = mtx.getFloatBuffer();
|
||||||
|
DoubleRawIndexer ldIdx = mat.createIndexer();
|
||||||
|
for (int row = 0; row < rows; row++) {
|
||||||
|
buf.position(row * step);
|
||||||
|
for (int col = 0; col < cols; col++) {
|
||||||
|
valor = buf.get();
|
||||||
|
ldIdx.put(row, col, valor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ldIdx.release();
|
||||||
|
return mat;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,135 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import ai.djl.ndarray.NDArray;
|
||||||
|
import ai.djl.ndarray.NDManager;
|
||||||
|
import me.aias.ocr.model.Point;
|
||||||
|
import org.bytedeco.javacpp.indexer.DoubleRawIndexer;
|
||||||
|
import org.bytedeco.opencv.opencv_core.Mat;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Calvin
|
||||||
|
* @date Oct 19, 2021
|
||||||
|
*/
|
||||||
|
public class PointUtils {
|
||||||
|
|
||||||
|
public static ai.djl.modality.cv.output.Point getCenterPoint(List<Point> points) {
|
||||||
|
double sumX = 0;
|
||||||
|
double sumY = 0;
|
||||||
|
|
||||||
|
for (Point point : points) {
|
||||||
|
sumX = sumX + point.getX();
|
||||||
|
sumY = sumY + point.getY();
|
||||||
|
}
|
||||||
|
|
||||||
|
ai.djl.modality.cv.output.Point centerPoint = new ai.djl.modality.cv.output.Point(sumX / 4, sumY / 4);
|
||||||
|
return centerPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Point transformPoint(NDManager manager, Mat mat, Point point) {
|
||||||
|
double[][] pointsArray = new double[3][3];
|
||||||
|
DoubleRawIndexer ldIdx = mat.createIndexer();
|
||||||
|
for (int i = 0; i < 3; i++) {
|
||||||
|
for (int j = 0; j < 3; j++) {
|
||||||
|
pointsArray[i][j] = ldIdx.get(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NDArray ndPoints = manager.create(pointsArray);
|
||||||
|
|
||||||
|
double[] vector = new double[3];
|
||||||
|
vector[0] = point.getX();
|
||||||
|
vector[1] = point.getY();
|
||||||
|
vector[2] = 1f;
|
||||||
|
NDArray vPoints = manager.create(vector);
|
||||||
|
vPoints = vPoints.reshape(3, 1);
|
||||||
|
NDArray result = ndPoints.matMul(vPoints);
|
||||||
|
double[] dArray = result.toDoubleArray();
|
||||||
|
if (dArray[2] != 0) {
|
||||||
|
point.setX((int) (dArray[0] / dArray[2]));
|
||||||
|
point.setY((int) (dArray[1] / dArray[2]));
|
||||||
|
}
|
||||||
|
|
||||||
|
return point;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<Point> transformPoints(NDManager manager, Mat mat, List<Point> points) {
|
||||||
|
int cols = mat.cols();
|
||||||
|
int rows = mat.rows();
|
||||||
|
double[][] pointsArray = new double[rows][cols];
|
||||||
|
DoubleRawIndexer ldIdx = mat.createIndexer();
|
||||||
|
for (int i = 0; i < rows; i++) {
|
||||||
|
for (int j = 0; j < cols; j++) {
|
||||||
|
pointsArray[i][j] = ldIdx.get(i, j);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
NDArray ndPoints = manager.create(pointsArray);
|
||||||
|
|
||||||
|
double[] vector = new double[3];
|
||||||
|
for (int i = 0; i < points.size(); i++) {
|
||||||
|
vector[0] = points.get(i).getX();
|
||||||
|
vector[1] = points.get(i).getY();
|
||||||
|
vector[2] = 1f;
|
||||||
|
NDArray vPoints = manager.create(vector);
|
||||||
|
vPoints = vPoints.reshape(3, 1);
|
||||||
|
NDArray result = ndPoints.matMul(vPoints);
|
||||||
|
double[] dArray = result.toDoubleArray();
|
||||||
|
if (dArray.length > 2) {
|
||||||
|
if (dArray[2] != 0) {
|
||||||
|
points.get(i).setX((int) (dArray[0] / dArray[2]));
|
||||||
|
points.get(i).setY((int) (dArray[1] / dArray[2]));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
points.get(i).setX((int) (dArray[0]));
|
||||||
|
points.get(i).setY((int) (dArray[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return points;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get (x1,y1,x2,y2) coordinations
|
||||||
|
*
|
||||||
|
* @param points
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int[] rectXYXY(List<Point> points) {
|
||||||
|
int left = points.get(0).getX();
|
||||||
|
int top = points.get(0).getY();
|
||||||
|
int right = points.get(2).getX();
|
||||||
|
int bottom = points.get(2).getY();
|
||||||
|
return new int[]{left, top, right, bottom};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get (x1,y1,w,h) coordinations
|
||||||
|
*
|
||||||
|
* @param points
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public static int[] rectXYWH(List<Point> points) {
|
||||||
|
int minX = Integer.MAX_VALUE;
|
||||||
|
int minY = Integer.MAX_VALUE;
|
||||||
|
int maxX = Integer.MIN_VALUE;
|
||||||
|
int maxY = Integer.MIN_VALUE;
|
||||||
|
|
||||||
|
for (Point point : points) {
|
||||||
|
int x = point.getX();
|
||||||
|
int y = point.getY();
|
||||||
|
if (x < minX)
|
||||||
|
minX = x;
|
||||||
|
if (x > maxX)
|
||||||
|
maxX = x;
|
||||||
|
if (y < minY)
|
||||||
|
minY = y;
|
||||||
|
if (y > maxY)
|
||||||
|
maxY = y;
|
||||||
|
}
|
||||||
|
|
||||||
|
int w = maxX - minX;
|
||||||
|
int h = maxY - minY;
|
||||||
|
return new int[]{minX, minY, w, h};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,14 @@
|
|||||||
|
package me.aias.ocr.utils;
|
||||||
|
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 生成文件名
|
||||||
|
*/
|
||||||
|
public class UUIDUtils {
|
||||||
|
|
||||||
|
public static String getUUID() {
|
||||||
|
return UUID.randomUUID().toString().replace("-", "");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
11
8_suite_hub/iocr/ocr-demo/src/main/main.iml
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="false" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
</component>
|
||||||
|
</module>
|
70
8_suite_hub/iocr/ocr-demo/src/main/resources/application.yml
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
# Server Port
|
||||||
|
server:
|
||||||
|
port: 8089
|
||||||
|
tomcat:
|
||||||
|
uri-encoding: UTF-8
|
||||||
|
baseUri: http://127.0.0.1:${server.port}
|
||||||
|
|
||||||
|
# Swagger-ui
|
||||||
|
swagger:
|
||||||
|
enabled: true
|
||||||
|
|
||||||
|
spring:
|
||||||
|
servlet:
|
||||||
|
multipart:
|
||||||
|
enabled: true
|
||||||
|
max-file-size: 30MB
|
||||||
|
max-request-size: 30MB
|
||||||
|
http:
|
||||||
|
encoding:
|
||||||
|
charset: utf-8
|
||||||
|
enabled: true
|
||||||
|
force: true
|
||||||
|
messages:
|
||||||
|
encoding: UTF-8
|
||||||
|
|
||||||
|
# File path
|
||||||
|
file:
|
||||||
|
mac:
|
||||||
|
path: file/
|
||||||
|
linux:
|
||||||
|
path: file/
|
||||||
|
windows:
|
||||||
|
path: C:\ocr\file\
|
||||||
|
# File max size - MB
|
||||||
|
maxSize: 100
|
||||||
|
|
||||||
|
# Model type: mobile, light, server
|
||||||
|
model:
|
||||||
|
type: mobile
|
||||||
|
table:
|
||||||
|
# Layout detection model URI
|
||||||
|
layout: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ppyolov2_r50vd_dcn_365e_publaynet_infer.zip
|
||||||
|
# Table detection model URI
|
||||||
|
table-en: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/en_table.zip
|
||||||
|
mobile:
|
||||||
|
# mobile detection model URI
|
||||||
|
det: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_ppocr_mobile_v2.0_det_infer.zip
|
||||||
|
# mobile recognition model URI
|
||||||
|
rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_ppocr_mobile_v2.0_rec_infer.zip
|
||||||
|
light:
|
||||||
|
# light detection model URI
|
||||||
|
det: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_PP-OCRv2_det_infer.zip
|
||||||
|
# light recognition model URI
|
||||||
|
rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_PP-OCRv2_rec_infer.zip
|
||||||
|
server:
|
||||||
|
# server detection model URI
|
||||||
|
det: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_ppocr_server_v2.0_det_infer.zip
|
||||||
|
# server recognition model URI
|
||||||
|
rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/ch_ppocr_server_v2.0_rec_infer.zip
|
||||||
|
|
||||||
|
|
||||||
|
# Verify image transformation result
|
||||||
|
image:
|
||||||
|
debug: true
|
||||||
|
|
||||||
|
# distance calculation type: L2, IoU
|
||||||
|
distance:
|
||||||
|
type: L2
|
||||||
|
|
||||||
|
|
17
8_suite_hub/iocr/ocr-demo/src/main/resources/log4j2.xml
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<Configuration status="INFO">
|
||||||
|
<Appenders>
|
||||||
|
<Console name="console" target="SYSTEM_OUT">
|
||||||
|
<PatternLayout
|
||||||
|
pattern="[%-5level] - %msg%n"/>
|
||||||
|
</Console>
|
||||||
|
</Appenders>
|
||||||
|
<Loggers>
|
||||||
|
<Root level="info" additivity="false">
|
||||||
|
<AppenderRef ref="console"/>
|
||||||
|
</Root>
|
||||||
|
<Logger name="me.calvin" level="${sys:me.calvin.logging.level:-info}" additivity="false">
|
||||||
|
<AppenderRef ref="console"/>
|
||||||
|
</Logger>
|
||||||
|
</Loggers>
|
||||||
|
</Configuration>
|
12
8_suite_hub/iocr/ocr-demo/src/test/test.iml
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<module type="JAVA_MODULE" version="4">
|
||||||
|
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||||
|
<exclude-output />
|
||||||
|
<content url="file://$MODULE_DIR$">
|
||||||
|
<sourceFolder url="file://$MODULE_DIR$/java" isTestSource="true" />
|
||||||
|
</content>
|
||||||
|
<orderEntry type="inheritedJdk" />
|
||||||
|
<orderEntry type="sourceFolder" forTests="false" />
|
||||||
|
<orderEntry type="module" module-name="main" />
|
||||||
|
</component>
|
||||||
|
</module>
|
14
8_suite_hub/iocr/ocr-ui/.editorconfig
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
# http://editorconfig.org
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
charset = utf-8
|
||||||
|
indent_style = space
|
||||||
|
indent_size = 2
|
||||||
|
end_of_line = lf
|
||||||
|
insert_final_newline = true
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[*.md]
|
||||||
|
insert_final_newline = false
|
||||||
|
trim_trailing_whitespace = false
|
6
8_suite_hub/iocr/ocr-ui/.env.development
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# just a flag
|
||||||
|
ENV = 'development'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = 'http://127.0.0.1:8089'
|
||||||
|
|
6
8_suite_hub/iocr/ocr-ui/.env.production
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# just a flag
|
||||||
|
ENV = 'production'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = 'http://127.0.0.1:8089'
|
||||||
|
|
8
8_suite_hub/iocr/ocr-ui/.env.staging
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
NODE_ENV = production
|
||||||
|
|
||||||
|
# just a flag
|
||||||
|
ENV = 'staging'
|
||||||
|
|
||||||
|
# base api
|
||||||
|
VUE_APP_BASE_API = '/stage-api'
|
||||||
|
|
4
8_suite_hub/iocr/ocr-ui/.eslintignore
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
build/*.js
|
||||||
|
src/assets
|
||||||
|
public
|
||||||
|
dist
|
198
8_suite_hub/iocr/ocr-ui/.eslintrc.js
Normal file
@ -0,0 +1,198 @@
|
|||||||
|
module.exports = {
|
||||||
|
root: true,
|
||||||
|
parserOptions: {
|
||||||
|
parser: 'babel-eslint',
|
||||||
|
sourceType: 'module'
|
||||||
|
},
|
||||||
|
env: {
|
||||||
|
browser: true,
|
||||||
|
node: true,
|
||||||
|
es6: true,
|
||||||
|
},
|
||||||
|
extends: ['plugin:vue/recommended', 'eslint:recommended'],
|
||||||
|
|
||||||
|
// add your custom rules here
|
||||||
|
//it is base on https://github.com/vuejs/eslint-config-vue
|
||||||
|
rules: {
|
||||||
|
"vue/max-attributes-per-line": [2, {
|
||||||
|
"singleline": 10,
|
||||||
|
"multiline": {
|
||||||
|
"max": 1,
|
||||||
|
"allowFirstLine": false
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
"vue/singleline-html-element-content-newline": "off",
|
||||||
|
"vue/multiline-html-element-content-newline":"off",
|
||||||
|
"vue/name-property-casing": ["error", "PascalCase"],
|
||||||
|
"vue/no-v-html": "off",
|
||||||
|
'accessor-pairs': 2,
|
||||||
|
'arrow-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'block-spacing': [2, 'always'],
|
||||||
|
'brace-style': [2, '1tbs', {
|
||||||
|
'allowSingleLine': true
|
||||||
|
}],
|
||||||
|
'camelcase': [0, {
|
||||||
|
'properties': 'always'
|
||||||
|
}],
|
||||||
|
'comma-dangle': [2, 'never'],
|
||||||
|
'comma-spacing': [2, {
|
||||||
|
'before': false,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'comma-style': [2, 'last'],
|
||||||
|
'constructor-super': 2,
|
||||||
|
'curly': [2, 'multi-line'],
|
||||||
|
'dot-location': [2, 'property'],
|
||||||
|
'eol-last': 2,
|
||||||
|
'eqeqeq': ["error", "always", {"null": "ignore"}],
|
||||||
|
'generator-star-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'handle-callback-err': [2, '^(err|error)$'],
|
||||||
|
'indent': [2, 2, {
|
||||||
|
'SwitchCase': 1
|
||||||
|
}],
|
||||||
|
'jsx-quotes': [2, 'prefer-single'],
|
||||||
|
'key-spacing': [2, {
|
||||||
|
'beforeColon': false,
|
||||||
|
'afterColon': true
|
||||||
|
}],
|
||||||
|
'keyword-spacing': [2, {
|
||||||
|
'before': true,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'new-cap': [2, {
|
||||||
|
'newIsCap': true,
|
||||||
|
'capIsNew': false
|
||||||
|
}],
|
||||||
|
'new-parens': 2,
|
||||||
|
'no-array-constructor': 2,
|
||||||
|
'no-caller': 2,
|
||||||
|
'no-console': 'off',
|
||||||
|
'no-class-assign': 2,
|
||||||
|
'no-cond-assign': 2,
|
||||||
|
'no-const-assign': 2,
|
||||||
|
'no-control-regex': 0,
|
||||||
|
'no-delete-var': 2,
|
||||||
|
'no-dupe-args': 2,
|
||||||
|
'no-dupe-class-members': 2,
|
||||||
|
'no-dupe-keys': 2,
|
||||||
|
'no-duplicate-case': 2,
|
||||||
|
'no-empty-character-class': 2,
|
||||||
|
'no-empty-pattern': 2,
|
||||||
|
'no-eval': 2,
|
||||||
|
'no-ex-assign': 2,
|
||||||
|
'no-extend-native': 2,
|
||||||
|
'no-extra-bind': 2,
|
||||||
|
'no-extra-boolean-cast': 2,
|
||||||
|
'no-extra-parens': [2, 'functions'],
|
||||||
|
'no-fallthrough': 2,
|
||||||
|
'no-floating-decimal': 2,
|
||||||
|
'no-func-assign': 2,
|
||||||
|
'no-implied-eval': 2,
|
||||||
|
'no-inner-declarations': [2, 'functions'],
|
||||||
|
'no-invalid-regexp': 2,
|
||||||
|
'no-irregular-whitespace': 2,
|
||||||
|
'no-iterator': 2,
|
||||||
|
'no-label-var': 2,
|
||||||
|
'no-labels': [2, {
|
||||||
|
'allowLoop': false,
|
||||||
|
'allowSwitch': false
|
||||||
|
}],
|
||||||
|
'no-lone-blocks': 2,
|
||||||
|
'no-mixed-spaces-and-tabs': 2,
|
||||||
|
'no-multi-spaces': 2,
|
||||||
|
'no-multi-str': 2,
|
||||||
|
'no-multiple-empty-lines': [2, {
|
||||||
|
'max': 1
|
||||||
|
}],
|
||||||
|
'no-native-reassign': 2,
|
||||||
|
'no-negated-in-lhs': 2,
|
||||||
|
'no-new-object': 2,
|
||||||
|
'no-new-require': 2,
|
||||||
|
'no-new-symbol': 2,
|
||||||
|
'no-new-wrappers': 2,
|
||||||
|
'no-obj-calls': 2,
|
||||||
|
'no-octal': 2,
|
||||||
|
'no-octal-escape': 2,
|
||||||
|
'no-path-concat': 2,
|
||||||
|
'no-proto': 2,
|
||||||
|
'no-redeclare': 2,
|
||||||
|
'no-regex-spaces': 2,
|
||||||
|
'no-return-assign': [2, 'except-parens'],
|
||||||
|
'no-self-assign': 2,
|
||||||
|
'no-self-compare': 2,
|
||||||
|
'no-sequences': 2,
|
||||||
|
'no-shadow-restricted-names': 2,
|
||||||
|
'no-spaced-func': 2,
|
||||||
|
'no-sparse-arrays': 2,
|
||||||
|
'no-this-before-super': 2,
|
||||||
|
'no-throw-literal': 2,
|
||||||
|
'no-trailing-spaces': 2,
|
||||||
|
'no-undef': 2,
|
||||||
|
'no-undef-init': 2,
|
||||||
|
'no-unexpected-multiline': 2,
|
||||||
|
'no-unmodified-loop-condition': 2,
|
||||||
|
'no-unneeded-ternary': [2, {
|
||||||
|
'defaultAssignment': false
|
||||||
|
}],
|
||||||
|
'no-unreachable': 2,
|
||||||
|
'no-unsafe-finally': 2,
|
||||||
|
'no-unused-vars': [2, {
|
||||||
|
'vars': 'all',
|
||||||
|
'args': 'none'
|
||||||
|
}],
|
||||||
|
'no-useless-call': 2,
|
||||||
|
'no-useless-computed-key': 2,
|
||||||
|
'no-useless-constructor': 2,
|
||||||
|
'no-useless-escape': 0,
|
||||||
|
'no-whitespace-before-property': 2,
|
||||||
|
'no-with': 2,
|
||||||
|
'one-var': [2, {
|
||||||
|
'initialized': 'never'
|
||||||
|
}],
|
||||||
|
'operator-linebreak': [2, 'after', {
|
||||||
|
'overrides': {
|
||||||
|
'?': 'before',
|
||||||
|
':': 'before'
|
||||||
|
}
|
||||||
|
}],
|
||||||
|
'padded-blocks': [2, 'never'],
|
||||||
|
'quotes': [2, 'single', {
|
||||||
|
'avoidEscape': true,
|
||||||
|
'allowTemplateLiterals': true
|
||||||
|
}],
|
||||||
|
'semi': [2, 'never'],
|
||||||
|
'semi-spacing': [2, {
|
||||||
|
'before': false,
|
||||||
|
'after': true
|
||||||
|
}],
|
||||||
|
'space-before-blocks': [2, 'always'],
|
||||||
|
'space-before-function-paren': [2, 'never'],
|
||||||
|
'space-in-parens': [2, 'never'],
|
||||||
|
'space-infix-ops': 2,
|
||||||
|
'space-unary-ops': [2, {
|
||||||
|
'words': true,
|
||||||
|
'nonwords': false
|
||||||
|
}],
|
||||||
|
'spaced-comment': [2, 'always', {
|
||||||
|
'markers': ['global', 'globals', 'eslint', 'eslint-disable', '*package', '!', ',']
|
||||||
|
}],
|
||||||
|
'template-curly-spacing': [2, 'never'],
|
||||||
|
'use-isnan': 2,
|
||||||
|
'valid-typeof': 2,
|
||||||
|
'wrap-iife': [2, 'any'],
|
||||||
|
'yield-star-spacing': [2, 'both'],
|
||||||
|
'yoda': [2, 'never'],
|
||||||
|
'prefer-const': 2,
|
||||||
|
'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0,
|
||||||
|
'object-curly-spacing': [2, 'always', {
|
||||||
|
objectsInObjects: false
|
||||||
|
}],
|
||||||
|
'array-bracket-spacing': [2, 'never']
|
||||||
|
}
|
||||||
|
}
|
5
8_suite_hub/iocr/ocr-ui/.travis.yml
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
language: node_js
|
||||||
|
node_js: 10
|
||||||
|
script: npm run test
|
||||||
|
notifications:
|
||||||
|
email: false
|
14
8_suite_hub/iocr/ocr-ui/babel.config.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
module.exports = {
|
||||||
|
presets: [
|
||||||
|
// https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app
|
||||||
|
'@vue/cli-plugin-babel/preset'
|
||||||
|
],
|
||||||
|
'env': {
|
||||||
|
'development': {
|
||||||
|
// babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require().
|
||||||
|
// This plugin can significantly increase the speed of hot updates, when you have a large number of pages.
|
||||||
|
// https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html
|
||||||
|
'plugins': ['dynamic-import-node']
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
35
8_suite_hub/iocr/ocr-ui/build/index.js
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
const { run } = require('runjs')
|
||||||
|
const chalk = require('chalk')
|
||||||
|
const config = require('../vue.config.js')
|
||||||
|
const rawArgv = process.argv.slice(2)
|
||||||
|
const args = rawArgv.join(' ')
|
||||||
|
|
||||||
|
if (process.env.npm_config_preview || rawArgv.includes('--preview')) {
|
||||||
|
const report = rawArgv.includes('--report')
|
||||||
|
|
||||||
|
run(`vue-cli-service build ${args}`)
|
||||||
|
|
||||||
|
const port = 9526
|
||||||
|
const publicPath = config.publicPath
|
||||||
|
|
||||||
|
var connect = require('connect')
|
||||||
|
var serveStatic = require('serve-static')
|
||||||
|
const app = connect()
|
||||||
|
|
||||||
|
app.use(
|
||||||
|
publicPath,
|
||||||
|
serveStatic('./dist', {
|
||||||
|
index: ['index.html', '/']
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
app.listen(port, function () {
|
||||||
|
console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`))
|
||||||
|
if (report) {
|
||||||
|
console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`))
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
run(`vue-cli-service build ${args}`)
|
||||||
|
}
|
24
8_suite_hub/iocr/ocr-ui/jest.config.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
module.exports = {
|
||||||
|
moduleFileExtensions: ['js', 'jsx', 'json', 'vue'],
|
||||||
|
transform: {
|
||||||
|
'^.+\\.vue$': 'vue-jest',
|
||||||
|
'.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$':
|
||||||
|
'jest-transform-stub',
|
||||||
|
'^.+\\.jsx?$': 'babel-jest'
|
||||||
|
},
|
||||||
|
moduleNameMapper: {
|
||||||
|
'^@/(.*)$': '<rootDir>/src/$1'
|
||||||
|
},
|
||||||
|
snapshotSerializers: ['jest-serializer-vue'],
|
||||||
|
testMatch: [
|
||||||
|
'**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)'
|
||||||
|
],
|
||||||
|
collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'],
|
||||||
|
coverageDirectory: '<rootDir>/tests/unit/coverage',
|
||||||
|
// 'collectCoverage': true,
|
||||||
|
'coverageReporters': [
|
||||||
|
'lcov',
|
||||||
|
'text-summary'
|
||||||
|
],
|
||||||
|
testURL: 'http://localhost/'
|
||||||
|
}
|
9
8_suite_hub/iocr/ocr-ui/jsconfig.json
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./",
|
||||||
|
"paths": {
|
||||||
|
"@/*": ["src/*"]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"exclude": ["node_modules", "dist"]
|
||||||
|
}
|
65
8_suite_hub/iocr/ocr-ui/package.json
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"name": "ocr-ui",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "OCR UI Demo",
|
||||||
|
"author": "Calvin <693544619@qq.com>",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "vue-cli-service serve",
|
||||||
|
"build:prod": "vue-cli-service build",
|
||||||
|
"build:stage": "vue-cli-service build --mode staging",
|
||||||
|
"preview": "node build/index.js --preview",
|
||||||
|
"lint": "eslint --ext .js,.vue src",
|
||||||
|
"test:unit": "jest --clearCache && vue-cli-service test:unit",
|
||||||
|
"test:ci": "npm run lint && npm run test:unit"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"axios": "0.18.1",
|
||||||
|
"core-js": "3.6.5",
|
||||||
|
"easy-circular-progress": "1.0.4",
|
||||||
|
"echarts": "^4.2.1",
|
||||||
|
"element-ui": "2.13.2",
|
||||||
|
"js-base64": "^2.6.4",
|
||||||
|
"js-cookie": "2.2.0",
|
||||||
|
"normalize.css": "7.0.0",
|
||||||
|
"nprogress": "0.2.0",
|
||||||
|
"path-to-regexp": "2.4.0",
|
||||||
|
"vertx3-eventbus-client": "^3.9.4",
|
||||||
|
"vue": "2.6.10",
|
||||||
|
"vue-count-to": "^1.0.13",
|
||||||
|
"vue-json-viewer": "^2.2.18",
|
||||||
|
"vue-router": "3.0.6",
|
||||||
|
"vuex": "3.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@vue/cli-plugin-babel": "4.4.4",
|
||||||
|
"@vue/cli-plugin-eslint": "4.4.4",
|
||||||
|
"@vue/cli-plugin-unit-jest": "4.4.4",
|
||||||
|
"@vue/cli-service": "4.4.4",
|
||||||
|
"@vue/test-utils": "1.0.0-beta.29",
|
||||||
|
"autoprefixer": "9.5.1",
|
||||||
|
"babel-eslint": "10.1.0",
|
||||||
|
"babel-jest": "23.6.0",
|
||||||
|
"babel-plugin-dynamic-import-node": "2.3.3",
|
||||||
|
"chalk": "2.4.2",
|
||||||
|
"connect": "3.6.6",
|
||||||
|
"eslint": "6.7.2",
|
||||||
|
"eslint-plugin-vue": "6.2.2",
|
||||||
|
"html-webpack-plugin": "3.2.0",
|
||||||
|
"mockjs": "1.0.1-beta3",
|
||||||
|
"runjs": "4.3.2",
|
||||||
|
"sass": "1.26.8",
|
||||||
|
"sass-loader": "8.0.2",
|
||||||
|
"script-ext-html-webpack-plugin": "2.1.3",
|
||||||
|
"serve-static": "1.13.2",
|
||||||
|
"vue-template-compiler": "2.6.10"
|
||||||
|
},
|
||||||
|
"browserslist": [
|
||||||
|
"> 1%",
|
||||||
|
"last 2 versions"
|
||||||
|
],
|
||||||
|
"engines": {
|
||||||
|
"node": ">=8.9",
|
||||||
|
"npm": ">= 3.0.0"
|
||||||
|
},
|
||||||
|
"license": "MIT"
|
||||||
|
}
|
8
8_suite_hub/iocr/ocr-ui/postcss.config.js
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
// https://github.com/michael-ciniawsky/postcss-load-config
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
'plugins': {
|
||||||
|
// to edit target browsers: use "browserslist" field in package.json
|
||||||
|
'autoprefixer': {}
|
||||||
|
}
|
||||||
|
}
|
BIN
8_suite_hub/iocr/ocr-ui/public/favicon.ico
Normal file
After Width: | Height: | Size: 17 KiB |
17
8_suite_hub/iocr/ocr-ui/public/index.html
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no">
|
||||||
|
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
|
||||||
|
<title><%= webpackConfig.name %></title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<noscript>
|
||||||
|
<strong>We're sorry but <%= webpackConfig.name %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
|
||||||
|
</noscript>
|
||||||
|
<div id="app"></div>
|
||||||
|
<!-- built files will be auto injected -->
|
||||||
|
</body>
|
||||||
|
</html>
|
11
8_suite_hub/iocr/ocr-ui/src/App.vue
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
<template>
|
||||||
|
<div id="app">
|
||||||
|
<router-view />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'App'
|
||||||
|
}
|
||||||
|
</script>
|
14
8_suite_hub/iocr/ocr-ui/src/api/inference.js
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function generalInfoForImageUrl(data) {
|
||||||
|
return request({
|
||||||
|
url: '/inference/generalInfoForImageUrl',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
url: data.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { generalInfoForImageUrl }
|
||||||
|
|
24
8_suite_hub/iocr/ocr-ui/src/api/table.js
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function tableInfoForImageUrl(data) {
|
||||||
|
return request({
|
||||||
|
url: '/table/tableInfoForImageUrl',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
url: data.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function autoTableInfoForImageUrl(data) {
|
||||||
|
return request({
|
||||||
|
url: '/table/autoTableInfoForImageUrl',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
url: data.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { tableInfoForImageUrl, autoTableInfoForImageUrl }
|
||||||
|
|
68
8_suite_hub/iocr/ocr-ui/src/api/template.js
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
import request from '@/utils/request'
|
||||||
|
|
||||||
|
export function infoForImageUrl(uid, data) {
|
||||||
|
return request({
|
||||||
|
url: '/template/infoForImageUrl',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
uid: uid,
|
||||||
|
url: data.url
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplate(uid) {
|
||||||
|
return request({
|
||||||
|
url: '/template/getTemplate',
|
||||||
|
method: 'get',
|
||||||
|
params: {
|
||||||
|
uid: uid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getTemplates() {
|
||||||
|
return request({
|
||||||
|
url: '/template/getTemplates',
|
||||||
|
method: 'get'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function updateTemplate(data) {
|
||||||
|
return request({
|
||||||
|
url: '/template/updateTemplate',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getLabelData(data) {
|
||||||
|
return request({
|
||||||
|
url: '/template/getLabelData',
|
||||||
|
method: 'post',
|
||||||
|
data
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addTemplate(name, imageFile) {
|
||||||
|
return request({
|
||||||
|
url: '/template/updateTemplate',
|
||||||
|
method: 'post',
|
||||||
|
params: {
|
||||||
|
name: name,
|
||||||
|
imageFile: imageFile
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function removeTemplate(uid) {
|
||||||
|
return request({
|
||||||
|
url: '/template/removeTemplate',
|
||||||
|
method: 'post',
|
||||||
|
params: {
|
||||||
|
uid: uid
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export default { getTemplate, getTemplates, updateTemplate, getLabelData, addTemplate, removeTemplate }
|
BIN
8_suite_hub/iocr/ocr-ui/src/assets/404_images/404.png
Normal file
After Width: | Height: | Size: 96 KiB |
BIN
8_suite_hub/iocr/ocr-ui/src/assets/404_images/404_cloud.png
Normal file
After Width: | Height: | Size: 4.7 KiB |
78
8_suite_hub/iocr/ocr-ui/src/components/Breadcrumb/index.vue
Normal file
@ -0,0 +1,78 @@
|
|||||||
|
<template>
|
||||||
|
<el-breadcrumb class="app-breadcrumb" separator="/">
|
||||||
|
<transition-group name="breadcrumb">
|
||||||
|
<el-breadcrumb-item v-for="(item,index) in levelList" :key="item.path">
|
||||||
|
<span v-if="item.redirect==='noRedirect'||index==levelList.length-1" class="no-redirect">{{ item.meta.title }}</span>
|
||||||
|
<a v-else @click.prevent="handleLink(item)">{{ item.meta.title }}</a>
|
||||||
|
</el-breadcrumb-item>
|
||||||
|
</transition-group>
|
||||||
|
</el-breadcrumb>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import pathToRegexp from 'path-to-regexp'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
data() {
|
||||||
|
return {
|
||||||
|
levelList: null
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
$route() {
|
||||||
|
this.getBreadcrumb()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
created() {
|
||||||
|
this.getBreadcrumb()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
getBreadcrumb() {
|
||||||
|
// only show routes with meta.title
|
||||||
|
let matched = this.$route.matched.filter(item => item.meta && item.meta.title)
|
||||||
|
const first = matched[0]
|
||||||
|
|
||||||
|
if (!this.isDashboard(first)) {
|
||||||
|
matched = [{ path: '/dashboard', meta: { title: 'Dashboard' }}].concat(matched)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.levelList = matched.filter(item => item.meta && item.meta.title && item.meta.breadcrumb !== false)
|
||||||
|
},
|
||||||
|
isDashboard(route) {
|
||||||
|
const name = route && route.name
|
||||||
|
if (!name) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return name.trim().toLocaleLowerCase() === 'Dashboard'.toLocaleLowerCase()
|
||||||
|
},
|
||||||
|
pathCompile(path) {
|
||||||
|
// To solve this problem https://github.com/PanJiaChen/vue-element-admin/issues/561
|
||||||
|
const { params } = this.$route
|
||||||
|
var toPath = pathToRegexp.compile(path)
|
||||||
|
return toPath(params)
|
||||||
|
},
|
||||||
|
handleLink(item) {
|
||||||
|
const { redirect, path } = item
|
||||||
|
if (redirect) {
|
||||||
|
this.$router.push(redirect)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
this.$router.push(this.pathCompile(path))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.app-breadcrumb.el-breadcrumb {
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 50px;
|
||||||
|
margin-left: 8px;
|
||||||
|
|
||||||
|
.no-redirect {
|
||||||
|
color: #97a8be;
|
||||||
|
cursor: text;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
44
8_suite_hub/iocr/ocr-ui/src/components/Hamburger/index.vue
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<template>
|
||||||
|
<div style="padding: 0 15px;" @click="toggleClick">
|
||||||
|
<svg
|
||||||
|
:class="{'is-active':isActive}"
|
||||||
|
class="hamburger"
|
||||||
|
viewBox="0 0 1024 1024"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
width="64"
|
||||||
|
height="64"
|
||||||
|
>
|
||||||
|
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM142.4 642.1L298.7 519a8.84 8.84 0 0 0 0-13.9L142.4 381.9c-5.8-4.6-14.4-.5-14.4 6.9v246.3a8.9 8.9 0 0 0 14.4 7z" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'Hamburger',
|
||||||
|
props: {
|
||||||
|
isActive: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleClick() {
|
||||||
|
this.$emit('toggleClick')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.hamburger {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hamburger.is-active {
|
||||||
|
transform: rotate(180deg);
|
||||||
|
}
|
||||||
|
</style>
|
62
8_suite_hub/iocr/ocr-ui/src/components/SvgIcon/index.vue
Normal file
@ -0,0 +1,62 @@
|
|||||||
|
<template>
|
||||||
|
<div v-if="isExternal" :style="styleExternalIcon" class="svg-external-icon svg-icon" v-on="$listeners" />
|
||||||
|
<svg v-else :class="svgClass" aria-hidden="true" v-on="$listeners">
|
||||||
|
<use :xlink:href="iconName" />
|
||||||
|
</svg>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
// doc: https://panjiachen.github.io/vue-element-admin-site/feature/component/svg-icon.html#usage
|
||||||
|
import { isExternal } from '@/utils/validate'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
name: 'SvgIcon',
|
||||||
|
props: {
|
||||||
|
iconClass: {
|
||||||
|
type: String,
|
||||||
|
required: true
|
||||||
|
},
|
||||||
|
className: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
isExternal() {
|
||||||
|
return isExternal(this.iconClass)
|
||||||
|
},
|
||||||
|
iconName() {
|
||||||
|
return `#icon-${this.iconClass}`
|
||||||
|
},
|
||||||
|
svgClass() {
|
||||||
|
if (this.className) {
|
||||||
|
return 'svg-icon ' + this.className
|
||||||
|
} else {
|
||||||
|
return 'svg-icon'
|
||||||
|
}
|
||||||
|
},
|
||||||
|
styleExternalIcon() {
|
||||||
|
return {
|
||||||
|
mask: `url(${this.iconClass}) no-repeat 50% 50%`,
|
||||||
|
'-webkit-mask': `url(${this.iconClass}) no-repeat 50% 50%`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.svg-icon {
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
vertical-align: -0.15em;
|
||||||
|
fill: currentColor;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
.svg-external-icon {
|
||||||
|
background-color: currentColor;
|
||||||
|
mask-size: cover!important;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
</style>
|
40
8_suite_hub/iocr/ocr-ui/src/layout/components/AppMain.vue
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
<template>
|
||||||
|
<section class="app-main">
|
||||||
|
<transition name="fade-transform" mode="out-in">
|
||||||
|
<router-view :key="key" />
|
||||||
|
</transition>
|
||||||
|
</section>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'AppMain',
|
||||||
|
computed: {
|
||||||
|
key() {
|
||||||
|
return this.$route.path
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.app-main {
|
||||||
|
/*50 = navbar */
|
||||||
|
min-height: calc(100vh - 50px);
|
||||||
|
width: 100%;
|
||||||
|
position: relative;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
.fixed-header+.app-main {
|
||||||
|
padding-top: 50px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
// fix css style bug in open el-dialog
|
||||||
|
.el-popup-parent--hidden {
|
||||||
|
.fixed-header {
|
||||||
|
padding-right: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
111
8_suite_hub/iocr/ocr-ui/src/layout/components/Navbar.vue
Normal file
@ -0,0 +1,111 @@
|
|||||||
|
<template>
|
||||||
|
<div class="navbar">
|
||||||
|
<hamburger :is-active="sidebar.opened" class="hamburger-container" @toggleClick="toggleSideBar" />
|
||||||
|
|
||||||
|
<breadcrumb class="breadcrumb-container" />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import { mapGetters } from 'vuex'
|
||||||
|
import Breadcrumb from '@/components/Breadcrumb'
|
||||||
|
import Hamburger from '@/components/Hamburger'
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
Breadcrumb,
|
||||||
|
Hamburger
|
||||||
|
},
|
||||||
|
computed: {
|
||||||
|
...mapGetters([
|
||||||
|
'sidebar',
|
||||||
|
'avatar'
|
||||||
|
])
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
toggleSideBar() {
|
||||||
|
this.$store.dispatch('app/toggleSideBar')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.navbar {
|
||||||
|
height: 50px;
|
||||||
|
overflow: hidden;
|
||||||
|
position: relative;
|
||||||
|
background: #fff;
|
||||||
|
box-shadow: 0 1px 4px rgba(0,21,41,.08);
|
||||||
|
|
||||||
|
.hamburger-container {
|
||||||
|
line-height: 46px;
|
||||||
|
height: 100%;
|
||||||
|
float: left;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .3s;
|
||||||
|
-webkit-tap-highlight-color:transparent;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, .025)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.breadcrumb-container {
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-menu {
|
||||||
|
float: right;
|
||||||
|
height: 100%;
|
||||||
|
line-height: 50px;
|
||||||
|
|
||||||
|
&:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.right-menu-item {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 8px;
|
||||||
|
height: 100%;
|
||||||
|
font-size: 18px;
|
||||||
|
color: #5a5e66;
|
||||||
|
vertical-align: text-bottom;
|
||||||
|
|
||||||
|
&.hover-effect {
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background .3s;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: rgba(0, 0, 0, .025)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.avatar-container {
|
||||||
|
margin-right: 30px;
|
||||||
|
|
||||||
|
.avatar-wrapper {
|
||||||
|
margin-top: 5px;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.user-avatar {
|
||||||
|
cursor: pointer;
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
border-radius: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.el-icon-caret-bottom {
|
||||||
|
cursor: pointer;
|
||||||
|
position: absolute;
|
||||||
|
right: -20px;
|
||||||
|
top: 25px;
|
||||||
|
font-size: 12px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -0,0 +1,26 @@
|
|||||||
|
export default {
|
||||||
|
computed: {
|
||||||
|
device() {
|
||||||
|
return this.$store.state.app.device
|
||||||
|
}
|
||||||
|
},
|
||||||
|
mounted() {
|
||||||
|
// In order to fix the click on menu on the ios device will trigger the mouseleave bug
|
||||||
|
// https://github.com/PanJiaChen/vue-element-admin/issues/1135
|
||||||
|
this.fixBugIniOS()
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
fixBugIniOS() {
|
||||||
|
const $subMenu = this.$refs.subMenu
|
||||||
|
if ($subMenu) {
|
||||||
|
const handleMouseleave = $subMenu.handleMouseleave
|
||||||
|
$subMenu.handleMouseleave = (e) => {
|
||||||
|
if (this.device === 'mobile') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
handleMouseleave(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,41 @@
|
|||||||
|
<script>
|
||||||
|
export default {
|
||||||
|
name: 'MenuItem',
|
||||||
|
functional: true,
|
||||||
|
props: {
|
||||||
|
icon: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
},
|
||||||
|
title: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
|
}
|
||||||
|
},
|
||||||
|
render(h, context) {
|
||||||
|
const { icon, title } = context.props
|
||||||
|
const vnodes = []
|
||||||
|
|
||||||
|
if (icon) {
|
||||||
|
if (icon.includes('el-icon')) {
|
||||||
|
vnodes.push(<i class={[icon, 'sub-el-icon']} />)
|
||||||
|
} else {
|
||||||
|
vnodes.push(<svg-icon icon-class={icon}/>)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (title) {
|
||||||
|
vnodes.push(<span slot='title'>{(title)}</span>)
|
||||||
|
}
|
||||||
|
return vnodes
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.sub-el-icon {
|
||||||
|
color: currentColor;
|
||||||
|
width: 1em;
|
||||||
|
height: 1em;
|
||||||
|
}
|
||||||
|
</style>
|