update site link and renew iocr.
@ -1,5 +1,5 @@
|
||||
### 官网:
|
||||
[官网链接](http://www.aias.top/)
|
||||
[官网链接](https://www.aias.top/)
|
||||
|
||||
### 动物分类识别SDK
|
||||
动物识别sdk,支持7978种动物的分类识别。
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
### Git地址:
|
||||
[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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
@ -39,7 +39,7 @@
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
### Git地址:
|
||||
[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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
@ -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地址:
|
||||
@ -103,12 +103,12 @@ http://aias.top/guides.html
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
@ -118,7 +118,7 @@ if __name__ == '__main__':
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
### Git地址:
|
||||
[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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
### 不得用于非法用途!
|
||||
@ -43,7 +43,7 @@ build/output/result.gif
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
|
||||
### Git地址:
|
||||
@ -55,12 +55,12 @@ https://gitee.com/endlesshh/first-order-model-java
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
风格迁移可以把一张图片转换成另一种风格。本sdk预定义了4种画风:
|
||||
@ -38,7 +38,7 @@
|
||||
#### 找不到了,后面会有更好的替换
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
|
||||
### Git地址:
|
||||
@ -47,12 +47,12 @@ http://aias.top/guides.html
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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倍分辨率。
|
||||
@ -32,12 +32,12 @@
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
在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地址:
|
||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||
|
@ -1,5 +1,5 @@
|
||||
### 官网:
|
||||
[官网链接](http://www.aias.top/)
|
||||
[官网链接](https://www.aias.top/)
|
||||
|
||||
|
||||
### 人脸对齐 SDK
|
||||
@ -46,7 +46,7 @@
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
|
||||
### Git地址:
|
||||
@ -56,12 +56,12 @@ http://aias.top/guides.html
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
@ -54,7 +54,7 @@
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
|
||||
### Git地址:
|
||||
@ -63,12 +63,12 @@ http://aias.top/guides.html
|
||||
|
||||
|
||||
#### 帮助文档:
|
||||
- http://aias.top/guides.html
|
||||
- https://aias.top/guides.html
|
||||
- 1.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
@ -36,7 +36,7 @@
|
||||
|
||||
|
||||
### 其它帮助信息
|
||||
http://aias.top/guides.html
|
||||
https://aias.top/guides.html
|
||||
|
||||
### Git地址:
|
||||
[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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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
|
||||
*/
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
### 官网:
|
||||
[官网链接](http://www.aias.top/)
|
||||
[官网链接](https://www.aias.top/)
|
||||
|
||||
## 文字识别(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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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地址:
|
||||
[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.性能优化常见问题:
|
||||
- http://aias.top/AIAS/guides/performance.html
|
||||
- https://aias.top/AIAS/guides/performance.html
|
||||
- 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/engine_config.html
|
||||
- https://aias.top/AIAS/guides/engine_config.html
|
||||
- 3.模型加载方式(在线自动加载,及本地配置):
|
||||
- http://aias.top/AIAS/guides/load_model.html
|
||||
- https://aias.top/AIAS/guides/load_model.html
|
||||
- 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>
|