├── ocr_web_app ├── ocr_ui │ ├── .eslintignore │ ├── tests │ │ └── unit │ │ │ ├── .eslintrc.js │ │ │ ├── utils │ │ │ ├── param2Obj.spec.js │ │ │ ├── validate.spec.js │ │ │ ├── formatTime.spec.js │ │ │ └── parseTime.spec.js │ │ │ └── components │ │ │ ├── SvgIcon.spec.js │ │ │ └── Hamburger.spec.js │ ├── .travis.yml │ ├── public │ │ ├── favicon.ico │ │ └── index.html │ ├── .idea │ │ ├── .gitignore │ │ ├── codeStyles │ │ │ ├── codeStyleConfig.xml │ │ │ └── Project.xml │ │ ├── vcs.xml │ │ ├── modules.xml │ │ ├── inspectionProfiles │ │ │ └── Project_Default.xml │ │ └── ocr_ui.iml │ ├── src │ │ ├── assets │ │ │ ├── 404_images │ │ │ │ ├── 404.png │ │ │ │ └── 404_cloud.png │ │ │ └── styles │ │ │ │ ├── variables.scss │ │ │ │ ├── transition.scss │ │ │ │ ├── element-variables.scss │ │ │ │ ├── base.scss │ │ │ │ ├── element-ui.scss │ │ │ │ ├── mixin.scss │ │ │ │ ├── btn.scss │ │ │ │ └── eladmin.scss │ │ ├── layout │ │ │ ├── components │ │ │ │ ├── index.js │ │ │ │ ├── Sidebar │ │ │ │ │ ├── FixiOSBug.js │ │ │ │ │ ├── Link.vue │ │ │ │ │ ├── Item.vue │ │ │ │ │ ├── index.vue │ │ │ │ │ └── Logo.vue │ │ │ │ ├── AppMain.vue │ │ │ │ └── Navbar.vue │ │ │ ├── mixin │ │ │ │ └── ResizeHandler.js │ │ │ └── index.vue │ │ ├── App.vue │ │ ├── store │ │ │ ├── getters.js │ │ │ ├── index.js │ │ │ └── modules │ │ │ │ ├── settings.js │ │ │ │ └── app.js │ │ ├── utils │ │ │ ├── get-page-title.js │ │ │ ├── validate.js │ │ │ └── request.js │ │ ├── settings.js │ │ ├── styles │ │ │ ├── mixin.scss │ │ │ ├── variables.scss │ │ │ ├── element-ui.scss │ │ │ ├── transition.scss │ │ │ └── index.scss │ │ ├── api │ │ │ ├── inference.js │ │ │ └── table.js │ │ ├── permission.js │ │ ├── main.js │ │ ├── common │ │ │ └── mixin │ │ │ │ └── table-mixin.js │ │ └── components │ │ │ ├── Hamburger │ │ │ └── index.vue │ │ │ ├── SvgIcon │ │ │ └── index.vue │ │ │ └── Breadcrumb │ │ │ └── index.vue │ ├── .env.production │ ├── .env.development │ ├── .env.staging │ ├── jsconfig.json │ ├── postcss.config.js │ ├── .editorconfig │ ├── babel.config.js │ ├── jest.config.js │ ├── build │ │ └── index.js │ ├── nginx.conf │ └── package.json ├── windows nginx配置参考文档.docx ├── Ubuntu配置java与nginx_V0.2.pdf └── ocr_backend │ ├── src │ ├── main │ │ ├── java │ │ │ ├── META-INF │ │ │ │ └── MANIFEST.MF │ │ │ └── top │ │ │ │ └── aias │ │ │ │ └── ocr │ │ │ │ ├── bean │ │ │ │ ├── LabelDTO.java │ │ │ │ ├── DataBean.java │ │ │ │ ├── ProjBean.java │ │ │ │ ├── Point.java │ │ │ │ ├── TemplateBean.java │ │ │ │ ├── LabelBean.java │ │ │ │ ├── TableResult.java │ │ │ │ ├── CrossRangeCellMeta.java │ │ │ │ ├── ResultBean.java │ │ │ │ └── RotatedBox.java │ │ │ │ ├── utils │ │ │ │ ├── UUIDUtils.java │ │ │ │ ├── Constants.java │ │ │ │ └── DJLImageUtils.java │ │ │ │ ├── MainApplication.java │ │ │ │ ├── service │ │ │ │ ├── TableInferService.java │ │ │ │ ├── InferService.java │ │ │ │ └── impl │ │ │ │ │ └── InferServiceImpl.java │ │ │ │ ├── configuration │ │ │ │ ├── FileProperties.java │ │ │ │ └── ModelConfiguration.java │ │ │ │ └── model │ │ │ │ ├── pool │ │ │ │ ├── MlsdPool.java │ │ │ │ ├── DetectorPool.java │ │ │ │ ├── RecognizerPool.java │ │ │ │ ├── TableRecPool.java │ │ │ │ ├── LayoutPool.java │ │ │ │ └── HorizontalDetectorPool.java │ │ │ │ └── LayoutDetectionModel.java │ │ ├── main.iml │ │ └── resources │ │ │ ├── log4j2.xml │ │ │ ├── application.yml │ │ │ ├── application-linux.yml │ │ │ ├── application-mac.yml │ │ │ ├── application-online.yml │ │ │ └── application-win.yml │ └── test │ │ └── test.iml │ ├── build │ └── opencv │ │ ├── result.png │ │ └── perspective.png │ ├── output │ └── ocr │ │ └── paddle_OCR_detect.png │ └── ocr_backend.iml ├── ocr_v3_sdk ├── src │ ├── test │ │ └── resources │ │ │ ├── 1.jpg │ │ │ ├── 2.jpg │ │ │ ├── aaa.png │ │ │ ├── d2.jpg │ │ │ ├── freetxt.png │ │ │ ├── langs │ │ │ ├── ch.png │ │ │ ├── ch2.png │ │ │ ├── cht.png │ │ │ ├── en.png │ │ │ ├── ka.png │ │ │ ├── ta.png │ │ │ ├── te.png │ │ │ ├── japan.png │ │ │ ├── arabic.png │ │ │ ├── korean.png │ │ │ └── devanagari.png │ │ │ └── ticket_0.png │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ ├── utils │ │ ├── common │ │ │ ├── ImageInfo.java │ │ │ ├── RotatedBox.java │ │ │ └── RotatedBoxCompX.java │ │ ├── opencv │ │ │ └── OpenCVUtils.java │ │ └── detection │ │ │ └── OcrV3Detection.java │ │ └── OcrV3DetExample.java ├── build │ └── output │ │ └── ocr_result.png ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md ├── ocr_v4_sdk ├── src │ ├── test │ │ └── resources │ │ │ ├── 1.jpg │ │ │ └── 2.jpg │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ ├── utils │ │ ├── common │ │ │ ├── ImageInfo.java │ │ │ ├── RotatedBox.java │ │ │ └── RotatedBoxCompX.java │ │ ├── detection │ │ │ └── OcrV4Detection.java │ │ └── opencv │ │ │ └── OpenCVUtils.java │ │ └── OcrV4DetExample.java ├── build │ └── output │ │ ├── ocr_result.png │ │ └── detect_rect.png ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── ocr_v4_sdk.iml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md ├── ocr_led_sdk ├── src │ ├── test │ │ └── resources │ │ │ └── led.jpg │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ ├── utils │ │ ├── common │ │ │ ├── ImageInfo.java │ │ │ ├── RotatedBox.java │ │ │ └── RotatedBoxCompX.java │ │ ├── opencv │ │ │ └── OpenCVUtils.java │ │ └── detection │ │ │ └── OcrV3Detection.java │ │ └── OcrV3DetExample.java ├── build │ └── output │ │ ├── detect_rect.png │ │ └── ocr_result.png ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── ocr_led_sdk.iml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md ├── ocr_table_sdk ├── build │ └── output │ │ ├── table.xls │ │ ├── table_cells_content.png │ │ ├── table_cells_detected.png │ │ ├── table_texts_detected.png │ │ └── table.html ├── src │ ├── test │ │ └── resources │ │ │ ├── aaa.jpg │ │ │ ├── img.png │ │ │ ├── table.jpg │ │ │ ├── chTable.png │ │ │ └── tables.jpeg │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ └── utils │ │ ├── common │ │ └── DirectionInfo.java │ │ ├── table │ │ ├── TableResult.java │ │ └── CrossRangeCellMeta.java │ │ └── layout │ │ └── LayoutDetection.java ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md ├── ocr_layout_sdk ├── src │ ├── test │ │ └── resources │ │ │ ├── 1.png │ │ │ ├── 2.png │ │ │ └── 3.png │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ ├── TableDetExample.java │ │ ├── LayoutCNDetExample.java │ │ ├── LayoutENDetExample.java │ │ └── utils │ │ └── layout │ │ └── LayoutDetection.java ├── build │ └── output │ │ ├── table_detect_result.png │ │ ├── cn_layout_detect_result.png │ │ └── en_layout_detect_result.png ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md ├── ocr_direction_det_sdk ├── src │ ├── test │ │ └── resources │ │ │ ├── ticket_0.png │ │ │ ├── ticket_180.png │ │ │ ├── ticket_270.png │ │ │ └── ticket_90.png │ └── main │ │ ├── resources │ │ └── log4j2.xml │ │ └── java │ │ └── top │ │ └── aias │ │ └── ocr │ │ ├── utils │ │ ├── common │ │ │ ├── DirectionInfo.java │ │ │ └── RotatedBox.java │ │ ├── detection │ │ │ └── OcrV4Detection.java │ │ ├── opencv │ │ │ └── OpenCVUtils.java │ │ └── cls │ │ │ └── PpWordRotateTranslator.java │ │ ├── RotationExample.java │ │ └── DirectionDetExample.java ├── .idea │ ├── .gitignore │ ├── vcs.xml │ ├── encodings.xml │ ├── misc.xml │ ├── compiler.xml │ └── jarRepositories.xml └── README.md └── .gitignore /ocr_web_app/ocr_ui/.eslintignore: -------------------------------------------------------------------------------- 1 | build/*.js 2 | src/assets 3 | public 4 | dist 5 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | env: { 3 | jest: true 4 | } 5 | } 6 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/1.jpg -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/2.jpg -------------------------------------------------------------------------------- /ocr_v4_sdk/src/test/resources/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v4_sdk/src/test/resources/1.jpg -------------------------------------------------------------------------------- /ocr_v4_sdk/src/test/resources/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v4_sdk/src/test/resources/2.jpg -------------------------------------------------------------------------------- /ocr_led_sdk/src/test/resources/led.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_led_sdk/src/test/resources/led.jpg -------------------------------------------------------------------------------- /ocr_table_sdk/build/output/table.xls: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/build/output/table.xls -------------------------------------------------------------------------------- /ocr_v3_sdk/build/output/ocr_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/build/output/ocr_result.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/aaa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/aaa.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/d2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/d2.jpg -------------------------------------------------------------------------------- /ocr_v4_sdk/build/output/ocr_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v4_sdk/build/output/ocr_result.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 10 3 | script: npm run test 4 | notifications: 5 | email: false 6 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_ui/public/favicon.ico -------------------------------------------------------------------------------- /ocr_web_app/windows nginx配置参考文档.docx: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/windows nginx配置参考文档.docx -------------------------------------------------------------------------------- /ocr_layout_sdk/src/test/resources/1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/src/test/resources/1.png -------------------------------------------------------------------------------- /ocr_layout_sdk/src/test/resources/2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/src/test/resources/2.png -------------------------------------------------------------------------------- /ocr_layout_sdk/src/test/resources/3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/src/test/resources/3.png -------------------------------------------------------------------------------- /ocr_led_sdk/build/output/detect_rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_led_sdk/build/output/detect_rect.png -------------------------------------------------------------------------------- /ocr_led_sdk/build/output/ocr_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_led_sdk/build/output/ocr_result.png -------------------------------------------------------------------------------- /ocr_table_sdk/src/test/resources/aaa.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/src/test/resources/aaa.jpg -------------------------------------------------------------------------------- /ocr_table_sdk/src/test/resources/img.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/src/test/resources/img.png -------------------------------------------------------------------------------- /ocr_v4_sdk/build/output/detect_rect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v4_sdk/build/output/detect_rect.png -------------------------------------------------------------------------------- /ocr_web_app/Ubuntu配置java与nginx_V0.2.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/Ubuntu配置java与nginx_V0.2.pdf -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Main-Class: top.aias.ocr.MainApplication 3 | 4 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/test/resources/table.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/src/test/resources/table.jpg -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/freetxt.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/freetxt.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/ch.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/ch.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/ch2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/ch2.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/cht.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/cht.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/en.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/en.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/ka.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/ka.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/ta.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/ta.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/te.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/te.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/ticket_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/ticket_0.png -------------------------------------------------------------------------------- /ocr_table_sdk/src/test/resources/chTable.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/src/test/resources/chTable.png -------------------------------------------------------------------------------- /ocr_table_sdk/src/test/resources/tables.jpeg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/src/test/resources/tables.jpeg -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/japan.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/japan.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/arabic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/arabic.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/korean.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/korean.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/build/opencv/result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_backend/build/opencv/result.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/404_images/404.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_ui/src/assets/404_images/404.png -------------------------------------------------------------------------------- /ocr_table_sdk/build/output/table_cells_content.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/build/output/table_cells_content.png -------------------------------------------------------------------------------- /ocr_v3_sdk/src/test/resources/langs/devanagari.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_v3_sdk/src/test/resources/langs/devanagari.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.env.production: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'production' 3 | 4 | # base api 127.0.0.1 5 | VUE_APP_BASE_API = 'http://127.0.0.1:8089' 6 | 7 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/test/resources/ticket_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_direction_det_sdk/src/test/resources/ticket_0.png -------------------------------------------------------------------------------- /ocr_layout_sdk/build/output/table_detect_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/build/output/table_detect_result.png -------------------------------------------------------------------------------- /ocr_table_sdk/build/output/table_cells_detected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/build/output/table_cells_detected.png -------------------------------------------------------------------------------- /ocr_table_sdk/build/output/table_texts_detected.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_table_sdk/build/output/table_texts_detected.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/build/opencv/perspective.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_backend/build/opencv/perspective.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.env.development: -------------------------------------------------------------------------------- 1 | # just a flag 2 | ENV = 'development' 3 | 4 | # base api 127.0.0.1 5 | VUE_APP_BASE_API = 'http://127.0.0.1:8089' 6 | 7 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.env.staging: -------------------------------------------------------------------------------- 1 | NODE_ENV = production 2 | 3 | # just a flag 4 | ENV = 'staging' 5 | 6 | # base api 7 | VUE_APP_BASE_API = '/stage-api' 8 | 9 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/test/resources/ticket_180.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_direction_det_sdk/src/test/resources/ticket_180.png -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/test/resources/ticket_270.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_direction_det_sdk/src/test/resources/ticket_270.png -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/test/resources/ticket_90.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_direction_det_sdk/src/test/resources/ticket_90.png -------------------------------------------------------------------------------- /ocr_layout_sdk/build/output/cn_layout_detect_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/build/output/cn_layout_detect_result.png -------------------------------------------------------------------------------- /ocr_layout_sdk/build/output/en_layout_detect_result.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_layout_sdk/build/output/en_layout_detect_result.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/404_images/404_cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_ui/src/assets/404_images/404_cloud.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/output/ocr/paddle_OCR_detect.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/mymagicpower/java-ocr/HEAD/ocr_web_app/ocr_backend/output/ocr/paddle_OCR_detect.png -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/index.js: -------------------------------------------------------------------------------- 1 | export { default as Navbar } from './Navbar' 2 | export { default as Sidebar } from './Sidebar' 3 | export { default as AppMain } from './AppMain' 4 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/App.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 12 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/codeStyles/codeStyleConfig.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/jsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "compilerOptions": { 3 | "baseUrl": "./", 4 | "paths": { 5 | "@/*": ["src/*"] 6 | } 7 | }, 8 | "exclude": ["node_modules", "dist"] 9 | } 10 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /shelf/ 3 | /workspace.xml 4 | # Editor-based HTTP Client requests 5 | /httpRequests/ 6 | # Datasource local storage ignored files 7 | /dataSources/ 8 | /dataSources.local.xml 9 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/ocr_backend.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/postcss.config.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = { 4 | 'plugins': { 5 | // to edit target browsers: use "browserslist" field in package.json 6 | 'autoprefixer': {} 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/store/getters.js: -------------------------------------------------------------------------------- 1 | const getters = { 2 | sidebar: state => state.app.sidebar, 3 | device: state => state.app.device, 4 | token: state => state.user.token, 5 | avatar: state => state.user.avatar, 6 | name: state => state.user.name 7 | } 8 | export default getters 9 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/utils/get-page-title.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const title = defaultSettings.title || 'Vue Admin Template' 4 | 5 | export default function getPageTitle(pageTitle) { 6 | if (pageTitle) { 7 | return `${pageTitle} - ${title}` 8 | } 9 | return `${title}` 10 | } 11 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/inspectionProfiles/Project_Default.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.editorconfig: -------------------------------------------------------------------------------- 1 | # http://editorconfig.org 2 | root = true 3 | 4 | [*] 5 | charset = utf-8 6 | indent_style = space 7 | indent_size = 2 8 | end_of_line = lf 9 | insert_final_newline = true 10 | trim_trailing_whitespace = true 11 | 12 | [*.md] 13 | insert_final_newline = false 14 | trim_trailing_whitespace = false 15 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/LabelDTO.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | /** 5 | * @author Calvin 6 | * @mail 179209347@qq.com 7 | * @website www.aias.top 8 | */ 9 | @Data 10 | public class LabelDTO { 11 | private String uid; 12 | private LabelBean labelData; 13 | } 14 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/DataBean.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | import java.util.List; 5 | /** 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | @Data 12 | public class DataBean { 13 | private String value; 14 | private List points; 15 | } 16 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/settings.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | 3 | title: 'OCR UI', 4 | 5 | /** 6 | * @type {boolean} true | false 7 | * @description Whether fix the header 8 | */ 9 | fixedHeader: false, 10 | 11 | /** 12 | * @type {boolean} true | false 13 | * @description Whether show the logo in sidebar 14 | */ 15 | sidebarLogo: false 16 | } 17 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/store/index.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | import getters from './getters' 4 | import app from './modules/app' 5 | import settings from './modules/settings' 6 | 7 | Vue.use(Vuex) 8 | 9 | const store = new Vuex.Store({ 10 | modules: { 11 | app, 12 | settings 13 | }, 14 | getters 15 | }) 16 | 17 | export default store 18 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/ocr_led_sdk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/ocr_v4_sdk.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/ProjBean.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import lombok.Data; 5 | /** 6 | * 透视变换对象 7 | * 8 | * @author Calvin 9 | * @mail 179209347@qq.com 10 | * @website www.aias.top 11 | */ 12 | @Data 13 | public class ProjBean { 14 | private Image image; 15 | private org.opencv.core.Mat warpMat; 16 | } 17 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/utils/validate.js: -------------------------------------------------------------------------------- 1 | /** 2 | * @param {string} path 3 | * @returns {Boolean} 4 | */ 5 | export function isExternal(path) { 6 | return /^(https?:|mailto:|tel:)/.test(path) 7 | } 8 | 9 | /** 10 | * @param {string} str 11 | * @returns {Boolean} 12 | */ 13 | export function validUsername(str) { 14 | const valid_map = ['admin', 'editor'] 15 | return valid_map.indexOf(str.trim()) >= 0 16 | } 17 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ocr_direction_det_sdk/models/ 2 | ocr_layout_sdk/models/ 3 | ocr_led_sdk/models/ 4 | ocr_v4_sdk/target/ 5 | ocr_v4_sdk/models/ 6 | ocr_v3_sdk/target/ 7 | ocr_v3_sdk/models/ 8 | ocr_table_sdk/models/ 9 | desktop_app_ocr/ocr_sdk/target/ 10 | ocr_web_app/ocr_backend/.idea/ 11 | ocr_web_app/ocr_backend/models/ 12 | ocr_web_app/ocr_ui/node_modules/ 13 | iocr/ocr_backend/.idea/ 14 | iocr/ocr_backend/target/ 15 | iocr/ocr_ui/.idea/ 16 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/utils/UUIDUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils; 2 | 3 | import java.util.UUID; 4 | 5 | /** 6 | * 生成文件名 7 | * Generate file name 8 | * 9 | * @author Calvin 10 | * @mail 179209347@qq.com 11 | * @website www.aias.top 12 | */ 13 | public class UUIDUtils { 14 | 15 | public static String getUUID() { 16 | return UUID.randomUUID().toString().replace("-", ""); 17 | } 18 | 19 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/Point.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | /** 5 | * @author Calvin 6 | * @mail 179209347@qq.com 7 | * @website www.aias.top 8 | */ 9 | @Data 10 | public class Point { 11 | private int x; 12 | private int y; 13 | 14 | public Point() { 15 | } 16 | 17 | public Point(int x, int y) { 18 | this.x = x; 19 | this.y = y; 20 | } 21 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/TemplateBean.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | /** 7 | * 模板对象 8 | * 9 | * @author Calvin 10 | * @mail 179209347@qq.com 11 | * @website www.aias.top 12 | */ 13 | @Data 14 | public class TemplateBean { 15 | private String uid; 16 | private String name; 17 | private String imageName; 18 | List labelData; 19 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/main.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/utils/param2Obj.spec.js: -------------------------------------------------------------------------------- 1 | import { param2Obj } from '@/utils/index.js' 2 | describe('Utils:param2Obj', () => { 3 | const url = 'https://github.com/PanJiaChen/vue-element-admin?name=bill&age=29&sex=1&field=dGVzdA==&key=%E6%B5%8B%E8%AF%95' 4 | 5 | it('param2Obj test', () => { 6 | expect(param2Obj(url)).toEqual({ 7 | name: 'bill', 8 | age: '29', 9 | sex: '1', 10 | field: window.btoa('test'), 11 | key: '测试' 12 | }) 13 | }) 14 | }) 15 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/LabelBean.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.List; 6 | /** 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | @Data 12 | public class LabelBean { 13 | private int index; 14 | private int active; 15 | private String type; 16 | private String value; 17 | private String field; 18 | private List points; 19 | private ai.djl.modality.cv.output.Point centerPoint; 20 | } 21 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/ocr_ui.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/MainApplication.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | 6 | /** 7 | * 入口主程序 8 | * 9 | * @author Calvin 10 | * @mail 179209347@qq.com 11 | * @website www.aias.top 12 | */ 13 | @SpringBootApplication 14 | public class MainApplication { 15 | 16 | public static void main(String[] args) { 17 | SpringApplication.run(MainApplication.class, args); 18 | } 19 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/service/TableInferService.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.service; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.translate.TranslateException; 5 | 6 | import java.util.List; 7 | 8 | /** 9 | * 表格识别接口 10 | * 11 | * @author Calvin 12 | * @mail 179209347@qq.com 13 | * @website www.aias.top 14 | */ 15 | public interface TableInferService { 16 | String getTableHtml(Image image) throws TranslateException; 17 | List getTableHtmlList(Image image) throws TranslateException; 18 | } 19 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/test/test.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/utils/Constants.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils; 2 | 3 | /** 4 | * 配置常量 5 | * 6 | * @author Calvin 7 | * @mail 179209347@qq.com 8 | * @website www.aias.top 9 | */ 10 | public class Constants { 11 | /** 12 | * win systems 13 | */ 14 | public static final String WIN = "win"; 15 | 16 | /** 17 | * mac system 18 | */ 19 | public static final String MAC = "mac"; 20 | 21 | /** 22 | * mac system 23 | */ 24 | public static final String LINUX = "linux"; 25 | } 26 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/api/inference.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function generalInfoForImageUrl(data) { 4 | return request({ 5 | url: '/inference/generalInfoForImageUrl', 6 | method: 'get', 7 | params: { 8 | url: data.url 9 | } 10 | }) 11 | } 12 | 13 | export function mlsdForImageUrl(data) { 14 | return request({ 15 | url: '/inference/mlsdForImageUrl', 16 | method: 'get', 17 | params: { 18 | url: data.url 19 | } 20 | }) 21 | } 22 | 23 | export default { generalInfoForImageUrl, mlsdForImageUrl } 24 | 25 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/api/table.js: -------------------------------------------------------------------------------- 1 | import request from '@/utils/request' 2 | 3 | export function tableInfoForImageUrl(data) { 4 | return request({ 5 | url: '/table/tableInfoForImageUrl', 6 | method: 'get', 7 | params: { 8 | url: data.url 9 | } 10 | }) 11 | } 12 | 13 | export function autoTableInfoForImageUrl(data) { 14 | return request({ 15 | url: '/table/autoTableInfoForImageUrl', 16 | method: 'get', 17 | params: { 18 | url: data.url 19 | } 20 | }) 21 | } 22 | 23 | export default { tableInfoForImageUrl, autoTableInfoForImageUrl } 24 | 25 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_layout_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/service/InferService.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.service; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDManager; 5 | import ai.djl.translate.TranslateException; 6 | import top.aias.ocr.bean.RotatedBox; 7 | 8 | import java.util.List; 9 | 10 | /** 11 | * 文字识别接口 12 | * 13 | * @author Calvin 14 | * @mail 179209347@qq.com 15 | * @website www.aias.top 16 | */ 17 | public interface InferService { 18 | List getGeneralInfo(NDManager manager, Image image) throws TranslateException; 19 | Image getWarpImg(Image image) throws TranslateException; 20 | } 21 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/babel.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | presets: [ 3 | // https://github.com/vuejs/vue-cli/tree/master/packages/@vue/babel-preset-app 4 | '@vue/cli-plugin-babel/preset' 5 | ], 6 | 'env': { 7 | 'development': { 8 | // babel-plugin-dynamic-import-node plugin only does one thing by converting all import() to require(). 9 | // This plugin can significantly increase the speed of hot updates, when you have a large number of pages. 10 | // https://panjiachen.github.io/vue-element-admin-site/guide/advanced/lazy-loading.html 11 | 'plugins': ['dynamic-import-node'] 12 | } 13 | } 14 | } 15 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/TableResult.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import ai.djl.modality.cv.output.BoundingBox; 4 | import lombok.Data; 5 | 6 | import java.util.List; 7 | /** 8 | * 表格检测结果 9 | * 10 | * @author Calvin 11 | * @mail 179209347@qq.com 12 | * @website www.aias.top 13 | */ 14 | @Data 15 | public class TableResult { 16 | private List structure_str_list; 17 | private List boxes; 18 | 19 | public TableResult(List structure_str_list, List boxes) { 20 | this.structure_str_list = structure_str_list; 21 | this.boxes = boxes; 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | 2 | spring: 3 | profiles: 4 | active: win 5 | servlet: 6 | multipart: 7 | enabled: true 8 | max-file-size: 30MB 9 | max-request-size: 30MB 10 | http: 11 | encoding: 12 | charset: utf-8 13 | enabled: true 14 | force: true 15 | messages: 16 | encoding: UTF-8 17 | 18 | # Swagger-ui 19 | swagger: 20 | enabled: true 21 | 22 | # File path 23 | file: 24 | mac: 25 | path: file/ 26 | linux: 27 | path: file/ 28 | windows: 29 | path: D:\\ 30 | # File max size - MB 31 | maxSize: 100 32 | 33 | 34 | # Verify image transformation result 35 | image: 36 | debug: true 37 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | <%= webpackConfig.name %> 9 | 10 | 11 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/store/modules/settings.js: -------------------------------------------------------------------------------- 1 | import defaultSettings from '@/settings' 2 | 3 | const { showSettings, fixedHeader, sidebarLogo } = defaultSettings 4 | 5 | const state = { 6 | showSettings: showSettings, 7 | fixedHeader: fixedHeader, 8 | sidebarLogo: sidebarLogo 9 | } 10 | 11 | const mutations = { 12 | CHANGE_SETTING: (state, { key, value }) => { 13 | // eslint-disable-next-line no-prototype-builtins 14 | if (state.hasOwnProperty(key)) { 15 | state[key] = value 16 | } 17 | } 18 | } 19 | 20 | const actions = { 21 | changeSetting({ commit }, data) { 22 | commit('CHANGE_SETTING', data) 23 | } 24 | } 25 | 26 | export default { 27 | namespaced: true, 28 | state, 29 | mutations, 30 | actions 31 | } 32 | 33 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // sidebar 2 | $menuText:#bfcbd9; 3 | $menuActiveText:#409EFF; 4 | $subMenuActiveText:#f4f4f5; //https://github.com/ElemeFE/element/issues/12951 5 | 6 | $menuBg:#304156; 7 | $menuHover:#263445; 8 | 9 | $subMenuBg:#1f2d3d; 10 | $subMenuHover:#001528; 11 | 12 | $sideBarWidth: 210px; 13 | 14 | // the :export directive is the magic sauce for webpack 15 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 16 | :export { 17 | menuText: $menuText; 18 | menuActiveText: $menuActiveText; 19 | subMenuActiveText: $subMenuActiveText; 20 | menuBg: $menuBg; 21 | menuHover: $menuHover; 22 | subMenuBg: $subMenuBg; 23 | subMenuHover: $subMenuHover; 24 | sideBarWidth: $sideBarWidth; 25 | } 26 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/components/SvgIcon.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import SvgIcon from '@/components/SvgIcon/index.vue' 3 | describe('SvgIcon.vue', () => { 4 | it('iconClass', () => { 5 | const wrapper = shallowMount(SvgIcon, { 6 | propsData: { 7 | iconClass: 'test' 8 | } 9 | }) 10 | expect(wrapper.find('use').attributes().href).toBe('#icon-test') 11 | }) 12 | it('className', () => { 13 | const wrapper = shallowMount(SvgIcon, { 14 | propsData: { 15 | iconClass: 'test' 16 | } 17 | }) 18 | expect(wrapper.classes().length).toBe(1) 19 | wrapper.setProps({ className: 'test' }) 20 | expect(wrapper.classes().includes('test')).toBe(true) 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/components/Hamburger.spec.js: -------------------------------------------------------------------------------- 1 | import { shallowMount } from '@vue/test-utils' 2 | import Hamburger from '@/components/Hamburger/index.vue' 3 | describe('Hamburger.vue', () => { 4 | it('toggle click', () => { 5 | const wrapper = shallowMount(Hamburger) 6 | const mockFn = jest.fn() 7 | wrapper.vm.$on('toggleClick', mockFn) 8 | wrapper.find('.hamburger').trigger('click') 9 | expect(mockFn).toBeCalled() 10 | }) 11 | it('prop isActive', () => { 12 | const wrapper = shallowMount(Hamburger) 13 | wrapper.setProps({ isActive: true }) 14 | expect(wrapper.contains('.is-active')).toBe(true) 15 | wrapper.setProps({ isActive: false }) 16 | expect(wrapper.contains('.is-active')).toBe(false) 17 | }) 18 | }) 19 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/utils/common/DirectionInfo.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | /** 3 | * @author Calvin 4 | * @mail 179209347@qq.com 5 | * @website www.aias.top 6 | */ 7 | public class DirectionInfo { 8 | private String name; 9 | private Double prob; 10 | 11 | public DirectionInfo(String name, Double prob) { 12 | this.name = name; 13 | this.prob = prob; 14 | } 15 | 16 | public String getName() { 17 | return name; 18 | } 19 | 20 | public void setName(String name) { 21 | this.name = name; 22 | } 23 | 24 | public Double getProb() { 25 | return prob; 26 | } 27 | 28 | public void setProb(Double prob) { 29 | this.prob = prob; 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/compiler.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/main/java/top/aias/ocr/utils/common/DirectionInfo.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | /** 3 | * 文本方向 4 | * @author Calvin 5 | * @mail 179209347@qq.com 6 | * @website www.aias.top 7 | */ 8 | public class DirectionInfo { 9 | private String name; 10 | private Double prob; 11 | 12 | public DirectionInfo(String name, Double prob) { 13 | this.name = name; 14 | this.prob = prob; 15 | } 16 | 17 | public String getName() { 18 | return name; 19 | } 20 | 21 | public void setName(String name) { 22 | this.name = name; 23 | } 24 | 25 | public Double getProb() { 26 | return prob; 27 | } 28 | 29 | public void setProb(Double prob) { 30 | this.prob = prob; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/permission.js: -------------------------------------------------------------------------------- 1 | import router from './router' 2 | import NProgress from 'nprogress' // progress bar 3 | import 'nprogress/nprogress.css' // progress bar style 4 | import getPageTitle from '@/utils/get-page-title' 5 | 6 | NProgress.configure({ showSpinner: false }) // NProgress Configuration 7 | 8 | router.beforeEach(async(to, from, next) => { 9 | // start progress bar 10 | NProgress.start() 11 | 12 | // set page title 13 | document.title = getPageTitle(to.meta.title) 14 | 15 | if (to.path === '/login') { 16 | // if is logged in, redirect to the home page 17 | next({ path: '/' }) 18 | NProgress.done() 19 | } else { 20 | next() 21 | } 22 | }) 23 | 24 | router.afterEach(() => { 25 | // finish progress bar 26 | NProgress.done() 27 | }) 28 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Sidebar/FixiOSBug.js: -------------------------------------------------------------------------------- 1 | export default { 2 | computed: { 3 | device() { 4 | return this.$store.state.app.device 5 | } 6 | }, 7 | mounted() { 8 | // In order to fix the click on menu on the ios device will trigger the mouseleave bug 9 | // https://github.com/PanJiaChen/vue-element-admin/issues/1135 10 | this.fixBugIniOS() 11 | }, 12 | methods: { 13 | fixBugIniOS() { 14 | const $subMenu = this.$refs.subMenu 15 | if ($subMenu) { 16 | const handleMouseleave = $subMenu.handleMouseleave 17 | $subMenu.handleMouseleave = (e) => { 18 | if (this.device === 'mobile') { 19 | return 20 | } 21 | handleMouseleave(e) 22 | } 23 | } 24 | } 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/utils/validate.spec.js: -------------------------------------------------------------------------------- 1 | import { validUsername, isExternal } from '@/utils/validate.js' 2 | 3 | describe('Utils:validate', () => { 4 | it('validUsername', () => { 5 | expect(validUsername('admin')).toBe(true) 6 | expect(validUsername('editor')).toBe(true) 7 | expect(validUsername('xxxx')).toBe(false) 8 | }) 9 | it('isExternal', () => { 10 | expect(isExternal('https://github.com/PanJiaChen/vue-element-admin')).toBe(true) 11 | expect(isExternal('http://github.com/PanJiaChen/vue-element-admin')).toBe(true) 12 | expect(isExternal('github.com/PanJiaChen/vue-element-admin')).toBe(false) 13 | expect(isExternal('/dashboard')).toBe(false) 14 | expect(isExternal('./dashboard')).toBe(false) 15 | expect(isExternal('dashboard')).toBe(false) 16 | }) 17 | }) 18 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | 3 | import 'normalize.css/normalize.css' // A modern alternative to CSS resets 4 | 5 | import ElementUI from 'element-ui' 6 | import 'element-ui/lib/theme-chalk/index.css' 7 | import locale from 'element-ui/lib/locale/lang/en' // lang i18n 8 | 9 | import '@/styles/index.scss' // global css 10 | 11 | import App from './App' 12 | import store from './store' 13 | import router from './router' 14 | 15 | import '@/permission' // permission control 16 | 17 | // set ElementUI lang to EN 18 | Vue.use(ElementUI, { locale }) 19 | // 如果想要中文版 element-ui,按如下方式声明 20 | // To use the Chinese version of element-ui, declare as follows 21 | // Vue.use(ElementUI) 22 | 23 | Vue.config.productionTip = false 24 | 25 | new Vue({ 26 | el: '#app', 27 | router, 28 | store, 29 | render: h => h(App) 30 | }) 31 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/AppMain.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 19 | 20 | 32 | 33 | 41 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/application-linux.yml: -------------------------------------------------------------------------------- 1 | # Server Port 2 | server: 3 | port: 8089 4 | tomcat: 5 | uri-encoding: UTF-8 6 | baseUri: http://127.0.0.1:${server.port} 7 | 8 | model: 9 | # 设置为 CPU 核心数 (Core Number) 10 | poolSize: 4 11 | table: 12 | # 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 13 | layout: /home/models/ocr/picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip 14 | # 英文表格识别 15 | rec: /home/models/ocr/en_ppstructure_mobile_v2.0_SLANet_infer.zip 16 | # 中文表格识别 17 | # /home/models/ocr/ch_ppstructure_mobile_v2.0_SLANet_infer.zip 18 | ocrv4: 19 | # server detection model URI 20 | det: /home/models/ocr/ch_PP-OCRv4_det_infer.zip 21 | # server recognition model URI 22 | rec: /home/models/ocr/ch_PP-OCRv4_rec_infer.zip 23 | mlsd: 24 | # mlsd model URI 25 | model: /home/models/ocr/mlsd_traced_model_onnx.zip 26 | 27 | 28 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | moduleFileExtensions: ['js', 'jsx', 'json', 'vue'], 3 | transform: { 4 | '^.+\\.vue$': 'vue-jest', 5 | '.+\\.(css|styl|less|sass|scss|svg|png|jpg|ttf|woff|woff2)$': 6 | 'jest-transform-stub', 7 | '^.+\\.jsx?$': 'babel-jest' 8 | }, 9 | moduleNameMapper: { 10 | '^@/(.*)$': '/src/$1' 11 | }, 12 | snapshotSerializers: ['jest-serializer-vue'], 13 | testMatch: [ 14 | '**/tests/unit/**/*.spec.(js|jsx|ts|tsx)|**/__tests__/*.(js|jsx|ts|tsx)' 15 | ], 16 | collectCoverageFrom: ['src/utils/**/*.{js,vue}', '!src/utils/auth.js', '!src/utils/request.js', 'src/components/**/*.{js,vue}'], 17 | coverageDirectory: '/tests/unit/coverage', 18 | // 'collectCoverage': true, 19 | 'coverageReporters': [ 20 | 'lcov', 21 | 'text-summary' 22 | ], 23 | testURL: 'http://localhost/' 24 | } 25 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Sidebar/Link.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 44 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Sidebar/Item.vue: -------------------------------------------------------------------------------- 1 | 34 | 35 | 42 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/common/mixin/table-mixin.js: -------------------------------------------------------------------------------- 1 | export default { 2 | data () { 3 | return { 4 | tableInit: false, 5 | emptyTable: false, 6 | page: { 7 | pageNum: 1, 8 | pageSize: 8, 9 | total: 0, 10 | }, 11 | } 12 | }, 13 | mounted () { 14 | }, 15 | computed: { 16 | // emptyTable () { 17 | // return this.page.total === 0 && this.page.pageNum === 1 && this.emptyParam 18 | // }, 19 | }, 20 | watch: { 21 | 'page.total' () { 22 | if (this.page.total > 0) { 23 | this.emptyTable = false 24 | } 25 | }, 26 | }, 27 | methods: { 28 | isObjectEmpty (data = {}) { 29 | return Object.values(data).filter(a => !!a).length === 0 30 | }, 31 | setEmptyTable () { 32 | this.tableInit = true 33 | console.log(this.page.total, this.page.total == 0) 34 | this.emptyTable = this.page.total == 0 35 | }, 36 | clearPage () { 37 | this.page.pageNum = 1 38 | }, 39 | }, 40 | } 41 | -------------------------------------------------------------------------------- /ocr_led_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /ocr_v3_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /ocr_v4_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | // cover some element-ui styles 2 | 3 | .el-breadcrumb__inner, 4 | .el-breadcrumb__inner a { 5 | font-weight: 400 !important; 6 | } 7 | 8 | .el-upload { 9 | input[type="file"] { 10 | display: none !important; 11 | } 12 | } 13 | 14 | .el-upload__input { 15 | display: none; 16 | } 17 | 18 | 19 | // to fixed https://github.com/ElemeFE/element/issues/2461 20 | .el-dialog { 21 | transform: none; 22 | left: 0; 23 | position: relative; 24 | margin: 0 auto; 25 | } 26 | 27 | // refine element ui upload 28 | .upload-container { 29 | .el-upload { 30 | width: 100%; 31 | 32 | .el-upload-dragger { 33 | width: 100%; 34 | height: 200px; 35 | } 36 | } 37 | } 38 | 39 | // dropdown 40 | .el-dropdown-menu { 41 | a { 42 | display: block 43 | } 44 | } 45 | 46 | // to fix el-date-picker css style 47 | .el-range-separator { 48 | box-sizing: content-box; 49 | } 50 | -------------------------------------------------------------------------------- /ocr_table_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/variables.scss: -------------------------------------------------------------------------------- 1 | // base color 2 | $blue:#324157; 3 | $light-blue:#3A71A8; 4 | $red:#C03639; 5 | $pink: #E65D6E; 6 | $green: #30B08F; 7 | $tiffany: #4AB7BD; 8 | $yellow:#FEC171; 9 | $panGreen: #30B08F; 10 | 11 | // sidebar 12 | $menuText:#bfcbd9; 13 | $menuActiveText:#409EFF; 14 | $subMenuActiveText:#f4f4f5; // https://github.com/ElemeFE/element/issues/12951 15 | 16 | $menuBg:#304156; 17 | $menuHover:#263445; 18 | 19 | $subMenuBg:#1f2d3d; 20 | $subMenuHover:#001528; 21 | 22 | $sideBarWidth: 205px; 23 | 24 | // the :export directive is the magic sauce for webpack 25 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 26 | :export { 27 | menuText: $menuText; 28 | menuActiveText: $menuActiveText; 29 | subMenuActiveText: $subMenuActiveText; 30 | menuBg: $menuBg; 31 | menuHover: $menuHover; 32 | subMenuBg: $subMenuBg; 33 | subMenuHover: $subMenuHover; 34 | sideBarWidth: $sideBarWidth; 35 | } 36 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/transition.scss: -------------------------------------------------------------------------------- 1 | // global transition css 2 | 3 | /* fade */ 4 | .fade-enter-active, 5 | .fade-leave-active { 6 | transition: opacity 0.28s; 7 | } 8 | 9 | .fade-enter, 10 | .fade-leave-active { 11 | opacity: 0; 12 | } 13 | 14 | /* fade-transform */ 15 | .fade-transform-leave-active, 16 | .fade-transform-enter-active { 17 | transition: all .5s; 18 | } 19 | 20 | .fade-transform-enter { 21 | opacity: 0; 22 | transform: translateX(-30px); 23 | } 24 | 25 | .fade-transform-leave-to { 26 | opacity: 0; 27 | transform: translateX(30px); 28 | } 29 | 30 | /* breadcrumb transition */ 31 | .breadcrumb-enter-active, 32 | .breadcrumb-leave-active { 33 | transition: all .5s; 34 | } 35 | 36 | .breadcrumb-enter, 37 | .breadcrumb-leave-active { 38 | opacity: 0; 39 | transform: translateX(20px); 40 | } 41 | 42 | .breadcrumb-move { 43 | transition: all .5s; 44 | } 45 | 46 | .breadcrumb-leave-active { 47 | position: absolute; 48 | } 49 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/element-variables.scss: -------------------------------------------------------------------------------- 1 | /** 2 | * I think element-ui's default theme color is too light for long-term use. 3 | * So I modified the default color and you can modify it to your liking. 4 | **/ 5 | 6 | /* theme color */ 7 | $--color-primary: #1890ff; 8 | $--color-success: #13ce66; 9 | $--color-warning: #FFBA00; 10 | $--color-danger: #ff4949; 11 | // $--color-info: #1E1E1E; 12 | 13 | $--button-font-weight: 400; 14 | 15 | // $--color-text-regular: #1f2d3d; 16 | 17 | $--border-color-light: #dfe4ed; 18 | $--border-color-lighter: #e6ebf5; 19 | 20 | $--table-border:1px solid#dfe6ec; 21 | 22 | /* icon font path, required */ 23 | $--font-path: '~element-ui/lib/theme-chalk/fonts'; 24 | 25 | @import "../../../node_modules/element-ui/packages/theme-chalk/src/index"; 26 | 27 | // the :export directive is the magic sauce for webpack 28 | // https://www.bluematador.com/blog/how-to-share-variables-between-js-and-sass 29 | :export { 30 | theme: $--color-primary; 31 | } 32 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/application-mac.yml: -------------------------------------------------------------------------------- 1 | # Server Port 2 | server: 3 | port: 8089 4 | tomcat: 5 | uri-encoding: UTF-8 6 | baseUri: http://127.0.0.1:${server.port} 7 | 8 | model: 9 | # 设置为 CPU 核心数 (Core Number) 10 | poolSize: 4 11 | table: 12 | # 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 13 | layout: /Users/calvin/ocr/ocr_backend/models/picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip 14 | # 英文表格识别 15 | rec: /Users/calvin/ocr/ocr_backend/models/en_ppstructure_mobile_v2.0_SLANet_infer.zip 16 | # 中文表格识别 17 | # rec: /Users/calvin/ocr/ocr_backend/models/ch_ppstructure_mobile_v2.0_SLANet_infer.zip 18 | ocrv4: 19 | # server detection model URI 20 | det: /Users/calvin/ocr/ocr_backend/models/ch_PP-OCRv4_det_infer.zip 21 | # server recognition model URI 22 | rec: /Users/calvin/ocr/ocr_backend/models/ch_PP-OCRv4_rec_infer.zip 23 | mlsd: 24 | # mlsd model URI 25 | model: /Users/calvin/ocr/ocr_backend/models/mlsd_traced_model_onnx.zip 26 | 27 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/main/java/top/aias/ocr/utils/table/TableResult.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.table; 2 | 3 | import ai.djl.modality.cv.output.BoundingBox; 4 | 5 | import java.util.List; 6 | /** 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class TableResult { 12 | private List structure_str_list; 13 | private List boxes; 14 | 15 | public TableResult(List structure_str_list, List boxes) { 16 | this.structure_str_list = structure_str_list; 17 | this.boxes = boxes; 18 | } 19 | 20 | public List getStructure_str_list() { 21 | return structure_str_list; 22 | } 23 | 24 | public void setStructure_str_list(List structure_str_list) { 25 | this.structure_str_list = structure_str_list; 26 | } 27 | 28 | public List getBoxes() { 29 | return boxes; 30 | } 31 | 32 | public void setBoxes(List boxes) { 33 | this.boxes = boxes; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/build/index.js: -------------------------------------------------------------------------------- 1 | const { run } = require('runjs') 2 | const chalk = require('chalk') 3 | const config = require('../vue.config.js') 4 | const rawArgv = process.argv.slice(2) 5 | const args = rawArgv.join(' ') 6 | 7 | if (process.env.npm_config_preview || rawArgv.includes('--preview')) { 8 | const report = rawArgv.includes('--report') 9 | 10 | run(`vue-cli-service build ${args}`) 11 | 12 | const port = 9526 13 | const publicPath = config.publicPath 14 | 15 | var connect = require('connect') 16 | var serveStatic = require('serve-static') 17 | const app = connect() 18 | 19 | app.use( 20 | publicPath, 21 | serveStatic('./dist', { 22 | index: ['index.html', '/'] 23 | }) 24 | ) 25 | 26 | app.listen(port, function () { 27 | console.log(chalk.green(`> Preview at http://localhost:${port}${publicPath}`)) 28 | if (report) { 29 | console.log(chalk.green(`> Report at http://localhost:${port}${publicPath}report.html`)) 30 | } 31 | 32 | }) 33 | } else { 34 | run(`vue-cli-service build ${args}`) 35 | } 36 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/application-online.yml: -------------------------------------------------------------------------------- 1 | # Server Port 2 | server: 3 | port: 8089 4 | tomcat: 5 | uri-encoding: UTF-8 6 | baseUri: http://127.0.0.1:${server.port} 7 | 8 | model: 9 | # 设置为 CPU 核心数 (Core Number) 10 | poolSize: 4 11 | table: 12 | # 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 13 | layout: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip 14 | # 英文表格识别 15 | rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/en_ppstructure_mobile_v2.0_SLANet_infer.zip 16 | # 中文表格识别 17 | # rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/ch_ppstructure_mobile_v2.0_SLANet_infer.zip 18 | ocrv4: 19 | # server detection model URI 20 | det: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/ch_PP-OCRv4_det_infer.zip 21 | # server recognition model URI 22 | rec: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/ch_PP-OCRv4_rec_infer.zip 23 | mlsd: 24 | # mlsd model URI 25 | model: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr/mlsd_traced_model_onnx.zip 26 | 27 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/main/java/top/aias/ocr/utils/table/CrossRangeCellMeta.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.table; 2 | 3 | /** 4 | * @Auther: xiaoqiang 5 | * @Date: 2020/12/9 9:17 6 | * @Description: 7 | */ 8 | public class CrossRangeCellMeta { 9 | public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) { 10 | super(); 11 | this.firstRowIndex = firstRowIndex; 12 | this.firstColIndex = firstColIndex; 13 | this.rowSpan = rowSpan; 14 | this.colSpan = colSpan; 15 | } 16 | 17 | private int firstRowIndex; 18 | private int firstColIndex; 19 | private int rowSpan;// 跨越行数 20 | private int colSpan;// 跨越列数 21 | 22 | public int getFirstRow() { 23 | return firstRowIndex; 24 | } 25 | 26 | public int getLastRow() { 27 | return firstRowIndex + rowSpan - 1; 28 | } 29 | 30 | public int getFirstCol() { 31 | return firstColIndex; 32 | } 33 | 34 | public int getLastCol() { 35 | return firstColIndex + colSpan - 1; 36 | } 37 | 38 | public int getColSpan(){ 39 | return colSpan; 40 | } 41 | } 42 | 43 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/base.scss: -------------------------------------------------------------------------------- 1 | // flex row 2 | @mixin flex-row { 3 | display: flex; 4 | flex-direction: row; 5 | } 6 | @mixin flex-row-between { 7 | @include flex-row(); 8 | justify-content: space-between; 9 | } 10 | 11 | @mixin flex-row-between-center { 12 | @include flex-row-between(); 13 | align-items: center 14 | } 15 | 16 | @mixin flex-row-center { 17 | @include flex-row(); 18 | justify-content: center 19 | } 20 | 21 | @mixin flex-row-all-center { 22 | @include flex-row-center; 23 | align-items: center 24 | 25 | } 26 | 27 | @mixin all-height($height) { 28 | height: $height; 29 | line-height: $height 30 | } 31 | 32 | @mixin ellipsis($width) { 33 | width: $width; 34 | display: inline-block; 35 | overflow: hidden; 36 | white-space: nowrap; 37 | text-overflow: ellipsis 38 | } 39 | 40 | // flex column 41 | @mixin flex-column { 42 | display: flex; 43 | flex-direction: column 44 | } 45 | 46 | @mixin flex-column-center { 47 | @include flex-column(); 48 | justify-content: center 49 | } 50 | 51 | @mixin flex-column-all-center { 52 | @include flex-column-center; 53 | align-items: center 54 | } 55 | 56 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/CrossRangeCellMeta.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | /** 3 | * excel 单元 4 | * 5 | * @author Calvin 6 | * @mail 179209347@qq.com 7 | * @website www.aias.top 8 | */ 9 | public class CrossRangeCellMeta { 10 | public CrossRangeCellMeta(int firstRowIndex, int firstColIndex, int rowSpan, int colSpan) { 11 | super(); 12 | this.firstRowIndex = firstRowIndex; 13 | this.firstColIndex = firstColIndex; 14 | this.rowSpan = rowSpan; 15 | this.colSpan = colSpan; 16 | } 17 | 18 | private int firstRowIndex; 19 | private int firstColIndex; 20 | private int rowSpan;// 跨越行数 21 | private int colSpan;// 跨越列数 22 | 23 | public int getFirstRow() { 24 | return firstRowIndex; 25 | } 26 | 27 | public int getLastRow() { 28 | return firstRowIndex + rowSpan - 1; 29 | } 30 | 31 | public int getFirstCol() { 32 | return firstColIndex; 33 | } 34 | 35 | public int getLastCol() { 36 | return firstColIndex + colSpan - 1; 37 | } 38 | 39 | public int getColSpan(){ 40 | return colSpan; 41 | } 42 | } 43 | 44 | -------------------------------------------------------------------------------- /ocr_v4_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | ### 下载模型,放置于models目录 5 | - 链接:https://pan.baidu.com/s/1qO_tQrXyMIDcBnBxJKsQPw?pwd=5soi 6 | 7 | ## OCR文字识别 8 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 9 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 10 | OCR(文字识别)是目前常用的一种AI能力。 11 | 12 | 13 | #### 文字识别SDK (原生支持旋转倾斜文本, 如果需要,图像预处理SDK可以作为辅助) 14 | ##### 1. 文本检测 - OcrV4DetExample 15 | 16 | ![OcrV3DetExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3DetExample.jpeg) 17 | 18 | ##### 2. 文本识别 - OcrV4RecExample 19 | 20 | ![OcrV3RecExample1](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3RecExample1.jpeg) 21 | 22 | ![OcrV3RecExample2](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3RecExample2.jpeg) 23 | 24 | 25 | 26 | #### 帮助文档: 27 | - https://aias.top/guides.html 28 | - 1.性能优化常见问题: 29 | - https://aias.top/AIAS/guides/performance.html 30 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 31 | - https://aias.top/AIAS/guides/engine_config.html 32 | - 3.模型加载方式(在线自动加载,及本地配置): 33 | - https://aias.top/AIAS/guides/load_model.html 34 | - 4.Windows环境常见问题: 35 | - https://aias.top/AIAS/guides/windows.html 36 | 37 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/ResultBean.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | import java.util.HashMap; 7 | import java.util.Map; 8 | /** 9 | * 10 | * @author Calvin 11 | * @mail 179209347@qq.com 12 | * @website www.aias.top 13 | */ 14 | @Data 15 | public class ResultBean implements Serializable { 16 | private static final long serialVersionUID = 1L; 17 | private int code; 18 | private String value; 19 | private Map data = new HashMap(); 20 | 21 | public static ResultBean success() { 22 | ResultBean rb = new ResultBean(); 23 | rb.setCode(0); 24 | rb.setValue("Success"); 25 | return rb; 26 | } 27 | 28 | public static ResultBean failure() { 29 | ResultBean msg = new ResultBean(); 30 | msg.setCode(-1); 31 | msg.setValue("Failure"); 32 | return msg; 33 | } 34 | 35 | public ResultBean() { 36 | 37 | } 38 | 39 | public ResultBean add(String key, Object value) { 40 | this.getData().put(key, value); 41 | return this; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/resources/application-win.yml: -------------------------------------------------------------------------------- 1 | # Server Port 2 | server: 3 | port: 8089 4 | tomcat: 5 | uri-encoding: UTF-8 6 | baseUri: http://127.0.0.1:${server.port} 7 | 8 | model: 9 | # 设置为 CPU 核心数 (Core Number) 10 | poolSize: 4 11 | table: 12 | # 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 13 | layout: D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip 14 | # 英文表格识别 15 | rec: D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\en_ppstructure_mobile_v2.0_SLANet_infer.zip 16 | # 中文表格识别 17 | # D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\ch_ppstructure_mobile_v2.0_SLANet_infer.zip 18 | ocrv4: 19 | # server detection model URI 20 | det: D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\ch_PP-OCRv4_det_infer.zip 21 | # server recognition model URI 22 | rec: D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\ch_PP-OCRv4_rec_infer.zip 23 | mlsd: 24 | # mlsd model URI 25 | model: D:\\ai_projects\\AIAS\\6_web_app\\ocr_web_app\\ocr_backend\\models\\mlsd_traced_model_onnx.zip 26 | 27 | 28 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/utils/formatTime.spec.js: -------------------------------------------------------------------------------- 1 | import { formatTime } from '@/utils/index.js' 2 | 3 | describe('Utils:formatTime', () => { 4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 5 | const retrofit = 5 * 1000 6 | 7 | it('ten digits timestamp', () => { 8 | expect(formatTime((d / 1000).toFixed(0))).toBe('7月13日17时54分') 9 | }) 10 | it('test now', () => { 11 | expect(formatTime(+new Date() - 1)).toBe('刚刚') 12 | }) 13 | it('less two minute', () => { 14 | expect(formatTime(+new Date() - 60 * 2 * 1000 + retrofit)).toBe('2分钟前') 15 | }) 16 | it('less two hour', () => { 17 | expect(formatTime(+new Date() - 60 * 60 * 2 * 1000 + retrofit)).toBe('2小时前') 18 | }) 19 | it('less one day', () => { 20 | expect(formatTime(+new Date() - 60 * 60 * 24 * 1 * 1000)).toBe('1天前') 21 | }) 22 | it('more than one day', () => { 23 | expect(formatTime(d)).toBe('7月13日17时54分') 24 | }) 25 | it('format', () => { 26 | expect(formatTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 27 | expect(formatTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 28 | expect(formatTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 29 | }) 30 | }) 31 | -------------------------------------------------------------------------------- /ocr_layout_sdk/.idea/jarRepositories.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 9 | 10 | 14 | 15 | 19 | 20 | 24 | 25 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/configuration/FileProperties.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.configuration; 2 | 3 | import lombok.Data; 4 | import top.aias.ocr.utils.Constants; 5 | import org.springframework.boot.context.properties.ConfigurationProperties; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * 文件配置 10 | * 11 | * @author Calvin 12 | * @mail 179209347@qq.com 13 | * @website www.aias.top 14 | */ 15 | @Data 16 | @Configuration 17 | @ConfigurationProperties(prefix = "file") 18 | public class FileProperties { 19 | 20 | /** 21 | * File size limitation 22 | */ 23 | private Long maxSize; 24 | 25 | private ElPath mac; 26 | 27 | private ElPath linux; 28 | 29 | private ElPath windows; 30 | 31 | public ElPath getPath() { 32 | String os = System.getProperty("os.name"); 33 | if (os.toLowerCase().startsWith(Constants.WIN)) { 34 | return windows; 35 | } else if (os.toLowerCase().startsWith(Constants.MAC)) { 36 | return mac; 37 | } 38 | return linux; 39 | } 40 | 41 | @Data 42 | public static class ElPath { 43 | 44 | private String path; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/styles/index.scss: -------------------------------------------------------------------------------- 1 | @import './variables.scss'; 2 | @import './mixin.scss'; 3 | @import './transition.scss'; 4 | @import './element-ui.scss'; 5 | @import './sidebar.scss'; 6 | 7 | body { 8 | height: 100%; 9 | -moz-osx-font-smoothing: grayscale; 10 | -webkit-font-smoothing: antialiased; 11 | text-rendering: optimizeLegibility; 12 | font-family: Helvetica Neue, Helvetica, PingFang SC, Hiragino Sans GB, Microsoft YaHei, Arial, sans-serif; 13 | } 14 | 15 | label { 16 | font-weight: 700; 17 | } 18 | 19 | html { 20 | height: 100%; 21 | box-sizing: border-box; 22 | } 23 | 24 | #app { 25 | height: 100%; 26 | } 27 | 28 | *, 29 | *:before, 30 | *:after { 31 | box-sizing: inherit; 32 | } 33 | 34 | a:focus, 35 | a:active { 36 | outline: none; 37 | } 38 | 39 | a, 40 | a:focus, 41 | a:hover { 42 | cursor: pointer; 43 | color: inherit; 44 | text-decoration: none; 45 | } 46 | 47 | div:focus { 48 | outline: none; 49 | } 50 | 51 | .clearfix { 52 | &:after { 53 | visibility: hidden; 54 | display: block; 55 | font-size: 0; 56 | content: " "; 57 | clear: both; 58 | height: 0; 59 | } 60 | } 61 | 62 | // main-container global css 63 | .app-container { 64 | padding: 20px; 65 | } 66 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/utils/common/ImageInfo.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDArray; 5 | /** 6 | * 图像信息 7 | * 8 | * @author Calvin 9 | * @mail 179209347@qq.com 10 | * @website www.aias.top 11 | */ 12 | public class ImageInfo { 13 | private String name; 14 | private Double prob; 15 | private Image image; 16 | private NDArray box; 17 | 18 | public ImageInfo(Image image, NDArray box) { 19 | this.image = image; 20 | this.box = box; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public Double getProb() { 32 | return prob; 33 | } 34 | 35 | public void setProb(Double prob) { 36 | this.prob = prob; 37 | } 38 | 39 | public Image getImage() { 40 | return image; 41 | } 42 | 43 | public void setImage(Image image) { 44 | this.image = image; 45 | } 46 | 47 | public NDArray getBox() { 48 | return box; 49 | } 50 | 51 | public void setBox(NDArray box) { 52 | this.box = box; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/utils/common/ImageInfo.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDArray; 5 | /** 6 | * 图像信息 7 | * 8 | * @author Calvin 9 | * @mail 179209347@qq.com 10 | * @website www.aias.top 11 | */ 12 | public class ImageInfo { 13 | private String name; 14 | private Double prob; 15 | private Image image; 16 | private NDArray box; 17 | 18 | public ImageInfo(Image image, NDArray box) { 19 | this.image = image; 20 | this.box = box; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public Double getProb() { 32 | return prob; 33 | } 34 | 35 | public void setProb(Double prob) { 36 | this.prob = prob; 37 | } 38 | 39 | public Image getImage() { 40 | return image; 41 | } 42 | 43 | public void setImage(Image image) { 44 | this.image = image; 45 | } 46 | 47 | public NDArray getBox() { 48 | return box; 49 | } 50 | 51 | public void setBox(NDArray box) { 52 | this.box = box; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/utils/common/ImageInfo.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDArray; 5 | /** 6 | * 图像信息 7 | * 8 | * @author Calvin 9 | * @mail 179209347@qq.com 10 | * @website www.aias.top 11 | */ 12 | public class ImageInfo { 13 | private String name; 14 | private Double prob; 15 | private Image image; 16 | private NDArray box; 17 | 18 | public ImageInfo(Image image, NDArray box) { 19 | this.image = image; 20 | this.box = box; 21 | } 22 | 23 | public String getName() { 24 | return name; 25 | } 26 | 27 | public void setName(String name) { 28 | this.name = name; 29 | } 30 | 31 | public Double getProb() { 32 | return prob; 33 | } 34 | 35 | public void setProb(Double prob) { 36 | this.prob = prob; 37 | } 38 | 39 | public Image getImage() { 40 | return image; 41 | } 42 | 43 | public void setImage(Image image) { 44 | this.image = image; 45 | } 46 | 47 | public NDArray getBox() { 48 | return box; 49 | } 50 | 51 | public void setBox(NDArray box) { 52 | this.box = box; 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/bean/RotatedBox.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.bean; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBox implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBox(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 Y 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBox o) { 28 | NDArray lowBox = this.getBox(); 29 | NDArray highBox = o.getBox(); 30 | float lowY = lowBox.toFloatArray()[1]; 31 | float highY = highBox.toFloatArray()[1]; 32 | return (lowY < highY) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBox.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBox implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBox(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 Y 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBox o) { 28 | NDArray lowBox = this.getBox(); 29 | NDArray highBox = o.getBox(); 30 | float lowY = lowBox.toFloatArray()[1]; 31 | float highY = highBox.toFloatArray()[1]; 32 | return (lowY < highY) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBox.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBox implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBox(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 Y 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBox o) { 28 | NDArray lowBox = this.getBox(); 29 | NDArray highBox = o.getBox(); 30 | float lowY = lowBox.toFloatArray()[1]; 31 | float highY = highBox.toFloatArray()[1]; 32 | return (lowY < highY) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBox.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBox implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBox(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 Y 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBox o) { 28 | NDArray lowBox = this.getBox(); 29 | NDArray highBox = o.getBox(); 30 | float lowY = lowBox.toFloatArray()[1]; 31 | float highY = highBox.toFloatArray()[1]; 32 | return (lowY < highY) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/store/modules/app.js: -------------------------------------------------------------------------------- 1 | import Cookies from 'js-cookie' 2 | 3 | const state = { 4 | sidebar: { 5 | opened: Cookies.get('sidebarStatus') ? !!+Cookies.get('sidebarStatus') : true, 6 | withoutAnimation: false 7 | }, 8 | device: 'desktop' 9 | } 10 | 11 | const mutations = { 12 | TOGGLE_SIDEBAR: state => { 13 | state.sidebar.opened = !state.sidebar.opened 14 | state.sidebar.withoutAnimation = false 15 | if (state.sidebar.opened) { 16 | Cookies.set('sidebarStatus', 1) 17 | } else { 18 | Cookies.set('sidebarStatus', 0) 19 | } 20 | }, 21 | CLOSE_SIDEBAR: (state, withoutAnimation) => { 22 | Cookies.set('sidebarStatus', 0) 23 | state.sidebar.opened = false 24 | state.sidebar.withoutAnimation = withoutAnimation 25 | }, 26 | TOGGLE_DEVICE: (state, device) => { 27 | state.device = device 28 | } 29 | } 30 | 31 | const actions = { 32 | toggleSideBar({ commit }) { 33 | commit('TOGGLE_SIDEBAR') 34 | }, 35 | closeSideBar({ commit }, { withoutAnimation }) { 36 | commit('CLOSE_SIDEBAR', withoutAnimation) 37 | }, 38 | toggleDevice({ commit }, device) { 39 | commit('TOGGLE_DEVICE', device) 40 | } 41 | } 42 | 43 | export default { 44 | namespaced: true, 45 | state, 46 | mutations, 47 | actions 48 | } 49 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBoxCompX.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 - 支持左上角 X 坐标升序排序 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBoxCompX implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBoxCompX(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 X 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBoxCompX o) { 28 | NDArray leftBox = this.getBox(); 29 | NDArray rightBox = o.getBox(); 30 | float leftX = leftBox.toFloatArray()[0]; 31 | float rightX = rightBox.toFloatArray()[0]; 32 | return (leftX < rightX) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBoxCompX.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 - 支持左上角 X 坐标升序排序 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBoxCompX implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBoxCompX(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 X 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBoxCompX o) { 28 | NDArray leftBox = this.getBox(); 29 | NDArray rightBox = o.getBox(); 30 | float leftX = leftBox.toFloatArray()[0]; 31 | float rightX = rightBox.toFloatArray()[0]; 32 | return (leftX < rightX) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBoxCompX.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | /** 5 | * 旋转检测框 - 支持左上角 X 坐标升序排序 6 | * 7 | * @author Calvin 8 | * @mail 179209347@qq.com 9 | * @website www.aias.top 10 | */ 11 | public class RotatedBoxCompX implements Comparable { 12 | private NDArray box; 13 | private String text; 14 | 15 | public RotatedBoxCompX(NDArray box, String text) { 16 | this.box = box; 17 | this.text = text; 18 | } 19 | 20 | /** 21 | * 将左上角 X 坐标升序排序 22 | * 23 | * @param o 24 | * @return 25 | */ 26 | @Override 27 | public int compareTo(RotatedBoxCompX o) { 28 | NDArray leftBox = this.getBox(); 29 | NDArray rightBox = o.getBox(); 30 | float leftX = leftBox.toFloatArray()[0]; 31 | float rightX = rightBox.toFloatArray()[0]; 32 | return (leftX < rightX) ? -1 : 1; 33 | } 34 | 35 | public NDArray getBox() { 36 | return box; 37 | } 38 | 39 | public void setBox(NDArray box) { 40 | this.box = box; 41 | } 42 | 43 | public String getText() { 44 | return text; 45 | } 46 | 47 | public void setText(String text) { 48 | this.text = text; 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/tests/unit/utils/parseTime.spec.js: -------------------------------------------------------------------------------- 1 | import { parseTime } from '@/utils/index.js' 2 | 3 | describe('Utils:parseTime', () => { 4 | const d = new Date('2018-07-13 17:54:01') // "2018-07-13 17:54:01" 5 | it('timestamp', () => { 6 | expect(parseTime(d)).toBe('2018-07-13 17:54:01') 7 | }) 8 | it('timestamp string', () => { 9 | expect(parseTime((d + ''))).toBe('2018-07-13 17:54:01') 10 | }) 11 | it('ten digits timestamp', () => { 12 | expect(parseTime((d / 1000).toFixed(0))).toBe('2018-07-13 17:54:01') 13 | }) 14 | it('new Date', () => { 15 | expect(parseTime(new Date(d))).toBe('2018-07-13 17:54:01') 16 | }) 17 | it('format', () => { 18 | expect(parseTime(d, '{y}-{m}-{d} {h}:{i}')).toBe('2018-07-13 17:54') 19 | expect(parseTime(d, '{y}-{m}-{d}')).toBe('2018-07-13') 20 | expect(parseTime(d, '{y}/{m}/{d} {h}-{i}')).toBe('2018/07/13 17-54') 21 | }) 22 | it('get the day of the week', () => { 23 | expect(parseTime(d, '{a}')).toBe('五') // 星期五 24 | }) 25 | it('get the day of the week', () => { 26 | expect(parseTime(+d + 1000 * 60 * 60 * 24 * 2, '{a}')).toBe('日') // 星期日 27 | }) 28 | it('empty argument', () => { 29 | expect(parseTime()).toBeNull() 30 | }) 31 | 32 | it('null', () => { 33 | expect(parseTime(null)).toBeNull() 34 | }) 35 | }) 36 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/RotationExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.modality.cv.ImageFactory; 5 | import ai.djl.modality.cv.util.NDImageUtils; 6 | import ai.djl.ndarray.NDArray; 7 | import ai.djl.ndarray.NDManager; 8 | import ai.djl.opencv.OpenCVImageFactory; 9 | import top.aias.ocr.utils.common.ImageUtils; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | 13 | import java.io.IOException; 14 | import java.nio.file.Path; 15 | import java.nio.file.Paths; 16 | 17 | /** 18 | * 图片旋转 19 | * Rotation Example 20 | * 21 | * @author Calvin 22 | * @email 179209347@qq.com 23 | * @website www.aias.top 24 | */ 25 | public final class RotationExample { 26 | 27 | private static final Logger logger = LoggerFactory.getLogger(RotationExample.class); 28 | 29 | private RotationExample() { 30 | } 31 | 32 | public static void main(String[] args) throws IOException { 33 | Path imageFile = Paths.get("src/test/resources/ticket_0.png"); 34 | Image image = ImageFactory.getInstance().fromFile(imageFile); 35 | // 逆时针旋转 36 | // Counterclockwise rotation 37 | image = ImageUtils.rotateImg(image,1); 38 | 39 | ImageUtils.saveImage(image, "rotated_result.png", "build/output"); 40 | } 41 | 42 | } 43 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/components/Hamburger/index.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 32 | 33 | 45 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/element-ui.scss: -------------------------------------------------------------------------------- 1 | // cover some element-ui styles 2 | 3 | .el-breadcrumb__inner, 4 | .el-breadcrumb__inner a { 5 | font-weight: 400 !important; 6 | } 7 | 8 | .el-upload { 9 | input[type="file"] { 10 | display: none !important; 11 | } 12 | } 13 | 14 | .el-upload__input { 15 | display: none; 16 | } 17 | 18 | .cell { 19 | .el-tag { 20 | margin-right: 0; 21 | } 22 | } 23 | 24 | .small-padding { 25 | .cell { 26 | padding-left: 5px; 27 | padding-right: 5px; 28 | } 29 | } 30 | 31 | .fixed-width { 32 | .el-button--mini { 33 | padding: 7px 10px; 34 | width: 60px; 35 | } 36 | } 37 | 38 | .status-col { 39 | .cell { 40 | padding: 0 10px; 41 | text-align: center; 42 | 43 | .el-tag { 44 | margin-right: 0; 45 | } 46 | } 47 | } 48 | 49 | // to fixed https://github.com/ElemeFE/element/issues/2461 50 | .el-dialog { 51 | transform: none; 52 | left: 0; 53 | position: relative; 54 | margin: 0 auto; 55 | } 56 | 57 | // refine element ui upload 58 | .upload-container { 59 | .el-upload { 60 | width: 100%; 61 | 62 | .el-upload-dragger { 63 | width: 100%; 64 | height: 200px; 65 | } 66 | } 67 | } 68 | 69 | // dropdown 70 | .el-dropdown-menu { 71 | a { 72 | display: block 73 | } 74 | } 75 | 76 | // fix date-picker ui bug in filter-item 77 | .el-range-editor.el-input__inner { 78 | display: inline-flex !important; 79 | } 80 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/mixin/ResizeHandler.js: -------------------------------------------------------------------------------- 1 | import store from '@/store' 2 | 3 | const { body } = document 4 | const WIDTH = 992 // refer to Bootstrap's responsive design 5 | 6 | export default { 7 | watch: { 8 | $route(route) { 9 | if (this.device === 'mobile' && this.sidebar.opened) { 10 | store.dispatch('app/closeSideBar', { withoutAnimation: false }) 11 | } 12 | } 13 | }, 14 | beforeMount() { 15 | window.addEventListener('resize', this.$_resizeHandler) 16 | }, 17 | beforeDestroy() { 18 | window.removeEventListener('resize', this.$_resizeHandler) 19 | }, 20 | mounted() { 21 | const isMobile = this.$_isMobile() 22 | if (isMobile) { 23 | store.dispatch('app/toggleDevice', 'mobile') 24 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 25 | } 26 | }, 27 | methods: { 28 | // use $_ for mixins properties 29 | // https://vuejs.org/v2/style-guide/index.html#Private-property-names-essential 30 | $_isMobile() { 31 | const rect = body.getBoundingClientRect() 32 | return rect.width - 1 < WIDTH 33 | }, 34 | $_resizeHandler() { 35 | if (!document.hidden) { 36 | const isMobile = this.$_isMobile() 37 | store.dispatch('app/toggleDevice', isMobile ? 'mobile' : 'desktop') 38 | 39 | if (isMobile) { 40 | store.dispatch('app/closeSideBar', { withoutAnimation: true }) 41 | } 42 | } 43 | } 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/utils/detection/OcrV4Detection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.detection; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDList; 5 | import ai.djl.repository.zoo.Criteria; 6 | import ai.djl.training.util.ProgressBar; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.nio.file.Paths; 12 | /** 13 | * 文字检测 14 | * 15 | * @author Calvin 16 | * @mail 179209347@qq.com 17 | * @website www.aias.top 18 | */ 19 | public final class OcrV4Detection { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(OcrV4Detection.class); 22 | 23 | public OcrV4Detection() { 24 | } 25 | 26 | /** 27 | * 中文文本检测 28 | * @return 29 | */ 30 | public Criteria chDetCriteria() { 31 | Criteria criteria = 32 | Criteria.builder() 33 | .optEngine("OnnxRuntime") 34 | // .optModelName("inference") 35 | .setTypes(Image.class, NDList.class) 36 | .optModelPath(Paths.get("models/ch_PP-OCRv4_det_infer.onnx")) 37 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 38 | .optProgress(new ProgressBar()) 39 | .build(); 40 | 41 | return criteria; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/utils/detection/OcrV4Detection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.detection; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDList; 5 | import ai.djl.repository.zoo.Criteria; 6 | import ai.djl.training.util.ProgressBar; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.nio.file.Paths; 12 | /** 13 | * 文字检测 14 | * 15 | * @author Calvin 16 | * @mail 179209347@qq.com 17 | * @website www.aias.top 18 | */ 19 | public final class OcrV4Detection { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(OcrV4Detection.class); 22 | 23 | public OcrV4Detection() { 24 | } 25 | 26 | /** 27 | * 中文文本检测 28 | * @return 29 | */ 30 | public Criteria chDetCriteria() { 31 | Criteria criteria = 32 | Criteria.builder() 33 | .optEngine("OnnxRuntime") 34 | // .optModelName("inference") 35 | .setTypes(Image.class, NDList.class) 36 | .optModelPath(Paths.get("models/ch_PP-OCRv4_det_infer/inference.onnx")) 37 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 38 | .optProgress(new ProgressBar()) 39 | .build(); 40 | 41 | return criteria; 42 | } 43 | 44 | } 45 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/service/impl/InferServiceImpl.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.service.impl; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDManager; 5 | import ai.djl.translate.TranslateException; 6 | import top.aias.ocr.bean.RotatedBox; 7 | import top.aias.ocr.model.MlsdSquareModel; 8 | import top.aias.ocr.model.RecognitionModel; 9 | import top.aias.ocr.service.InferService; 10 | import org.slf4j.Logger; 11 | import org.slf4j.LoggerFactory; 12 | import org.springframework.beans.factory.annotation.Autowired; 13 | import org.springframework.stereotype.Service; 14 | 15 | import java.util.List; 16 | 17 | /** 18 | * 文字识别服务 19 | * 20 | * @author Calvin 21 | * @mail 179209347@qq.com 22 | * @website www.aias.top 23 | */ 24 | @Service 25 | public class InferServiceImpl implements InferService { 26 | private Logger logger = LoggerFactory.getLogger(InferServiceImpl.class); 27 | 28 | @Autowired 29 | private RecognitionModel recognitionModel; 30 | 31 | @Autowired 32 | private MlsdSquareModel mlsdSquareModel; 33 | 34 | public List getGeneralInfo(NDManager manager, Image image) throws TranslateException { 35 | List detectedObjects = recognitionModel.predict(manager, image); 36 | return detectedObjects; 37 | } 38 | 39 | public Image getWarpImg(Image image) throws TranslateException { 40 | Image cropImg = mlsdSquareModel.predict(image); 41 | return cropImg; 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/utils/common/RotatedBox.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.common; 2 | 3 | import ai.djl.ndarray.NDArray; 4 | 5 | /** 6 | * 旋转检测框 7 | * 8 | * @author Calvin 9 | * @mail 179209347@qq.com 10 | * @website www.aias.top 11 | */ 12 | public class RotatedBox implements Comparable { 13 | private NDArray box; 14 | private String text; 15 | private double prob; 16 | 17 | public RotatedBox(NDArray box, String text, double prob) { 18 | this.box = box; 19 | this.text = text; 20 | this.prob = prob; 21 | } 22 | 23 | /** 24 | * 将左上角 Y 坐标升序排序 25 | * 26 | * @param o 27 | * @return 28 | */ 29 | @Override 30 | public int compareTo(RotatedBox o) { 31 | NDArray lowBox = this.getBox(); 32 | NDArray highBox = o.getBox(); 33 | float lowY = lowBox.toFloatArray()[1]; 34 | float highY = highBox.toFloatArray()[1]; 35 | return (lowY < highY) ? -1 : 1; 36 | } 37 | 38 | public NDArray getBox() { 39 | return box; 40 | } 41 | 42 | public void setBox(NDArray box) { 43 | this.box = box; 44 | } 45 | 46 | public String getText() { 47 | return text; 48 | } 49 | 50 | public void setText(String text) { 51 | this.text = text; 52 | } 53 | 54 | public double getProb() { 55 | return prob; 56 | } 57 | 58 | public void setProb(double prob) { 59 | this.prob = prob; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | #### 下载模型,放置于models目录 5 | - 链接:https://pan.baidu.com/s/1DOlDnpxf8XUvTGfFrCWdmQ?pwd=gdin 6 | 7 | ## 文字识别(OCR)工具箱 8 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 9 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 10 | OCR(文字识别)是目前常用的一种AI能力。 11 | 12 | #### 图像方向检测与旋转SDK 13 | 14 | ##### 1. 方向检测 - DirectionDetExample 15 | 模型本身支持 0 度,和 180 度两种方向分类。 16 | 但是由于中文的书写习惯,根据宽高比可以判断文本的90度和270度两个方向。 17 | - 0度 18 | - 90度 19 | - 180度 20 | - 270度 21 | ![OcrDirectionExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrDirectionExample.jpeg) 22 | 23 | ##### 2. 方向旋转 - RotationExample 24 | - 逆时针旋转 25 | - 每次旋转90度的倍数 26 | ![RotationExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/RotationExample.jpeg) 27 | 28 | 29 | 30 | ### 开源算法 31 | #### 1. sdk使用的开源算法 32 | - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 33 | 34 | #### 2. 模型如何导出 ? 35 | (readme.md 里提供了推理模型的下载链接) 36 | - [export_model](https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.5/tools/export_model.py) 37 | - [how_to_create_paddlepaddle_model](http://docs.djl.ai/docs/paddlepaddle/how_to_create_paddlepaddle_model_zh.html) 38 | 39 | 40 | 41 | #### 帮助文档: 42 | - https://aias.top/guides.html 43 | - 1.性能优化常见问题: 44 | - https://aias.top/AIAS/guides/performance.html 45 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 46 | - https://aias.top/AIAS/guides/engine_config.html 47 | - 3.模型加载方式(在线自动加载,及本地配置): 48 | - https://aias.top/AIAS/guides/load_model.html 49 | - 4.Windows环境常见问题: 50 | - https://aias.top/AIAS/guides/windows.html -------------------------------------------------------------------------------- /ocr_led_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | #### 下载模型,放置于models目录 5 | - 链接:https://pan.baidu.com/s/1kNlsZBvfZtX-VsdXLFI_8A?pwd=w0fo 6 | 7 | 8 | ## 文字识别(OCR)工具箱 9 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 10 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 11 | OCR(文字识别)是目前常用的一种AI能力。 12 | 13 | ### OCR工具箱功能: 14 | #### led 文字识别SDK 15 | ##### 1. 文本检测 - OcrV3DetExample 16 | 17 | ![OcrV3DetExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/led_det_result.png) 18 | 19 | ##### 2. 文本识别 - OcrV3RecExample 20 | 21 | 22 | ![OcrV3RecExample1](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/led_rec_result.png) 23 | 24 | 25 | 26 | 27 | 28 | ### 开源算法 29 | #### 1. sdk使用的开源算法 30 | - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 31 | - https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.6/applications/%E6%B6%B2%E6%99%B6%E5%B1%8F%E8%AF%BB%E6%95%B0%E8%AF%86%E5%88%AB.md 32 | 33 | #### 2. 模型如何导出 ? 34 | (readme.md 里提供了推理模型的下载链接) 35 | - [export_model](https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.5/tools/export_model.py) 36 | - [how_to_create_paddlepaddle_model](http://docs.djl.ai/docs/paddlepaddle/how_to_create_paddlepaddle_model_zh.html) 37 | 38 | 39 | 40 | #### 帮助文档: 41 | - https://aias.top/guides.html 42 | - 1.性能优化常见问题: 43 | - https://aias.top/AIAS/guides/performance.html 44 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 45 | - https://aias.top/AIAS/guides/engine_config.html 46 | - 3.模型加载方式(在线自动加载,及本地配置): 47 | - https://aias.top/AIAS/guides/load_model.html 48 | - 4.Windows环境常见问题: 49 | - https://aias.top/AIAS/guides/windows.html 50 | 51 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/components/SvgIcon/index.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 47 | 48 | 63 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/mixin.scss: -------------------------------------------------------------------------------- 1 | @mixin clearfix { 2 | &:after { 3 | content: ""; 4 | display: table; 5 | clear: both; 6 | } 7 | } 8 | 9 | @mixin scrollBar { 10 | &::-webkit-scrollbar-track-piece { 11 | background: #d3dce6; 12 | } 13 | 14 | &::-webkit-scrollbar { 15 | width: 6px; 16 | } 17 | 18 | &::-webkit-scrollbar-thumb { 19 | background: #99a9bf; 20 | border-radius: 20px; 21 | } 22 | } 23 | 24 | @mixin relative { 25 | position: relative; 26 | width: 100%; 27 | height: 100%; 28 | } 29 | 30 | @mixin pct($pct) { 31 | width: #{$pct}; 32 | position: relative; 33 | margin: 0 auto; 34 | } 35 | 36 | @mixin triangle($width, $height, $color, $direction) { 37 | $width: $width/2; 38 | $color-border-style: $height solid $color; 39 | $transparent-border-style: $width solid transparent; 40 | height: 0; 41 | width: 0; 42 | 43 | @if $direction==up { 44 | border-bottom: $color-border-style; 45 | border-left: $transparent-border-style; 46 | border-right: $transparent-border-style; 47 | } 48 | 49 | @else if $direction==right { 50 | border-left: $color-border-style; 51 | border-top: $transparent-border-style; 52 | border-bottom: $transparent-border-style; 53 | } 54 | 55 | @else if $direction==down { 56 | border-top: $color-border-style; 57 | border-left: $transparent-border-style; 58 | border-right: $transparent-border-style; 59 | } 60 | 61 | @else if $direction==left { 62 | border-right: $color-border-style; 63 | border-top: $transparent-border-style; 64 | border-bottom: $transparent-border-style; 65 | } 66 | } 67 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/MlsdPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.repository.zoo.ZooModel; 6 | 7 | import java.util.ArrayList; 8 | /** 9 | * 文本转正连接池 10 | * 11 | * @author Calvin 12 | * @mail 179209347@qq.com 13 | * @website www.aias.top 14 | */ 15 | public class MlsdPool { 16 | private int poolSize; 17 | private ZooModel model; 18 | private ArrayList> predictorList = new ArrayList<>(); 19 | 20 | 21 | public MlsdPool(int poolSize, ZooModel model) { 22 | this.poolSize = poolSize; 23 | this.model = model; 24 | 25 | for (int i = 0; i < poolSize; i++) { 26 | Predictor predictor = model.newPredictor(); 27 | predictorList.add(predictor); 28 | } 29 | } 30 | 31 | public synchronized Predictor getPredictor() { 32 | while (predictorList.isEmpty()) { 33 | try { 34 | wait(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | Predictor predictor = predictorList.remove(0); 40 | return predictor; 41 | } 42 | 43 | public synchronized void releasePredictor(Predictor predictor) { 44 | predictorList.add(predictor); 45 | notifyAll(); 46 | } 47 | 48 | public void close() { 49 | for (Predictor predictor : predictorList) { 50 | predictor.close(); 51 | } 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Sidebar/index.vue: -------------------------------------------------------------------------------- 1 | 20 | 21 | 57 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/DetectorPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.ndarray.NDList; 6 | import ai.djl.repository.zoo.ZooModel; 7 | 8 | import java.util.ArrayList; 9 | /** 10 | * 文字检测连接池 11 | * 12 | * @author Calvin 13 | * @mail 179209347@qq.com 14 | * @website www.aias.top 15 | */ 16 | public class DetectorPool { 17 | private int poolSize; 18 | private ZooModel detectionModel; 19 | private ArrayList> detectorList = new ArrayList<>(); 20 | 21 | 22 | public DetectorPool(int poolSize, ZooModel detectionModel) { 23 | this.poolSize = poolSize; 24 | this.detectionModel = detectionModel; 25 | 26 | for (int i = 0; i < poolSize; i++) { 27 | Predictor detector = detectionModel.newPredictor(); 28 | detectorList.add(detector); 29 | } 30 | } 31 | 32 | public synchronized Predictor getDetector() { 33 | while (detectorList.isEmpty()) { 34 | try { 35 | wait(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | Predictor detector = detectorList.remove(0); 41 | return detector; 42 | } 43 | 44 | public synchronized void releaseDetector(Predictor detector) { 45 | detectorList.add(detector); 46 | notifyAll(); 47 | } 48 | 49 | public void close() { 50 | for (Predictor detector : detectorList) { 51 | detector.close(); 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/RecognizerPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.repository.zoo.ZooModel; 6 | 7 | import java.util.ArrayList; 8 | /** 9 | * 文字识别连接池 10 | * 11 | * @author Calvin 12 | * @mail 179209347@qq.com 13 | * @website www.aias.top 14 | */ 15 | public class RecognizerPool { 16 | private int poolSize; 17 | private ZooModel recognitionModel; 18 | private ArrayList> recognizerList = new ArrayList<>(); 19 | 20 | 21 | public RecognizerPool(int poolSize, ZooModel detectionModel) { 22 | this.poolSize = poolSize; 23 | this.recognitionModel = detectionModel; 24 | 25 | for (int i = 0; i < poolSize; i++) { 26 | Predictor detector = detectionModel.newPredictor(); 27 | recognizerList.add(detector); 28 | } 29 | } 30 | 31 | public synchronized Predictor getRecognizer(){ 32 | while (recognizerList.isEmpty()) { 33 | try { 34 | wait(); 35 | } catch (InterruptedException e) { 36 | e.printStackTrace(); 37 | } 38 | } 39 | Predictor recognizer = recognizerList.remove(0); 40 | return recognizer; 41 | } 42 | 43 | public synchronized void releaseRecognizer(Predictor recognizer) { 44 | recognizerList.add(recognizer); 45 | notifyAll(); 46 | } 47 | 48 | public void close() { 49 | for (Predictor detector : recognizerList) { 50 | detector.close(); 51 | } 52 | 53 | } 54 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/TableRecPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.repository.zoo.ZooModel; 6 | import top.aias.ocr.bean.TableResult; 7 | 8 | import java.util.ArrayList; 9 | /** 10 | * 表格识别连接池 11 | * 12 | * @author Calvin 13 | * @mail 179209347@qq.com 14 | * @website www.aias.top 15 | */ 16 | public class TableRecPool { 17 | private int poolSize; 18 | private ZooModel model; 19 | private ArrayList> predictorList = new ArrayList<>(); 20 | 21 | 22 | public TableRecPool(int poolSize, ZooModel model) { 23 | this.poolSize = poolSize; 24 | this.model = model; 25 | 26 | for (int i = 0; i < poolSize; i++) { 27 | Predictor predictor = model.newPredictor(); 28 | predictorList.add(predictor); 29 | } 30 | } 31 | 32 | public synchronized Predictor getPredictor() { 33 | while (predictorList.isEmpty()) { 34 | try { 35 | wait(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | Predictor predictor = predictorList.remove(0); 41 | return predictor; 42 | } 43 | 44 | public synchronized void releasePredictor(Predictor predictor) { 45 | predictorList.add(predictor); 46 | notifyAll(); 47 | } 48 | 49 | public void close() { 50 | for (Predictor predictor : predictorList) { 51 | predictor.close(); 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /ocr_layout_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | #### 下载模型,放置于models目录 5 | - 链接:https://pan.baidu.com/s/1aUOhMUQpvNb5VvcnIhLlVQ?pwd=2hqi 6 | 7 | 8 | ## 文字识别(OCR)工具箱 9 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 10 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 11 | OCR(文字识别)是目前常用的一种AI能力。 12 | 13 | ### OCR工具箱功能: 14 | #### 版面分析 - ocr_layout_sdk 15 | 可以用于配合文字识别,表格识别的流水线处理使用。 16 | ##### 1. 中文版面分析 - LayoutCNDetExample 17 | 中文版面分析模型,可以划分为表格、图片、图片标题、表格、表格标题、页眉、脚本、引用、公式10类区域: 18 | - text 19 | - title 20 | - figure 21 | - figure_caption 22 | - table 23 | - table_caption 24 | - header 25 | - footer 26 | - reference 27 | - equation 28 | ![LayoutCNDetExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/LayoutCNDetExample.jpeg) 29 | 30 | ##### 2. 英文版面分析 - LayoutENDetExample 31 | 英文版面分析模型,可以划分文字、标题、表格、图片以及列表5类区域: 32 | - text 33 | - title 34 | - list 35 | - table 36 | - figure 37 | - 运行成功后,命令行应该看到下面的信息: 38 | 39 | ![LayoutENDetExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/LayoutENDetExample.jpeg) 40 | 41 | 42 | ### 开源算法 43 | #### 1. sdk使用的开源算法 44 | - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 45 | 46 | #### 2. 模型如何导出 ? 47 | (readme.md 里提供了推理模型的下载链接) 48 | - [export_model](https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.5/tools/export_model.py) 49 | - [how_to_create_paddlepaddle_model](http://docs.djl.ai/docs/paddlepaddle/how_to_create_paddlepaddle_model_zh.html) 50 | 51 | 52 | 53 | #### 帮助文档: 54 | - https://aias.top/guides.html 55 | - 1.性能优化常见问题: 56 | - https://aias.top/AIAS/guides/performance.html 57 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 58 | - https://aias.top/AIAS/guides/engine_config.html 59 | - 3.模型加载方式(在线自动加载,及本地配置): 60 | - https://aias.top/AIAS/guides/load_model.html 61 | - 4.Windows环境常见问题: 62 | - https://aias.top/AIAS/guides/windows.html -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/LayoutPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.modality.cv.output.DetectedObjects; 6 | import ai.djl.repository.zoo.ZooModel; 7 | 8 | import java.util.ArrayList; 9 | /** 10 | * 布局检测连接池 11 | * 12 | * @author Calvin 13 | * @mail 179209347@qq.com 14 | * @website www.aias.top 15 | */ 16 | public class LayoutPool { 17 | private int poolSize; 18 | private ZooModel model; 19 | private ArrayList> predictorList = new ArrayList<>(); 20 | 21 | 22 | public LayoutPool(int poolSize, ZooModel model) { 23 | this.poolSize = poolSize; 24 | this.model = model; 25 | 26 | for (int i = 0; i < poolSize; i++) { 27 | Predictor predictor = model.newPredictor(); 28 | predictorList.add(predictor); 29 | } 30 | } 31 | 32 | public synchronized Predictor getPredictor() { 33 | while (predictorList.isEmpty()) { 34 | try { 35 | wait(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | Predictor predictor = predictorList.remove(0); 41 | return predictor; 42 | } 43 | 44 | public synchronized void releasePredictor(Predictor predictor) { 45 | predictorList.add(predictor); 46 | notifyAll(); 47 | } 48 | 49 | public void close() { 50 | for (Predictor predictor : predictorList) { 51 | predictor.close(); 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /ocr_table_sdk/build/output/table.html: -------------------------------------------------------------------------------- 1 |
速度距离时间速度距离时间速度距离时间速度距离时间
844493'29"853312190339.42'37146431"
26815,7331”39417.22'38"652'15″83115108
3072.813313983730135”74037.23'02"
117564316841443'09”1455642’38”73560456”
55433.73'39”321'42″21410.63'11"84747316″
300122'27”70352'10″291'32”95168416″
72353455314'52”165050149"14885”
10523'57"2142'44"119128124”1024452'35"
1284663'05″6480”895402′40”1600481'48″
421253′34”1400441'53"52013130″148626104″
-------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/nginx.conf: -------------------------------------------------------------------------------- 1 | user www-data; 2 | worker_processes auto; 3 | pid /run/nginx.pid; 4 | include /etc/nginx/modules-enabled/*.conf; 5 | 6 | events { 7 | worker_connections 768; 8 | # multi_accept on; 9 | } 10 | 11 | http { 12 | 13 | ## 14 | # Basic Settings 15 | ## 16 | 17 | sendfile on; 18 | tcp_nopush on; 19 | tcp_nodelay on; 20 | keepalive_timeout 65; 21 | types_hash_max_size 2048; 22 | # server_tokens off; 23 | 24 | # server_names_hash_bucket_size 64; 25 | # server_name_in_redirect off; 26 | 27 | include /etc/nginx/mime.types; 28 | default_type application/octet-stream; 29 | 30 | ## 31 | # SSL Settings 32 | ## 33 | 34 | ssl_protocols TLSv1 TLSv1.1 TLSv1.2; # Dropping SSLv3, ref: POODLE 35 | ssl_prefer_server_ciphers on; 36 | 37 | ## 38 | # Logging Settings 39 | ## 40 | 41 | access_log /var/log/nginx/access.log; 42 | error_log /var/log/nginx/error.log; 43 | 44 | ## 45 | # Gzip Settings 46 | ## 47 | 48 | gzip on; 49 | 50 | # gzip_vary on; 51 | # gzip_proxied any; 52 | # gzip_comp_level 6; 53 | # gzip_buffers 16 8k; 54 | # gzip_http_version 1.1; 55 | # gzip_types text/plain text/css application/json application/javascript text/xml application/xml application/xml+rss text/javascript; 56 | 57 | ## 58 | # Virtual Host Configs 59 | ## 60 | 61 | include /etc/nginx/conf.d/*.conf; 62 | include /etc/nginx/sites-enabled/*; 63 | } 64 | 65 | 66 | #mail { 67 | # # See sample authentication script at: 68 | # # http://wiki.nginx.org/ImapAuthenticateWithApachePhpScript 69 | # 70 | # # auth_http localhost/auth.php; 71 | # # pop3_capabilities "TOP" "USER"; 72 | # # imap_capabilities "IMAP4rev1" "UIDPLUS"; 73 | # 74 | # server { 75 | # listen localhost:110; 76 | # protocol pop3; 77 | # proxy on; 78 | # } 79 | # 80 | # server { 81 | # listen localhost:143; 82 | # protocol imap; 83 | # proxy on; 84 | # } 85 | #} 86 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/pool/HorizontalDetectorPool.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model.pool;// 导入需要的包 2 | 3 | import ai.djl.inference.Predictor; 4 | import ai.djl.modality.cv.Image; 5 | import ai.djl.modality.cv.output.DetectedObjects; 6 | import ai.djl.repository.zoo.ZooModel; 7 | 8 | import java.util.ArrayList; 9 | /** 10 | * 水平文字检测连接池 11 | * 12 | * @author Calvin 13 | * @mail 179209347@qq.com 14 | * @website www.aias.top 15 | */ 16 | public class HorizontalDetectorPool { 17 | private int poolSize; 18 | private ZooModel detectionModel; 19 | private ArrayList> detectorList = new ArrayList<>(); 20 | 21 | 22 | public HorizontalDetectorPool(int poolSize, ZooModel detectionModel) { 23 | this.poolSize = poolSize; 24 | this.detectionModel = detectionModel; 25 | 26 | for (int i = 0; i < poolSize; i++) { 27 | Predictor detector = detectionModel.newPredictor(); 28 | detectorList.add(detector); 29 | } 30 | } 31 | 32 | public synchronized Predictor getDetector(){ 33 | while (detectorList.isEmpty()) { 34 | try { 35 | wait(); 36 | } catch (InterruptedException e) { 37 | e.printStackTrace(); 38 | } 39 | } 40 | Predictor detector = detectorList.remove(0); 41 | return detector; 42 | } 43 | 44 | public synchronized void releaseDetector(Predictor detector) { 45 | detectorList.add(detector); 46 | notifyAll(); 47 | } 48 | 49 | public void close() { 50 | for (Predictor detector : detectorList) { 51 | detector.close(); 52 | } 53 | 54 | } 55 | } -------------------------------------------------------------------------------- /ocr_v3_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | #### 下载模型,放置于models目录 5 | - 链接:https://pan.baidu.com/s/1GSdLe3jxPzzn-5GzUfze9A?pwd=2g6f 6 | 7 | 8 | ## 文字识别(OCR)工具箱 9 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 10 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 11 | OCR(文字识别)是目前常用的一种AI能力。 12 | 13 | ### OCR工具箱功能: 14 | #### 文字识别SDK (原生支持旋转倾斜文本, 如果需要,图像预处理SDK可以作为辅助) 15 | ##### 1. 文本检测 - OcrV3DetExample 16 | - 中文文本检测 17 | - 英文文本检测 18 | - 多语言文本检测 19 | ![OcrV3DetExample](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3DetExample.jpeg) 20 | 21 | ##### 2. 文本识别 - OcrV3RecExample 22 | 支持的语言模型: 23 | - 中文简体 24 | - 中文繁体 25 | - 英文 26 | - 韩语 27 | - 日语 28 | - 阿拉伯 29 | - 梵文 30 | - 泰米尔语 31 | - 泰卢固语 32 | - 卡纳达文 33 | - 斯拉夫 34 | 35 | ![OcrV3RecExample1](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3RecExample1.jpeg) 36 | 37 | ![OcrV3RecExample2](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/OcrV3RecExample2.jpeg) 38 | 39 | 40 | ##### 3. 多线程文本识别 - OcrV3MultiThreadRecExample 41 | CPU:2.3 GHz 四核 Intel Core i5 42 | 同样图片单线程运行时间:1172 ms 43 | 多线程运行时间:707 ms 44 | 图片检测框较多时,多线程可以显著提升识别速度。 45 | 46 | 47 | ### 开源算法 48 | #### 1. sdk使用的开源算法 49 | - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 50 | 51 | #### 2. 模型如何导出 ? 52 | (readme.md 里提供了推理模型的下载链接) 53 | - [export_model](https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.5/tools/export_model.py) 54 | - [how_to_create_paddlepaddle_model](http://docs.djl.ai/docs/paddlepaddle/how_to_create_paddlepaddle_model_zh.html) 55 | 56 | 57 | 58 | #### 帮助文档: 59 | - https://aias.top/guides.html 60 | - 1.性能优化常见问题: 61 | - https://aias.top/AIAS/guides/performance.html 62 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 63 | - https://aias.top/AIAS/guides/engine_config.html 64 | - 3.模型加载方式(在线自动加载,及本地配置): 65 | - https://aias.top/AIAS/guides/load_model.html 66 | - 4.Windows环境常见问题: 67 | - https://aias.top/AIAS/guides/windows.html 68 | 69 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/btn.scss: -------------------------------------------------------------------------------- 1 | @import 'variables'; 2 | 3 | @mixin colorBtn($color) { 4 | background: $color; 5 | 6 | &:hover { 7 | color: $color; 8 | 9 | &:before, 10 | &:after { 11 | background: $color; 12 | } 13 | } 14 | } 15 | 16 | .blue-btn { 17 | @include colorBtn($blue) 18 | } 19 | 20 | .light-blue-btn { 21 | @include colorBtn($light-blue) 22 | } 23 | 24 | .red-btn { 25 | @include colorBtn($red) 26 | } 27 | 28 | .pink-btn { 29 | @include colorBtn($pink) 30 | } 31 | 32 | .green-btn { 33 | @include colorBtn($green) 34 | } 35 | 36 | .tiffany-btn { 37 | @include colorBtn($tiffany) 38 | } 39 | 40 | .yellow-btn { 41 | @include colorBtn($yellow) 42 | } 43 | 44 | .pan-btn { 45 | font-size: 14px; 46 | color: #fff; 47 | padding: 14px 36px; 48 | border-radius: 8px; 49 | border: none; 50 | outline: none; 51 | transition: 600ms ease all; 52 | position: relative; 53 | display: inline-block; 54 | 55 | &:hover { 56 | background: #fff; 57 | 58 | &:before, 59 | &:after { 60 | width: 100%; 61 | transition: 600ms ease all; 62 | } 63 | } 64 | 65 | &:before, 66 | &:after { 67 | content: ''; 68 | position: absolute; 69 | top: 0; 70 | right: 0; 71 | height: 2px; 72 | width: 0; 73 | transition: 400ms ease all; 74 | } 75 | 76 | &::after { 77 | right: inherit; 78 | top: inherit; 79 | left: 0; 80 | bottom: 0; 81 | } 82 | } 83 | 84 | .custom-button { 85 | display: inline-block; 86 | line-height: 1; 87 | white-space: nowrap; 88 | cursor: pointer; 89 | background: #fff; 90 | color: #fff; 91 | -webkit-appearance: none; 92 | text-align: center; 93 | box-sizing: border-box; 94 | outline: 0; 95 | margin: 0; 96 | padding: 10px 15px; 97 | font-size: 14px; 98 | border-radius: 4px; 99 | } 100 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/utils/opencv/OpenCVUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.opencv; 2 | 3 | import org.opencv.core.CvType; 4 | import org.opencv.core.Mat; 5 | import org.opencv.imgproc.Imgproc; 6 | 7 | import java.awt.image.BufferedImage; 8 | import java.awt.image.DataBufferByte; 9 | 10 | /** 11 | * OpenCV Utils 12 | * 13 | * @author Calvin 14 | * @mail 179209347@qq.com 15 | * @website www.aias.top 16 | */ 17 | public class OpenCVUtils { 18 | 19 | /** 20 | * 透视变换 21 | * 22 | * @param src 23 | * @param srcPoints 24 | * @param dstPoints 25 | * @return 26 | */ 27 | public static Mat perspectiveTransform(Mat src, Mat srcPoints, Mat dstPoints) { 28 | Mat dst = src.clone(); 29 | Mat warp_mat = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); 30 | Imgproc.warpPerspective(src, dst, warp_mat, dst.size()); 31 | warp_mat.release(); 32 | 33 | return dst; 34 | } 35 | 36 | /** 37 | * Mat to BufferedImage 38 | * 39 | * @param mat 40 | * @return 41 | */ 42 | public static BufferedImage mat2Image(Mat mat) { 43 | int width = mat.width(); 44 | int height = mat.height(); 45 | byte[] data = new byte[width * height * (int) mat.elemSize()]; 46 | Imgproc.cvtColor(mat, mat, 4); 47 | mat.get(0, 0, data); 48 | BufferedImage ret = new BufferedImage(width, height, 5); 49 | ret.getRaster().setDataElements(0, 0, width, height, data); 50 | return ret; 51 | } 52 | 53 | /** 54 | * BufferedImage to Mat 55 | * 56 | * @param img 57 | * @return 58 | */ 59 | public static Mat image2Mat(BufferedImage img) { 60 | int width = img.getWidth(); 61 | int height = img.getHeight(); 62 | byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 63 | Mat mat = new Mat(height, width, CvType.CV_8UC3); 64 | mat.put(0, 0, data); 65 | return mat; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/utils/opencv/OpenCVUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.opencv; 2 | 3 | import org.opencv.core.CvType; 4 | import org.opencv.core.Mat; 5 | import org.opencv.imgproc.Imgproc; 6 | 7 | import java.awt.image.BufferedImage; 8 | import java.awt.image.DataBufferByte; 9 | 10 | /** 11 | * OpenCV Utils 12 | * 13 | * @author Calvin 14 | * @mail 179209347@qq.com 15 | * @website www.aias.top 16 | */ 17 | public class OpenCVUtils { 18 | 19 | /** 20 | * 透视变换 21 | * 22 | * @param src 23 | * @param srcPoints 24 | * @param dstPoints 25 | * @return 26 | */ 27 | public static Mat perspectiveTransform(Mat src, Mat srcPoints, Mat dstPoints) { 28 | Mat dst = src.clone(); 29 | Mat warp_mat = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); 30 | Imgproc.warpPerspective(src, dst, warp_mat, dst.size()); 31 | warp_mat.release(); 32 | 33 | return dst; 34 | } 35 | 36 | /** 37 | * Mat to BufferedImage 38 | * 39 | * @param mat 40 | * @return 41 | */ 42 | public static BufferedImage mat2Image(Mat mat) { 43 | int width = mat.width(); 44 | int height = mat.height(); 45 | byte[] data = new byte[width * height * (int) mat.elemSize()]; 46 | Imgproc.cvtColor(mat, mat, 4); 47 | mat.get(0, 0, data); 48 | BufferedImage ret = new BufferedImage(width, height, 5); 49 | ret.getRaster().setDataElements(0, 0, width, height, data); 50 | return ret; 51 | } 52 | 53 | /** 54 | * BufferedImage to Mat 55 | * 56 | * @param img 57 | * @return 58 | */ 59 | public static Mat image2Mat(BufferedImage img) { 60 | int width = img.getWidth(); 61 | int height = img.getHeight(); 62 | byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 63 | Mat mat = new Mat(height, width, CvType.CV_8UC3); 64 | mat.put(0, 0, data); 65 | return mat; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/utils/opencv/OpenCVUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.opencv; 2 | 3 | import org.opencv.core.CvType; 4 | import org.opencv.core.Mat; 5 | import org.opencv.imgproc.Imgproc; 6 | 7 | import java.awt.image.BufferedImage; 8 | import java.awt.image.DataBufferByte; 9 | 10 | /** 11 | * OpenCV Utils 12 | * 13 | * @author Calvin 14 | * @mail 179209347@qq.com 15 | * @website www.aias.top 16 | */ 17 | public class OpenCVUtils { 18 | 19 | /** 20 | * 透视变换 21 | * 22 | * @param src 23 | * @param srcPoints 24 | * @param dstPoints 25 | * @return 26 | */ 27 | public static Mat perspectiveTransform(Mat src, Mat srcPoints, Mat dstPoints) { 28 | Mat dst = src.clone(); 29 | Mat warp_mat = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); 30 | Imgproc.warpPerspective(src, dst, warp_mat, dst.size()); 31 | warp_mat.release(); 32 | 33 | return dst; 34 | } 35 | 36 | /** 37 | * Mat to BufferedImage 38 | * 39 | * @param mat 40 | * @return 41 | */ 42 | public static BufferedImage mat2Image(Mat mat) { 43 | int width = mat.width(); 44 | int height = mat.height(); 45 | byte[] data = new byte[width * height * (int) mat.elemSize()]; 46 | Imgproc.cvtColor(mat, mat, 4); 47 | mat.get(0, 0, data); 48 | BufferedImage ret = new BufferedImage(width, height, 5); 49 | ret.getRaster().setDataElements(0, 0, width, height, data); 50 | return ret; 51 | } 52 | 53 | /** 54 | * BufferedImage to Mat 55 | * 56 | * @param img 57 | * @return 58 | */ 59 | public static Mat image2Mat(BufferedImage img) { 60 | int width = img.getWidth(); 61 | int height = img.getHeight(); 62 | byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 63 | Mat mat = new Mat(height, width, CvType.CV_8UC3); 64 | mat.put(0, 0, data); 65 | return mat; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/utils/opencv/OpenCVUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.opencv; 2 | 3 | import org.opencv.core.CvType; 4 | import org.opencv.core.Mat; 5 | import org.opencv.imgproc.Imgproc; 6 | 7 | import java.awt.image.BufferedImage; 8 | import java.awt.image.DataBufferByte; 9 | 10 | /** 11 | * OpenCV Utils 12 | * 13 | * @author Calvin 14 | * @mail 179209347@qq.com 15 | * @website www.aias.top 16 | */ 17 | public class OpenCVUtils { 18 | 19 | /** 20 | * 透视变换 21 | * 22 | * @param src 23 | * @param srcPoints 24 | * @param dstPoints 25 | * @return 26 | */ 27 | public static Mat perspectiveTransform(Mat src, Mat srcPoints, Mat dstPoints) { 28 | Mat dst = src.clone(); 29 | Mat warp_mat = Imgproc.getPerspectiveTransform(srcPoints, dstPoints); 30 | Imgproc.warpPerspective(src, dst, warp_mat, dst.size()); 31 | warp_mat.release(); 32 | 33 | return dst; 34 | } 35 | 36 | /** 37 | * Mat to BufferedImage 38 | * 39 | * @param mat 40 | * @return 41 | */ 42 | public static BufferedImage mat2Image(Mat mat) { 43 | int width = mat.width(); 44 | int height = mat.height(); 45 | byte[] data = new byte[width * height * (int) mat.elemSize()]; 46 | Imgproc.cvtColor(mat, mat, 4); 47 | mat.get(0, 0, data); 48 | BufferedImage ret = new BufferedImage(width, height, 5); 49 | ret.getRaster().setDataElements(0, 0, width, height, data); 50 | return ret; 51 | } 52 | 53 | /** 54 | * BufferedImage to Mat 55 | * 56 | * @param img 57 | * @return 58 | */ 59 | public static Mat image2Mat(BufferedImage img) { 60 | int width = img.getWidth(); 61 | int height = img.getHeight(); 62 | byte[] data = ((DataBufferByte) img.getRaster().getDataBuffer()).getData(); 63 | Mat mat = new Mat(height, width, CvType.CV_8UC3); 64 | mat.put(0, 0, data); 65 | return mat; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /ocr_layout_sdk/src/main/java/top/aias/ocr/TableDetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.modality.cv.ImageFactory; 7 | import ai.djl.modality.cv.output.DetectedObjects; 8 | import ai.djl.repository.zoo.ModelZoo; 9 | import ai.djl.repository.zoo.ZooModel; 10 | import ai.djl.translate.TranslateException; 11 | import top.aias.ocr.utils.common.ImageUtils; 12 | import top.aias.ocr.utils.layout.LayoutDetection; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.io.IOException; 17 | import java.nio.file.Path; 18 | import java.nio.file.Paths; 19 | import java.util.List; 20 | 21 | /** 22 | * 中英文表格检测. 23 | * Table Detection 24 | * 25 | * @author Calvin 26 | * @mail 179209347@qq.com 27 | * @website www.aias.top 28 | */ 29 | public final class TableDetExample { 30 | 31 | private static final Logger logger = LoggerFactory.getLogger(TableDetExample.class); 32 | 33 | private TableDetExample() {} 34 | 35 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 36 | Path imageFile = Paths.get("src/test/resources/3.png"); 37 | Image image = ImageFactory.getInstance().fromFile(imageFile); 38 | 39 | LayoutDetection detection = new LayoutDetection(); 40 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.tableCriteria()); 41 | Predictor detector = detectionModel.newPredictor()) { 42 | 43 | DetectedObjects detections = detector.predict(image); 44 | 45 | List boxes = detections.items(); 46 | for (DetectedObjects.DetectedObject result : boxes) { 47 | System.out.println(result.getClassName() + " : " + result.getProbability()); 48 | } 49 | 50 | ImageUtils.saveBoundingBoxImage( 51 | image, detections, "table_detect_result.png", "build/output"); 52 | logger.info("{}", detections); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ocr_layout_sdk/src/main/java/top/aias/ocr/LayoutCNDetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.modality.cv.ImageFactory; 7 | import ai.djl.modality.cv.output.DetectedObjects; 8 | import ai.djl.repository.zoo.ModelZoo; 9 | import ai.djl.repository.zoo.ZooModel; 10 | import ai.djl.translate.TranslateException; 11 | import top.aias.ocr.utils.common.ImageUtils; 12 | import top.aias.ocr.utils.layout.LayoutDetection; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.io.IOException; 17 | import java.nio.file.Path; 18 | import java.nio.file.Paths; 19 | import java.util.List; 20 | 21 | /** 22 | * 中文布局检测. 23 | * Layout Detection 24 | * 25 | * @author Calvin 26 | * @mail 179209347@qq.com 27 | * @website www.aias.top 28 | */ 29 | public final class LayoutCNDetExample { 30 | 31 | private static final Logger logger = LoggerFactory.getLogger(LayoutCNDetExample.class); 32 | 33 | private LayoutCNDetExample() {} 34 | 35 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 36 | Path imageFile = Paths.get("src/test/resources/2.png"); 37 | Image image = ImageFactory.getInstance().fromFile(imageFile); 38 | 39 | LayoutDetection detection = new LayoutDetection(); 40 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.cnCriteria()); 41 | Predictor detector = detectionModel.newPredictor()) { 42 | 43 | DetectedObjects detections = detector.predict(image); 44 | 45 | List boxes = detections.items(); 46 | for (DetectedObjects.DetectedObject result : boxes) { 47 | System.out.println(result.getClassName() + " : " + result.getProbability()); 48 | } 49 | 50 | ImageUtils.saveBoundingBoxImage( 51 | image, detections, "cn_layout_detect_result.png", "build/output"); 52 | logger.info("{}", detections); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ocr_layout_sdk/src/main/java/top/aias/ocr/LayoutENDetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.modality.cv.ImageFactory; 7 | import ai.djl.modality.cv.output.DetectedObjects; 8 | import ai.djl.repository.zoo.ModelZoo; 9 | import ai.djl.repository.zoo.ZooModel; 10 | import ai.djl.translate.TranslateException; 11 | import top.aias.ocr.utils.common.ImageUtils; 12 | import top.aias.ocr.utils.layout.LayoutDetection; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.io.IOException; 17 | import java.nio.file.Path; 18 | import java.nio.file.Paths; 19 | import java.util.List; 20 | 21 | /** 22 | * 英文布局检测. 23 | * Layout Detection 24 | * 25 | * @author Calvin 26 | * @mail 179209347@qq.com 27 | * @website www.aias.top 28 | */ 29 | public final class LayoutENDetExample { 30 | 31 | private static final Logger logger = LoggerFactory.getLogger(LayoutENDetExample.class); 32 | 33 | private LayoutENDetExample() {} 34 | 35 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 36 | Path imageFile = Paths.get("src/test/resources/1.png"); 37 | Image image = ImageFactory.getInstance().fromFile(imageFile); 38 | 39 | LayoutDetection detection = new LayoutDetection(); 40 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.enCriteria()); 41 | Predictor detector = detectionModel.newPredictor()) { 42 | 43 | DetectedObjects detections = detector.predict(image); 44 | 45 | List boxes = detections.items(); 46 | for (DetectedObjects.DetectedObject result : boxes) { 47 | System.out.println(result.getClassName() + " : " + result.getProbability()); 48 | } 49 | 50 | ImageUtils.saveBoundingBoxImage( 51 | image, detections, "en_layout_detect_result.png", "build/output"); 52 | logger.info("{}", detections); 53 | } 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/.idea/codeStyles/Project.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 19 | 20 | 21 | 24 | 25 | 26 | 39 | 40 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "ocr-ui", 3 | "version": "1.0.0", 4 | "description": "OCR UI", 5 | "author": "Calvin <179209347@qq.com>", 6 | "scripts": { 7 | "dev": "vue-cli-service serve", 8 | "build:prod": "vue-cli-service build", 9 | "build:stage": "vue-cli-service build --mode staging", 10 | "preview": "node build/index.js --preview", 11 | "lint": "eslint --ext .js,.vue src", 12 | "test:unit": "jest --clearCache && vue-cli-service test:unit", 13 | "test:ci": "npm run lint && npm run test:unit" 14 | }, 15 | "dependencies": { 16 | "axios": "0.18.1", 17 | "core-js": "3.6.5", 18 | "easy-circular-progress": "1.0.4", 19 | "echarts": "^4.2.1", 20 | "element-ui": "2.13.2", 21 | "js-base64": "^2.6.4", 22 | "js-cookie": "2.2.0", 23 | "normalize.css": "7.0.0", 24 | "nprogress": "0.2.0", 25 | "path-to-regexp": "2.4.0", 26 | "vertx3-eventbus-client": "^3.9.4", 27 | "vue": "2.6.10", 28 | "vue-count-to": "^1.0.13", 29 | "vue-json-viewer": "^2.2.18", 30 | "vue-router": "3.0.6", 31 | "vuex": "3.1.0" 32 | }, 33 | "devDependencies": { 34 | "@vue/cli-plugin-babel": "4.4.4", 35 | "@vue/cli-plugin-eslint": "4.4.4", 36 | "@vue/cli-plugin-unit-jest": "4.4.4", 37 | "@vue/cli-service": "4.4.4", 38 | "@vue/test-utils": "1.0.0-beta.29", 39 | "autoprefixer": "9.5.1", 40 | "babel-eslint": "10.1.0", 41 | "babel-jest": "23.6.0", 42 | "babel-plugin-dynamic-import-node": "2.3.3", 43 | "chalk": "2.4.2", 44 | "connect": "3.6.6", 45 | "eslint": "6.7.2", 46 | "eslint-plugin-vue": "6.2.2", 47 | "html-webpack-plugin": "3.2.0", 48 | "mockjs": "1.0.1-beta3", 49 | "runjs": "4.3.2", 50 | "sass": "1.26.8", 51 | "sass-loader": "8.0.2", 52 | "script-ext-html-webpack-plugin": "2.1.3", 53 | "serve-static": "1.13.2", 54 | "vue-template-compiler": "2.6.10" 55 | }, 56 | "browserslist": [ 57 | "> 1%", 58 | "last 2 versions" 59 | ], 60 | "engines": { 61 | "node": ">=8.9", 62 | "npm": ">= 3.0.0" 63 | }, 64 | "license": "apache2.0" 65 | } 66 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Sidebar/Logo.vue: -------------------------------------------------------------------------------- 1 | 15 | 16 | 33 | 34 | 83 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/DirectionDetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.Device; 4 | import ai.djl.ModelException; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.modality.cv.ImageFactory; 7 | import ai.djl.modality.cv.output.DetectedObjects; 8 | import ai.djl.opencv.OpenCVImageFactory; 9 | import ai.djl.translate.TranslateException; 10 | import org.opencv.core.Mat; 11 | import top.aias.ocr.utils.cls.OcrDirectionDetection; 12 | import top.aias.ocr.utils.common.ImageUtils; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | import top.aias.ocr.utils.common.RotatedBox; 16 | 17 | import java.io.IOException; 18 | import java.nio.file.Path; 19 | import java.nio.file.Paths; 20 | import java.util.List; 21 | 22 | /** 23 | * OCR文字方向检测(轻量级模型). 24 | * 25 | * OCR text direction detection (light model) 26 | * 27 | * @author Calvin 28 | * @email 179209347@qq.com 29 | * @website www.aias.top 30 | */ 31 | public final class DirectionDetExample { 32 | 33 | private static final Logger logger = LoggerFactory.getLogger(DirectionDetExample.class); 34 | 35 | private DirectionDetExample() {} 36 | 37 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 38 | Path imageFile = Paths.get("src/test/resources/ticket_90.png"); 39 | Image image = OpenCVImageFactory.getInstance().fromFile(imageFile); 40 | 41 | 42 | try (OcrDirectionDetection detection = new OcrDirectionDetection(Device.cpu());) { 43 | 44 | long start = System.currentTimeMillis(); 45 | List detections = detection.predict(image); 46 | 47 | for (RotatedBox result : detections) { 48 | System.out.println(result.getText() + " : " + result.getProb()); 49 | } 50 | 51 | long end = System.currentTimeMillis(); 52 | System.out.println("Time: " + (end - start)); 53 | 54 | for (RotatedBox result : detections) { 55 | ImageUtils.drawRectWithText((Mat) image.getWrappedImage(), result.getBox(), result.getText()); 56 | } 57 | ImageUtils.saveImage(image, "cls_detect_result.png", "build/output"); 58 | } 59 | } 60 | } -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/utils/detection/OcrV3Detection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.detection; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDList; 5 | import ai.djl.repository.zoo.Criteria; 6 | import ai.djl.training.util.ProgressBar; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.nio.file.Paths; 12 | /** 13 | * 文字检测 14 | * 15 | * @author Calvin 16 | * @mail 179209347@qq.com 17 | * @website www.aias.top 18 | */ 19 | public final class OcrV3Detection { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(OcrV3Detection.class); 22 | 23 | public OcrV3Detection() { 24 | } 25 | /** 26 | * 中文文本检测 27 | * @return 28 | */ 29 | public Criteria ledDetCriteria() { 30 | Criteria criteria = 31 | Criteria.builder() 32 | .optEngine("OnnxRuntime") 33 | .optModelName("inference") 34 | .setTypes(Image.class, NDList.class) 35 | .optModelPath(Paths.get("models/ch_PP-OCRv3_det_infer_onnx_led.zip")) 36 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 37 | .optProgress(new ProgressBar()) 38 | .build(); 39 | 40 | return criteria; 41 | } 42 | 43 | /** 44 | * 液晶屏文本检测 45 | * @return 46 | */ 47 | public Criteria chDetCriteria() { 48 | Criteria criteria = 49 | Criteria.builder() 50 | .optEngine("OnnxRuntime") 51 | .optModelName("inference") 52 | .setTypes(Image.class, NDList.class) 53 | .optModelPath(Paths.get("models/ch_PP-OCRv3_det_infer_onnx.zip")) 54 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 55 | .optProgress(new ProgressBar()) 56 | .build(); 57 | 58 | return criteria; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/OcrV3DetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.ndarray.NDList; 7 | import ai.djl.ndarray.NDManager; 8 | import ai.djl.opencv.OpenCVImageFactory; 9 | import ai.djl.repository.zoo.ModelZoo; 10 | import ai.djl.repository.zoo.ZooModel; 11 | import ai.djl.translate.TranslateException; 12 | import top.aias.ocr.utils.common.ImageUtils; 13 | import top.aias.ocr.utils.detection.OcrV3Detection; 14 | import org.opencv.core.Mat; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.IOException; 19 | import java.nio.file.Path; 20 | import java.nio.file.Paths; 21 | 22 | /** 23 | * OCR文字检测(V3). 24 | * OCR Detection(V3) 25 | * 26 | * @author Calvin 27 | * @mail 179209347@qq.com 28 | * @website www.aias.top 29 | */ 30 | public final class OcrV3DetExample { 31 | 32 | private static final Logger logger = LoggerFactory.getLogger(OcrV3DetExample.class); 33 | 34 | private OcrV3DetExample() { 35 | } 36 | 37 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 38 | Path imageFile = Paths.get("src/test/resources/2.jpg"); 39 | Image image = OpenCVImageFactory.getInstance().fromFile(imageFile); 40 | 41 | OcrV3Detection detection = new OcrV3Detection(); 42 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.chDetCriteria()); 43 | Predictor detector = detectionModel.newPredictor(); 44 | NDManager manager = NDManager.newBaseManager();) { 45 | 46 | NDList dt_boxes = detector.predict(image); 47 | // 交给 NDManager自动管理内存 48 | // attach to manager for automatic memory management 49 | dt_boxes.attach(manager); 50 | 51 | for (int i = 0; i < dt_boxes.size(); i++) { 52 | ImageUtils.drawRect((Mat) image.getWrappedImage(), dt_boxes.get(i)); 53 | } 54 | ImageUtils.saveImage(image, "detect_rect.png", "build/output"); 55 | ((Mat) image.getWrappedImage()).release(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ocr_v4_sdk/src/main/java/top/aias/ocr/OcrV4DetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.ndarray.NDList; 7 | import ai.djl.ndarray.NDManager; 8 | import ai.djl.opencv.OpenCVImageFactory; 9 | import ai.djl.repository.zoo.ModelZoo; 10 | import ai.djl.repository.zoo.ZooModel; 11 | import ai.djl.translate.TranslateException; 12 | import top.aias.ocr.utils.common.ImageUtils; 13 | import top.aias.ocr.utils.detection.OcrV4Detection; 14 | import org.opencv.core.Mat; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.IOException; 19 | import java.nio.file.Path; 20 | import java.nio.file.Paths; 21 | 22 | /** 23 | * OCR文字检测(V4). 24 | * OCR Detection(V4) 25 | * 26 | * @author Calvin 27 | * @mail 179209347@qq.com 28 | * @website www.aias.top 29 | */ 30 | public final class OcrV4DetExample { 31 | 32 | private static final Logger logger = LoggerFactory.getLogger(OcrV4DetExample.class); 33 | 34 | private OcrV4DetExample() { 35 | } 36 | 37 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 38 | Path imageFile = Paths.get("src/test/resources/2.jpg"); 39 | Image image = OpenCVImageFactory.getInstance().fromFile(imageFile); 40 | 41 | OcrV4Detection detection = new OcrV4Detection(); 42 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.chDetCriteria()); 43 | Predictor detector = detectionModel.newPredictor(); 44 | NDManager manager = NDManager.newBaseManager();) { 45 | 46 | NDList dt_boxes = detector.predict(image); 47 | // 交给 NDManager自动管理内存 48 | // attach to manager for automatic memory management 49 | dt_boxes.attach(manager); 50 | 51 | for (int i = 0; i < dt_boxes.size(); i++) { 52 | ImageUtils.drawRect((Mat) image.getWrappedImage(), dt_boxes.get(i)); 53 | } 54 | ImageUtils.saveImage(image, "detect_rect.png", "build/output"); 55 | ((Mat) image.getWrappedImage()).release(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ocr_led_sdk/src/main/java/top/aias/ocr/OcrV3DetExample.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr; 2 | 3 | import ai.djl.ModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.ndarray.NDList; 7 | import ai.djl.ndarray.NDManager; 8 | import ai.djl.opencv.OpenCVImageFactory; 9 | import ai.djl.repository.zoo.ModelZoo; 10 | import ai.djl.repository.zoo.ZooModel; 11 | import ai.djl.translate.TranslateException; 12 | import top.aias.ocr.utils.common.ImageUtils; 13 | import top.aias.ocr.utils.detection.OcrV3Detection; 14 | import org.opencv.core.Mat; 15 | import org.slf4j.Logger; 16 | import org.slf4j.LoggerFactory; 17 | 18 | import java.io.IOException; 19 | import java.nio.file.Path; 20 | import java.nio.file.Paths; 21 | 22 | /** 23 | * OCR文字检测(V3). 24 | * OCR Detection(V3) 25 | * 26 | * @author Calvin 27 | * @mail 179209347@qq.com 28 | * @website www.aias.top 29 | */ 30 | public final class OcrV3DetExample { 31 | 32 | private static final Logger logger = LoggerFactory.getLogger(OcrV3DetExample.class); 33 | 34 | private OcrV3DetExample() { 35 | } 36 | 37 | public static void main(String[] args) throws IOException, ModelException, TranslateException { 38 | Path imageFile = Paths.get("src/test/resources/led.jpg"); 39 | Image image = OpenCVImageFactory.getInstance().fromFile(imageFile); 40 | 41 | OcrV3Detection detection = new OcrV3Detection(); 42 | try (ZooModel detectionModel = ModelZoo.loadModel(detection.ledDetCriteria()); 43 | Predictor detector = detectionModel.newPredictor(); 44 | NDManager manager = NDManager.newBaseManager();) { 45 | 46 | NDList dt_boxes = detector.predict(image); 47 | // 交给 NDManager自动管理内存 48 | // attach to manager for automatic memory management 49 | dt_boxes.attach(manager); 50 | 51 | for (int i = 0; i < dt_boxes.size(); i++) { 52 | ImageUtils.drawRect((Mat) image.getWrappedImage(), dt_boxes.get(i)); 53 | } 54 | ImageUtils.saveImage(image, "detect_rect.png", "build/output"); 55 | ((Mat) image.getWrappedImage()).release(); 56 | } 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /ocr_table_sdk/src/main/java/top/aias/ocr/utils/layout/LayoutDetection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.layout; 2 | 3 | import ai.djl.Device; 4 | import ai.djl.ModelException; 5 | import ai.djl.inference.Predictor; 6 | import ai.djl.modality.cv.Image; 7 | import ai.djl.modality.cv.output.DetectedObjects; 8 | import ai.djl.repository.zoo.Criteria; 9 | import ai.djl.repository.zoo.ModelZoo; 10 | import ai.djl.repository.zoo.ZooModel; 11 | import ai.djl.training.util.ProgressBar; 12 | import ai.djl.translate.TranslateException; 13 | import org.slf4j.Logger; 14 | import org.slf4j.LoggerFactory; 15 | 16 | import java.io.IOException; 17 | import java.nio.file.Paths; 18 | /** 19 | * 布局检测 20 | * 21 | * @author Calvin 22 | * @mail 179209347@qq.com 23 | * @website www.aias.top 24 | */ 25 | public final class LayoutDetection implements AutoCloseable { 26 | 27 | ZooModel model; 28 | Predictor predictor; 29 | private Device device; 30 | 31 | public LayoutDetection(Device device) throws ModelException, IOException { 32 | this.device = device; 33 | this.model = ModelZoo.loadModel(tableCriteria()); 34 | this.predictor = model.newPredictor(); 35 | } 36 | 37 | public DetectedObjects predict(Image img) throws TranslateException { 38 | return predictor.predict(img); 39 | } 40 | 41 | public void close(){ 42 | this.model.close(); 43 | this.predictor.close(); 44 | } 45 | 46 | /** 47 | * picodet_lcnet_x1_0_fgd_layout_table 48 | * 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 49 | * @return 50 | */ 51 | private Criteria tableCriteria() { 52 | 53 | Criteria criteria = 54 | Criteria.builder() 55 | .optEngine("OnnxRuntime") 56 | .optModelName("inference") 57 | .setTypes(Image.class, DetectedObjects.class) 58 | .optModelPath(Paths.get("models/picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip")) 59 | .optDevice(device) 60 | .optTranslator(new LayoutDetTranslator()) 61 | .optProgress(new ProgressBar()) 62 | .build(); 63 | 64 | return criteria; 65 | } 66 | 67 | } 68 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/index.vue: -------------------------------------------------------------------------------- 1 | 13 | 14 | 52 | 53 | 94 | -------------------------------------------------------------------------------- /ocr_table_sdk/README.md: -------------------------------------------------------------------------------- 1 | ### 官网: 2 | [官网链接](https://www.aias.top/) 3 | 4 | ### 下载模型,放置于models目录 5 | - 链接: https://pan.baidu.com/s/1sQ7L9BpJtqeNsHy1uOuzGg?pwd=g2c2 6 | 7 | ## 文字识别(OCR)工具箱 8 | 文字识别(OCR)目前在多个行业中得到了广泛应用,比如金融行业的单据识别输入,餐饮行业中的发票识别, 9 | 交通领域的车票识别,企业中各种表单识别,以及日常工作生活中常用的身份证,驾驶证,护照识别等等。 10 | OCR(文字识别)是目前常用的一种AI能力。 11 | 12 | ### OCR工具箱功能: 13 | #### 表格识别 14 | - 生成html表格 15 | - 生成excel文件 16 | ```text 17 | # 表格识别 model URI 18 | table-en: https://aias-home.oss-cn-beijing.aliyuncs.com/models/ocr_models/en_table.zip 19 | ``` 20 | 21 | ### 运行OCR识别例子 22 | 23 | #### 表格识别: 24 | - 运行成功后,命令行应该看到下面的信息: 25 | ```text 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | ... 54 | 55 |
MethodsRPFFPS
SegLink[26]70.086.077089
PixelLink[4j73.283.077.8
56 | 57 | 58 | ``` 59 | 60 | - 输出图片效果如下: 61 | ![table](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/table.jpeg) 62 | 63 | - 生成excel效果如下: 64 | ![excel](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/OCR/images/excel.png) 65 | 66 | 67 | 68 | 69 | ### 开源算法 70 | #### 1. sdk使用的开源算法 71 | - [PaddleOCR](https://github.com/PaddlePaddle/PaddleOCR) 72 | 73 | #### 2. 模型如何导出 ? 74 | (readme.md 里提供了推理模型的下载链接) 75 | - [export_model](https://github.com/PaddlePaddle/PaddleOCR/blob/release%2F2.5/tools/export_model.py) 76 | - [how_to_create_paddlepaddle_model](http://docs.djl.ai/docs/paddlepaddle/how_to_create_paddlepaddle_model_zh.html) 77 | 78 | 79 | ### Git地址: 80 | [Github链接](https://github.com/mymagicpower/AIAS) 81 | [Gitee链接](https://gitee.com/mymagicpower/AIAS) 82 | 83 | 84 | #### 帮助文档: 85 | - https://aias.top/guides.html 86 | - 1.性能优化常见问题: 87 | - https://aias.top/AIAS/guides/performance.html 88 | - 2.引擎配置(包括CPU,GPU在线自动加载,及本地配置): 89 | - https://aias.top/AIAS/guides/engine_config.html 90 | - 3.模型加载方式(在线自动加载,及本地配置): 91 | - https://aias.top/AIAS/guides/load_model.html 92 | - 4.Windows环境常见问题: 93 | - https://aias.top/AIAS/guides/windows.html -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/components/Breadcrumb/index.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 65 | 66 | 79 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/model/LayoutDetectionModel.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.model; 2 | 3 | import ai.djl.MalformedModelException; 4 | import ai.djl.inference.Predictor; 5 | import ai.djl.modality.cv.Image; 6 | import ai.djl.modality.cv.output.DetectedObjects; 7 | import ai.djl.repository.zoo.Criteria; 8 | import ai.djl.repository.zoo.ModelNotFoundException; 9 | import ai.djl.repository.zoo.ModelZoo; 10 | import ai.djl.repository.zoo.ZooModel; 11 | import ai.djl.training.util.ProgressBar; 12 | import ai.djl.translate.TranslateException; 13 | import top.aias.ocr.model.pool.LayoutPool; 14 | import top.aias.ocr.translator.PicoDetLayoutDetectionTranslator; 15 | 16 | import java.io.IOException; 17 | import java.nio.file.Paths; 18 | 19 | /** 20 | * 布局检测模型 21 | * 22 | * @author Calvin 23 | * @mail 179209347@qq.com 24 | * @website www.aias.top 25 | */ 26 | public final class LayoutDetectionModel implements AutoCloseable { 27 | 28 | private ZooModel model; 29 | private LayoutPool layoutPool; 30 | 31 | public void init(String layoutUri, int poolSize) throws MalformedModelException, ModelNotFoundException, IOException { 32 | this.model = ModelZoo.loadModel(criteria(layoutUri)); 33 | this.layoutPool = new LayoutPool(poolSize, model); 34 | } 35 | 36 | public void close() { 37 | this.model.close(); 38 | this.layoutPool.close(); 39 | } 40 | 41 | public DetectedObjects predict(Image image) throws TranslateException { 42 | Predictor predictor = layoutPool.getPredictor(); 43 | DetectedObjects detectedObjects = predictor.predict(image); 44 | layoutPool.releasePredictor(predictor); 45 | return detectedObjects; 46 | } 47 | 48 | private Criteria criteria(String model) { 49 | Criteria criteria = 50 | Criteria.builder() 51 | .optEngine("OnnxRuntime") 52 | .optModelName("inference") 53 | .setTypes(Image.class, DetectedObjects.class) 54 | .optModelPath(Paths.get(model)) 55 | // .optModelUrls(model) 56 | .optTranslator(new PicoDetLayoutDetectionTranslator()) 57 | .optProgress(new ProgressBar()) 58 | .build(); 59 | 60 | return criteria; 61 | } 62 | 63 | } 64 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/utils/request.js: -------------------------------------------------------------------------------- 1 | import axios from 'axios' 2 | import { MessageBox, Message } from 'element-ui' 3 | import store from '@/store' 4 | // import { BaseURL } from '../../public/config' 5 | 6 | // create an axios instance 7 | // const baseURL = process.env.VUE_APP_BASE_API 8 | const service = axios.create({ 9 | baseURL: process.env.VUE_APP_BASE_API // url = base url + request url 10 | // withCredentials: true, // send cookies when cross-domain requests 11 | // timeout: 5000 // request timeout 12 | }) 13 | 14 | // request interceptor 15 | service.interceptors.request.use( 16 | config => { 17 | config.headers['Content-Type'] = 'application/json;charset=utf-8' 18 | return config 19 | }, 20 | error => { 21 | // do something with request error 22 | console.log(error) // for debug 23 | return Promise.reject(error) 24 | } 25 | ) 26 | 27 | // response interceptor 28 | service.interceptors.response.use( 29 | /** 30 | * If you want to get http information such as headers or status 31 | * Please return response => response 32 | */ 33 | 34 | /** 35 | * Determine the request status by custom code 36 | * Here is just an example 37 | * You can also judge the status by HTTP Status Code 38 | */ 39 | response => { 40 | const res = response.data 41 | // if the custom code is not 20000, it is judged as an error. 42 | if (res.code !== 0) { 43 | Message({ 44 | message: res.data.message, 45 | type: 'error', 46 | duration: 5 * 1000 47 | }) 48 | 49 | // 50008: Illegal token; 50012: Other clients logged in; 50014: Token expired; 50 | if (res.code === 50008 || res.code === 50012 || res.code === 50014) { 51 | // to re-login 52 | MessageBox.confirm('You have been logged out, you can cancel to stay on this page, or log in again', 'Confirm logout', { 53 | confirmButtonText: 'Re-Login', 54 | cancelButtonText: 'Cancel', 55 | type: 'warning' 56 | }).then(() => { 57 | store.dispatch('user/resetToken').then(() => { 58 | location.reload() 59 | }) 60 | }) 61 | } 62 | return Promise.reject(new Error(res.data.message || 'Error')) 63 | } else { 64 | return res 65 | } 66 | }, 67 | error => { 68 | console.log('err' + error) // for debug 69 | Message({ 70 | message: error.message, 71 | type: 'error', 72 | duration: 5 * 1000 73 | }) 74 | return Promise.reject(error) 75 | } 76 | ) 77 | 78 | export default service 79 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/configuration/ModelConfiguration.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.configuration; 2 | 3 | import ai.djl.MalformedModelException; 4 | import ai.djl.repository.zoo.ModelNotFoundException; 5 | import org.springframework.beans.factory.annotation.Value; 6 | import org.springframework.context.annotation.Bean; 7 | import org.springframework.context.annotation.Configuration; 8 | import top.aias.ocr.model.LayoutDetectionModel; 9 | import top.aias.ocr.model.MlsdSquareModel; 10 | import top.aias.ocr.model.RecognitionModel; 11 | import top.aias.ocr.model.TableRecognitionModel; 12 | 13 | import java.io.IOException; 14 | 15 | /** 16 | * 模型配置 17 | * 18 | * @author Calvin 19 | * @mail 179209347@qq.com 20 | * @website www.aias.top 21 | */ 22 | @Configuration 23 | public class ModelConfiguration { 24 | @Value("${model.table.layout}") 25 | private String tableLayout; 26 | @Value("${model.table.rec}") 27 | private String table; 28 | // ocr model 29 | @Value("${model.ocrv4.det}") 30 | private String ocrDet; 31 | @Value("${model.ocrv4.rec}") 32 | private String ocrRec; 33 | @Value("${model.mlsd.model}") 34 | private String mlsd; 35 | @Value("${model.poolSize}") 36 | private int poolSize; 37 | 38 | 39 | @Bean 40 | public RecognitionModel recognitionModel() throws IOException, ModelNotFoundException, MalformedModelException { 41 | RecognitionModel recognitionModel = new RecognitionModel(); 42 | recognitionModel.init(ocrDet, ocrRec, poolSize); 43 | return recognitionModel; 44 | } 45 | 46 | @Bean 47 | public TableRecognitionModel tableDetectionModel() throws IOException, ModelNotFoundException, MalformedModelException { 48 | TableRecognitionModel tableRecognitionModel = new TableRecognitionModel(); 49 | tableRecognitionModel.init(table, poolSize); 50 | return tableRecognitionModel; 51 | } 52 | 53 | @Bean 54 | public LayoutDetectionModel layoutDetectionModel() throws IOException, ModelNotFoundException, MalformedModelException { 55 | LayoutDetectionModel layoutDetectionModel = new LayoutDetectionModel(); 56 | layoutDetectionModel.init(tableLayout, poolSize); 57 | return layoutDetectionModel; 58 | } 59 | 60 | @Bean 61 | public MlsdSquareModel mlsdSquareModel() throws IOException, ModelNotFoundException, MalformedModelException { 62 | MlsdSquareModel mlsdSquareModel = new MlsdSquareModel(); 63 | mlsdSquareModel.init(mlsd, poolSize); 64 | return mlsdSquareModel; 65 | } 66 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/layout/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 33 | 34 | 112 | -------------------------------------------------------------------------------- /ocr_direction_det_sdk/src/main/java/top/aias/ocr/utils/cls/PpWordRotateTranslator.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.cls; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.modality.cv.util.NDImageUtils; 5 | import ai.djl.ndarray.NDArray; 6 | import ai.djl.ndarray.NDList; 7 | import ai.djl.ndarray.index.NDIndex; 8 | import ai.djl.ndarray.types.Shape; 9 | import ai.djl.translate.Batchifier; 10 | import ai.djl.translate.Translator; 11 | import ai.djl.translate.TranslatorContext; 12 | import top.aias.ocr.utils.common.DirectionInfo; 13 | 14 | import java.util.Arrays; 15 | import java.util.List; 16 | /** 17 | * 方向检测 18 | * 19 | * @author Calvin 20 | * @mail 179209347@qq.com 21 | * @website www.aias.top 22 | */ 23 | public class PpWordRotateTranslator implements Translator { 24 | List classes = Arrays.asList("No Rotate", "Rotate"); 25 | 26 | public PpWordRotateTranslator() { 27 | } 28 | 29 | public DirectionInfo processOutput(TranslatorContext ctx, NDList list) { 30 | NDArray prob = list.singletonOrThrow(); 31 | float[] res = prob.toFloatArray(); 32 | int maxIndex = 0; 33 | if (res[1] > res[0]) { 34 | maxIndex = 1; 35 | } 36 | 37 | return new DirectionInfo(classes.get(maxIndex), Double.valueOf(res[maxIndex])); 38 | } 39 | 40 | // public NDList processInput2(TranslatorContext ctx, Image input){ 41 | // NDArray img = input.toNDArray(ctx.getNDManager()); 42 | // img = NDImageUtils.resize(img, 192, 48); 43 | // img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F); 44 | // img = img.expandDims(0); 45 | // return new NDList(new NDArray[]{img}); 46 | // } 47 | 48 | public NDList processInput(TranslatorContext ctx, Image input) { 49 | NDArray img = input.toNDArray(ctx.getNDManager()); 50 | int imgC = 3; 51 | int imgH = 48; 52 | int imgW = 192; 53 | 54 | NDArray array = ctx.getNDManager().zeros(new Shape(imgC, imgH, imgW)); 55 | 56 | int h = input.getHeight(); 57 | int w = input.getWidth(); 58 | int resized_w = 0; 59 | 60 | float ratio = (float) w / (float) h; 61 | if (Math.ceil(imgH * ratio) > imgW) { 62 | resized_w = imgW; 63 | } else { 64 | resized_w = (int) (Math.ceil(imgH * ratio)); 65 | } 66 | 67 | img = NDImageUtils.resize(img, resized_w, imgH); 68 | 69 | img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F); 70 | // img = img.transpose(2, 0, 1); 71 | 72 | array.set(new NDIndex(":,:,0:" + resized_w), img); 73 | 74 | array = array.expandDims(0); 75 | 76 | return new NDList(new NDArray[]{array}); 77 | } 78 | 79 | public Batchifier getBatchifier() { 80 | return null; 81 | } 82 | } -------------------------------------------------------------------------------- /ocr_web_app/ocr_ui/src/assets/styles/eladmin.scss: -------------------------------------------------------------------------------- 1 | .head-container { 2 | padding-bottom: 10px; 3 | .filter-item { 4 | display: inline-block; 5 | vertical-align: middle; 6 | margin: 0 3px 10px 0; 7 | input { 8 | height: 30.5px; 9 | line-height: 30.5px; 10 | } 11 | } 12 | .el-form-item-label { 13 | margin: 0 3px 9px 0; 14 | display: inline-block; 15 | text-align: right; 16 | vertical-align: middle; 17 | font-size: 14px; 18 | color: #606266; 19 | line-height: 30.5px; 20 | padding: 0 7px 0 7px; 21 | } 22 | .el-button+.el-button { 23 | margin-left: 0 !important; 24 | } 25 | .el-select__caret.el-input__icon.el-icon-arrow-up{ 26 | line-height: 30.5px; 27 | } 28 | .date-item { 29 | display: inline-block; 30 | vertical-align: middle; 31 | margin-bottom: 10px; 32 | height: 30.5px !important; 33 | width: 230px !important; 34 | } 35 | } 36 | .el-avatar { 37 | display: inline-block; 38 | text-align: center; 39 | background: #ccc; 40 | color: #fff; 41 | white-space: nowrap; 42 | position: relative; 43 | overflow: hidden; 44 | vertical-align: middle; 45 | width: 32px; 46 | height: 32px; 47 | line-height: 32px; 48 | border-radius: 16px; 49 | } 50 | 51 | .logo-con{ 52 | height: 60px; 53 | padding: 13px 0 0; 54 | img{ 55 | height: 32px; 56 | width: 135px; 57 | display: block; 58 | //margin: 0 auto; 59 | } 60 | } 61 | 62 | #el-login-footer { 63 | height: 40px; 64 | line-height: 40px; 65 | position: fixed; 66 | bottom: 0; 67 | width: 100%; 68 | text-align: center; 69 | color: #fff; 70 | font-family: Arial, serif; 71 | font-size: 12px; 72 | letter-spacing: 1px; 73 | } 74 | 75 | #el-main-footer { 76 | background: none repeat scroll 0 0 white; 77 | border-top: 1px solid #e7eaec; 78 | overflow: hidden; 79 | padding: 10px 6px 0 6px; 80 | height: 33px; 81 | font-size: 0.7rem !important; 82 | color: #7a8b9a; 83 | letter-spacing: 0.8px; 84 | font-family: Arial, sans-serif !important; 85 | position: fixed; 86 | bottom: 0; 87 | z-index: 99; 88 | width: 100%; 89 | } 90 | .eladmin-upload { 91 | border: 1px dashed #c0ccda; 92 | border-radius: 5px; 93 | height: 45px; 94 | line-height: 45px; 95 | width: 368px; 96 | } 97 | .my-blockquote{ 98 | margin: 0 0 10px; 99 | padding: 15px; 100 | line-height: 22px; 101 | border-left: 5px solid #00437B; 102 | border-radius: 0 2px 2px 0; 103 | background-color: #f2f2f2; 104 | } 105 | .my-code{ 106 | position: relative; 107 | padding: 15px; 108 | line-height: 20px; 109 | border-left: 5px solid #ddd; 110 | color: #333; 111 | font-family: Courier New, serif; 112 | font-size: 12px 113 | } 114 | 115 | .el-tabs{ 116 | margin-bottom: 25px; 117 | } 118 | -------------------------------------------------------------------------------- /ocr_web_app/ocr_backend/src/main/java/top/aias/ocr/utils/DJLImageUtils.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.modality.cv.output.DetectedObjects; 5 | 6 | import java.awt.*; 7 | import java.awt.image.BufferedImage; 8 | import java.io.IOException; 9 | import java.nio.file.Files; 10 | import java.nio.file.Path; 11 | import java.nio.file.Paths; 12 | /** 13 | * DJL 图像工具类 14 | * 15 | * @author Calvin 16 | * @mail 179209347@qq.com 17 | * @website www.aias.top 18 | */ 19 | public class DJLImageUtils { 20 | 21 | public static void saveDJLImage(Image img, String name, String path) { 22 | Path outputDir = Paths.get(path); 23 | Path imagePath = outputDir.resolve(name); 24 | try { 25 | img.save(Files.newOutputStream(imagePath), "png"); 26 | } catch (IOException e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | public static void saveBoundingBoxImage( 32 | Image img, DetectedObjects detection, String name, String path) throws IOException { 33 | // Make imageName copy with alpha channel because original imageName was jpg 34 | img.drawBoundingBoxes(detection); 35 | Path outputDir = Paths.get(path); 36 | Files.createDirectories(outputDir); 37 | Path imagePath = outputDir.resolve(name); 38 | // OpenJDK can't save jpg with alpha channel 39 | img.save(Files.newOutputStream(imagePath), "png"); 40 | } 41 | 42 | public static void drawImageRect(BufferedImage image, int x, int y, int width, int height) { 43 | Graphics2D g = (Graphics2D) image.getGraphics(); 44 | try { 45 | g.setColor(new Color(246, 96, 0)); 46 | BasicStroke bStroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); 47 | g.setStroke(bStroke); 48 | g.drawRect(x, y, width, height); 49 | 50 | } finally { 51 | g.dispose(); 52 | } 53 | } 54 | 55 | public static void drawImageRect( 56 | BufferedImage image, int x, int y, int width, int height, Color c) { 57 | Graphics2D g = (Graphics2D) image.getGraphics(); 58 | try { 59 | g.setColor(c); 60 | BasicStroke bStroke = new BasicStroke(4, BasicStroke.CAP_BUTT, BasicStroke.JOIN_MITER); 61 | g.setStroke(bStroke); 62 | g.drawRect(x, y, width, height); 63 | 64 | } finally { 65 | g.dispose(); 66 | } 67 | } 68 | 69 | public static void drawImageText(BufferedImage image, String text) { 70 | Graphics graphics = image.getGraphics(); 71 | int fontSize = 100; 72 | Font font = new Font("楷体", Font.PLAIN, fontSize); 73 | try { 74 | graphics.setFont(font); 75 | graphics.setColor(new Color(246, 96, 0)); 76 | int strWidth = graphics.getFontMetrics().stringWidth(text); 77 | graphics.drawString(text, fontSize - (strWidth / 2), fontSize + 30); 78 | } finally { 79 | graphics.dispose(); 80 | } 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /ocr_v3_sdk/src/main/java/top/aias/ocr/utils/detection/OcrV3Detection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.detection; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.ndarray.NDList; 5 | import ai.djl.repository.zoo.Criteria; 6 | import ai.djl.training.util.ProgressBar; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.util.concurrent.ConcurrentHashMap; 11 | import java.nio.file.Paths; 12 | /** 13 | * 文字检测 14 | * 15 | * @author Calvin 16 | * @mail 179209347@qq.com 17 | * @website www.aias.top 18 | */ 19 | public final class OcrV3Detection { 20 | 21 | private static final Logger logger = LoggerFactory.getLogger(OcrV3Detection.class); 22 | 23 | public OcrV3Detection() { 24 | } 25 | /** 26 | * 中文文本检测 27 | * @return 28 | */ 29 | public Criteria chDetCriteria() { 30 | Criteria criteria = 31 | Criteria.builder() 32 | .optEngine("OnnxRuntime") 33 | .optModelName("inference") 34 | .setTypes(Image.class, NDList.class) 35 | .optModelPath(Paths.get("models/ch_PP-OCRv3_det_infer_onnx.zip")) 36 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 37 | .optProgress(new ProgressBar()) 38 | .build(); 39 | 40 | return criteria; 41 | } 42 | 43 | /** 44 | * 英文文本检测 45 | * @return 46 | */ 47 | public Criteria enDetCriteria() { 48 | Criteria criteria = 49 | Criteria.builder() 50 | .optEngine("OnnxRuntime") 51 | .optModelName("inference") 52 | .setTypes(Image.class, NDList.class) 53 | .optModelPath(Paths.get("models/en_PP-OCRv3_det_infer_onnx.zip")) 54 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 55 | .optProgress(new ProgressBar()) 56 | .build(); 57 | 58 | return criteria; 59 | } 60 | 61 | /** 62 | * 多语言文本检测 63 | * @return 64 | */ 65 | public Criteria mlDetCriteria() { 66 | Criteria criteria = 67 | Criteria.builder() 68 | .optEngine("OnnxRuntime") 69 | .optModelName("inference") 70 | .setTypes(Image.class, NDList.class) 71 | .optModelPath(Paths.get("models/Multilingual_PP-OCRv3_det_infer_onnx.zip")) 72 | .optTranslator(new OCRDetectionTranslator(new ConcurrentHashMap())) 73 | .optProgress(new ProgressBar()) 74 | .build(); 75 | 76 | return criteria; 77 | } 78 | } 79 | -------------------------------------------------------------------------------- /ocr_layout_sdk/src/main/java/top/aias/ocr/utils/layout/LayoutDetection.java: -------------------------------------------------------------------------------- 1 | package top.aias.ocr.utils.layout; 2 | 3 | import ai.djl.modality.cv.Image; 4 | import ai.djl.modality.cv.output.DetectedObjects; 5 | import ai.djl.repository.zoo.Criteria; 6 | import ai.djl.training.util.ProgressBar; 7 | import org.slf4j.Logger; 8 | import org.slf4j.LoggerFactory; 9 | 10 | import java.nio.file.Paths; 11 | /** 12 | * 布局检测 13 | * 14 | * @author Calvin 15 | * @mail 179209347@qq.com 16 | * @website www.aias.top 17 | */ 18 | public final class LayoutDetection { 19 | 20 | private static final Logger logger = LoggerFactory.getLogger(LayoutDetection.class); 21 | 22 | public LayoutDetection() {} 23 | 24 | /** 25 | * picodet_lcnet_x1_0_fgd_layout_cdla 26 | * CDLA数据集训练的中文版面分析模型,可以划分为表格、图片、图片标题、表格、表格标题、页眉、脚本、引用、公式10类区域 27 | * @return 28 | */ 29 | public Criteria cnCriteria() { 30 | Criteria criteria = 31 | Criteria.builder() 32 | .optEngine("OnnxRuntime") 33 | .optModelName("inference") 34 | .setTypes(Image.class, DetectedObjects.class) 35 | .optModelPath(Paths.get("models/picodet_lcnet_x1_0_fgd_layout_cdla_infer_onnx.zip")) 36 | .optTranslator(new LayoutDetectionTranslator()) 37 | .optProgress(new ProgressBar()) 38 | .build(); 39 | 40 | return criteria; 41 | } 42 | 43 | /** 44 | * picodet_lcnet_x1_0_fgd_layout 45 | * 基于PicoDet LCNet_x1_0和FGD蒸馏在PubLayNet 数据集训练的英文版面分析模型,可以划分文字、标题、表格、图片以及列表5类区域 46 | * @return 47 | */ 48 | public Criteria enCriteria() { 49 | 50 | Criteria criteria = 51 | Criteria.builder() 52 | .optEngine("OnnxRuntime") 53 | .optModelName("inference") 54 | .setTypes(Image.class, DetectedObjects.class) 55 | .optModelPath(Paths.get("models/picodet_lcnet_x1_0_fgd_layout_infer_onnx.zip")) 56 | .optTranslator(new LayoutDetectionTranslator()) 57 | .optProgress(new ProgressBar()) 58 | .build(); 59 | 60 | return criteria; 61 | } 62 | 63 | /** 64 | * picodet_lcnet_x1_0_fgd_layout_table 65 | * 表格数据集训练的版面分析模型,支持中英文文档表格区域的检测 66 | * @return 67 | */ 68 | public Criteria tableCriteria() { 69 | 70 | Criteria criteria = 71 | Criteria.builder() 72 | .optEngine("OnnxRuntime") 73 | .optModelName("inference") 74 | .setTypes(Image.class, DetectedObjects.class) 75 | .optModelPath(Paths.get("models/picodet_lcnet_x1_0_fgd_layout_table_infer_onnx.zip")) 76 | .optTranslator(new LayoutDetectionTranslator()) 77 | .optProgress(new ProgressBar()) 78 | .build(); 79 | 80 | return criteria; 81 | } 82 | 83 | } 84 | --------------------------------------------------------------------------------