├── .gitignore
├── src
├── main
│ ├── resources
│ │ ├── model
│ │ │ ├── ocr
│ │ │ │ ├── ocr_cls_model.txt
│ │ │ │ ├── ocr_det_model.txt
│ │ │ │ ├── ocr_rec_model.txt
│ │ │ │ └── ch_ppocr_mobile_v2.0_cls_infer.zip
│ │ │ └── layout
│ │ │ │ └── layout.zip
│ │ └── application.properties
│ └── java
│ │ └── com
│ │ ├── sy
│ │ ├── DocAIServiceApplication.java
│ │ ├── common
│ │ │ ├── Constants.java
│ │ │ ├── PredictException.java
│ │ │ ├── ModelUrlUtils.java
│ │ │ ├── DetectObjectDto.java
│ │ │ └── ImageUtils.java
│ │ ├── layout
│ │ │ ├── LayoutProperties.java
│ │ │ ├── LayoutTranslator.java
│ │ │ ├── LayoutController.java
│ │ │ └── LayoutService.java
│ │ └── ocr
│ │ │ ├── OcrProperties.java
│ │ │ ├── MyRotateTranslator.java
│ │ │ ├── MyRecognitionTranslator.java
│ │ │ ├── OcrController.java
│ │ │ └── OcrService.java
│ │ └── utils
│ │ ├── FileFormatUtil.java
│ │ ├── PropertiesReader.java
│ │ ├── FileUploadConfig.java
│ │ └── CollectionUtil.java
└── test
│ └── java
│ └── com
│ └── sy
│ └── doc_ai
│ └── DocAiApplicationTests.java
├── requirements.txt
├── img
├── ocr_result.png
└── layout_result.png
├── .idea
├── encodings.xml
├── modules.xml
├── libraries
│ ├── Maven__ai_djl_api_0_15_0.xml
│ ├── Maven__org_ow2_asm_asm_9_1.xml
│ ├── Maven__dom4j_dom4j_1_6_1.xml
│ ├── Maven__org_apache_poi_poi_4_0_0.xml
│ ├── Maven__net_java_dev_jna_jna_5_9_0.xml
│ ├── Maven__org_hamcrest_hamcrest_2_2.xml
│ ├── Maven__org_yaml_snakeyaml_1_29.xml
│ ├── Maven__xml_apis_xml_apis_1_0_b2.xml
│ ├── Maven__com_aspose_aspose_ocr_22_9.xml
│ ├── Maven__org_objenesis_objenesis_3_2.xml
│ ├── Maven__org_slf4j_slf4j_api_1_7_36.xml
│ ├── Maven__com_google_code_gson_gson_2_8_9.xml
│ ├── Maven__com_fasterxml_classmate_1_5_1.xml
│ ├── Maven__net_minidev_json_smart_2_4_8.xml
│ ├── Maven__org_mockito_mockito_core_4_0_0.xml
│ ├── Maven__org_opentest4j_opentest4j_1_2_0.xml
│ ├── Maven__org_projectlombok_lombok_1_18_22.xml
│ ├── Maven__org_slf4j_jul_to_slf4j_1_7_36.xml
│ ├── Maven__org_xmlunit_xmlunit_core_2_8_4.xml
│ ├── Maven__org_skyscreamer_jsonassert_1_5_0.xml
│ ├── Maven__commons_codec_commons_codec_1_15.xml
│ ├── Maven__net_bytebuddy_byte_buddy_1_11_22.xml
│ ├── Maven__org_assertj_assertj_core_3_21_0.xml
│ ├── Maven__com_jayway_jsonpath_json_path_2_6_0.xml
│ ├── Maven__io_springfox_springfox_oas_3_0_0.xml
│ ├── Maven__io_springfox_springfox_spi_3_0_0.xml
│ ├── Maven__io_springfox_springfox_core_3_0_0.xml
│ ├── Maven__io_swagger_swagger_models_1_5_20.xml
│ ├── Maven__ch_qos_logback_logback_core_1_2_10.xml
│ ├── Maven__net_minidev_accessors_smart_2_4_8.xml
│ ├── Maven__org_apache_commons_commons_lang3_3_7.xml
│ ├── Maven__org_springframework_spring_aop_5_3_16.xml
│ ├── Maven__org_springframework_spring_jcl_5_3_16.xml
│ ├── Maven__org_springframework_spring_web_5_3_16.xml
│ ├── Maven__io_github_classgraph_classgraph_4_8_83.xml
│ ├── Maven__io_springfox_springfox_schema_3_0_0.xml
│ ├── Maven__org_mapstruct_mapstruct_1_3_1_Final.xml
│ ├── Maven__ai_djl_pytorch_pytorch_engine_0_15_0.xml
│ ├── Maven__org_junit_jupiter_junit_jupiter_5_8_2.xml
│ ├── Maven__org_springframework_spring_core_5_3_16.xml
│ ├── Maven__org_springframework_spring_test_5_3_16.xml
│ ├── Maven__ch_qos_logback_logback_classic_1_2_10.xml
│ ├── Maven__org_apiguardian_apiguardian_api_1_1_2.xml
│ ├── Maven__io_swagger_core_v3_swagger_models_2_1_2.xml
│ ├── Maven__org_apache_logging_log4j_log4j_api_2_17_1.xml
│ ├── Maven__org_springframework_spring_beans_5_3_16.xml
│ ├── Maven__io_springfox_springfox_swagger2_3_0_0.xml
│ ├── Maven__org_springframework_boot_spring_boot_2_6_4.xml
│ ├── Maven__org_springframework_spring_webmvc_5_3_16.xml
│ ├── Maven__io_springfox_springfox_data_rest_3_0_0.xml
│ ├── Maven__io_swagger_swagger_annotations_1_5_20.xml
│ ├── Maven__net_bytebuddy_byte_buddy_agent_1_11_22.xml
│ ├── Maven__org_apache_commons_commons_compress_1_21.xml
│ ├── Maven__ai_djl_pytorch_pytorch_model_zoo_0_15_0.xml
│ ├── Maven__org_springframework_spring_context_5_3_16.xml
│ ├── Maven__ai_djl_pytorch_pytorch_native_auto_1_9_1.xml
│ ├── Maven__com_microsoft_onnxruntime_onnxruntime_1_10_0.xml
│ ├── Maven__io_springfox_springfox_spring_web_3_0_0.xml
│ ├── Maven__io_springfox_springfox_swagger_ui_3_0_0.xml
│ ├── Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml
│ ├── Maven__org_mockito_mockito_junit_jupiter_4_0_0.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_core_2_13_1.xml
│ ├── Maven__io_springfox_springfox_boot_starter_3_0_0.xml
│ ├── Maven__org_apache_commons_commons_collections4_4_2.xml
│ ├── Maven__ai_djl_onnxruntime_onnxruntime_engine_0_15_0.xml
│ ├── Maven__io_swagger_core_v3_swagger_annotations_2_1_2.xml
│ ├── Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml
│ ├── Maven__org_apache_logging_log4j_log4j_to_slf4j_2_17_1.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_58.xml
│ ├── Maven__org_springframework_spring_expression_5_3_16.xml
│ ├── Maven__commons_collections_commons_collections_3_2_2.xml
│ ├── Maven__io_springfox_springfox_spring_webmvc_3_0_0.xml
│ ├── Maven__org_junit_jupiter_junit_jupiter_engine_5_8_2.xml
│ ├── Maven__org_junit_jupiter_junit_jupiter_params_5_8_2.xml
│ ├── Maven__org_springframework_boot_spring_boot_test_2_6_4.xml
│ ├── Maven__io_springfox_springfox_spring_webflux_3_0_0.xml
│ ├── Maven__io_springfox_springfox_swagger_common_3_0_0.xml
│ ├── Maven__ai_djl_paddlepaddle_paddlepaddle_engine_0_15_0.xml
│ ├── Maven__org_junit_platform_junit_platform_engine_1_8_2.xml
│ ├── Maven__io_springfox_springfox_bean_validators_3_0_0.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_58.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_databind_2_13_1.xml
│ ├── Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml
│ ├── Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml
│ ├── Maven__org_junit_platform_junit_platform_commons_1_8_2.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_2_6_4.xml
│ ├── Maven__ai_djl_paddlepaddle_paddlepaddle_model_zoo_0_15_0.xml
│ ├── Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_1.xml
│ ├── Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_58.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_web_2_6_4.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_json_2_6_4.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_test_2_6_4.xml
│ ├── Maven__org_springframework_boot_spring_boot_autoconfigure_2_6_4.xml
│ ├── Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_13_1.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_tomcat_2_6_4.xml
│ ├── Maven__org_springframework_boot_spring_boot_starter_logging_2_6_4.xml
│ ├── Maven__org_springframework_plugin_spring_plugin_core_2_0_0_RELEASE.xml
│ ├── Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_13_1.xml
│ ├── Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml
│ ├── Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_6_4.xml
│ ├── Maven__org_springframework_plugin_spring_plugin_metadata_2_0_0_RELEASE.xml
│ ├── Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_13_1.xml
│ └── Maven__org_springframework_boot_spring_boot_configuration_processor_2_6_4.xml
├── misc.xml
├── compiler.xml
├── jarRepositories.xml
├── workspace.xml
└── doc_ai.iml
├── README.md
├── pom.xml
└── doc_ai.iml
/.gitignore:
--------------------------------------------------------------------------------
1 | # Project exclude paths
2 | /target/
--------------------------------------------------------------------------------
/src/main/resources/model/ocr/ocr_cls_model.txt:
--------------------------------------------------------------------------------
1 | 这里是ocr的方向模型
--------------------------------------------------------------------------------
/src/main/resources/model/ocr/ocr_det_model.txt:
--------------------------------------------------------------------------------
1 | 这里是ocr的检测模型
--------------------------------------------------------------------------------
/src/main/resources/model/ocr/ocr_rec_model.txt:
--------------------------------------------------------------------------------
1 | 这里是ocr的识别模型
--------------------------------------------------------------------------------
/requirements.txt:
--------------------------------------------------------------------------------
1 | java11
2 | djl
3 | springboot
4 | onnxruntime
5 |
--------------------------------------------------------------------------------
/img/ocr_result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangnanboy/doc_ai/HEAD/img/ocr_result.png
--------------------------------------------------------------------------------
/img/layout_result.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangnanboy/doc_ai/HEAD/img/layout_result.png
--------------------------------------------------------------------------------
/src/main/resources/model/layout/layout.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangnanboy/doc_ai/HEAD/src/main/resources/model/layout/layout.zip
--------------------------------------------------------------------------------
/src/main/resources/application.properties:
--------------------------------------------------------------------------------
1 | spring.mvc.pathmatch.matching-strategy=ant_path_matcher
2 | spring.servlet.multipart.max-file-size=10MB
3 |
--------------------------------------------------------------------------------
/src/main/resources/model/ocr/ch_ppocr_mobile_v2.0_cls_infer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jiangnanboy/doc_ai/HEAD/src/main/resources/model/ocr/ch_ppocr_mobile_v2.0_cls_infer.zip
--------------------------------------------------------------------------------
/.idea/encodings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/src/test/java/com/sy/doc_ai/DocAiApplicationTests.java:
--------------------------------------------------------------------------------
1 | package com.sy.doc_ai;
2 |
3 | import org.junit.jupiter.api.Test;
4 | import org.springframework.boot.test.context.SpringBootTest;
5 |
6 | @SpringBootTest
7 | class DocAiApplicationTests {
8 |
9 | @Test
10 | void contextLoads() {
11 | }
12 |
13 | }
14 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/DocAIServiceApplication.java:
--------------------------------------------------------------------------------
1 | package com.sy;
2 |
3 | import org.springframework.boot.SpringApplication;
4 | import org.springframework.boot.autoconfigure.SpringBootApplication;
5 |
6 | /**
7 | * @author sy
8 | * @date 2022/9/13 22:25
9 | */
10 | @SpringBootApplication
11 | public class DocAIServiceApplication {
12 | public static void main(String[] args) {
13 | SpringApplication.run(DocAIServiceApplication.class, args);
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/common/Constants.java:
--------------------------------------------------------------------------------
1 | package com.sy.common;
2 |
3 | import lombok.experimental.UtilityClass;
4 |
5 | /**
6 | * @author sy
7 | * @date 2022/9/13 22:24
8 | */
9 | @UtilityClass
10 | public class Constants {
11 | /**
12 | * OCR推理引擎使用不同框架
13 | */
14 | public static final String ENGINE_PADDLE = "PaddlePaddle";
15 | public static final String ENGINE_ONNX = "OnnxRuntime";
16 | public static final String ENGINE_PYTORCH = "PyTorch";
17 | }
18 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/common/PredictException.java:
--------------------------------------------------------------------------------
1 | package com.sy.common;
2 |
3 | /**
4 | * 推理异常
5 | * @author sy
6 | * @date 2022/9/13 21:30
7 | */
8 | public class PredictException extends RuntimeException {
9 |
10 | public PredictException() {
11 | }
12 |
13 | public PredictException(Throwable exception) {
14 | super(exception);
15 | }
16 |
17 | public PredictException(String message, Throwable cause) {
18 | super(message, cause);
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_api_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_ow2_asm_asm_9_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__dom4j_dom4j_1_6_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
12 |
13 |
14 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_poi_poi_4_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_java_dev_jna_jna_5_9_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_hamcrest_hamcrest_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_yaml_snakeyaml_1_29.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__xml_apis_xml_apis_1_0_b2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_aspose_aspose_ocr_22_9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_objenesis_objenesis_3_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_slf4j_api_1_7_36.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_google_code_gson_gson_2_8_9.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_classmate_1_5_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_minidev_json_smart_2_4_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/utils/FileFormatUtil.java:
--------------------------------------------------------------------------------
1 | package com.utils;
2 |
3 | import java.util.Arrays;
4 | import java.util.List;
5 |
6 | /**
7 | * @author sy
8 | * @date 2022/11/11 22:35
9 | */
10 | public class FileFormatUtil {
11 | static List supportFileFormats = CollectionUtil.newArrayList(Arrays.asList("jpeg,jpg,png".split(",")));
12 | public static boolean checkFormats(String fileFullName) {
13 | String suffix = fileFullName.substring(fileFullName.lastIndexOf(".") + 1).toLowerCase();
14 | return supportFileFormats.stream().anyMatch(suffix::contains);
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mockito_mockito_core_4_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_opentest4j_opentest4j_1_2_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_projectlombok_lombok_1_18_22.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_slf4j_jul_to_slf4j_1_7_36.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_xmlunit_xmlunit_core_2_8_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_skyscreamer_jsonassert_1_5_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_codec_commons_codec_1_15.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_bytebuddy_byte_buddy_1_11_22.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_assertj_assertj_core_3_21_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_jayway_jsonpath_json_path_2_6_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_oas_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_spi_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_core_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_swagger_swagger_models_1_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_core_1_2_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_minidev_accessors_smart_2_4_8.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_lang3_3_7.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_aop_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_jcl_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_web_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_github_classgraph_classgraph_4_8_83.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_schema_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mapstruct_mapstruct_1_3_1_Final.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_pytorch_pytorch_engine_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_5_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_core_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_test_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ch_qos_logback_logback_classic_1_2_10.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apiguardian_apiguardian_api_1_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_swagger_core_v3_swagger_models_2_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_logging_log4j_log4j_api_2_17_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_beans_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_swagger2_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_webmvc_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_data_rest_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_swagger_swagger_annotations_1_5_20.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__net_bytebuddy_byte_buddy_agent_1_11_22.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_compress_1_21.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_pytorch_pytorch_model_zoo_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_context_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_pytorch_pytorch_native_auto_1_9_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_microsoft_onnxruntime_onnxruntime_1_10_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_spring_web_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_swagger_ui_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_api_5_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_mockito_mockito_junit_jupiter_4_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_core_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_boot_starter_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_commons_commons_collections4_4_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_onnxruntime_onnxruntime_engine_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_swagger_core_v3_swagger_annotations_2_1_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__jakarta_xml_bind_jakarta_xml_bind_api_2_3_3.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_logging_log4j_log4j_to_slf4j_2_17_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_el_9_0_58.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_spring_expression_5_3_16.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__commons_collections_commons_collections_3_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_spring_webmvc_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_engine_5_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_jupiter_junit_jupiter_params_5_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_spring_webflux_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_swagger_common_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_paddlepaddle_paddlepaddle_engine_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_platform_junit_platform_engine_1_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__io_springfox_springfox_bean_validators_3_0_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_core_9_0_58.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_databind_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__jakarta_activation_jakarta_activation_api_1_2_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__jakarta_annotation_jakarta_annotation_api_1_3_5.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_junit_platform_junit_platform_commons_1_8_2.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__ai_djl_paddlepaddle_paddlepaddle_model_zoo_0_15_0.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_core_jackson_annotations_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_apache_tomcat_embed_tomcat_embed_websocket_9_0_58.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/layout/LayoutProperties.java:
--------------------------------------------------------------------------------
1 | package com.sy.layout;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author sy
9 | * @date 2022/9/13 21:56
10 | */
11 | @Data
12 | @ConfigurationProperties(prefix = "doc.ai.layout1")
13 | @Configuration
14 | public class LayoutProperties {
15 | private String deviceType = "cpu";
16 | private String yoloUrl = "/model/layout/layout.zip";
17 | private String modelName = "layout_model.onnx";
18 | private String nameList = "coco.names";
19 | private Float threshold = 0.45f;
20 | private Integer width = 640;
21 | private Integer height = 640;
22 | }
23 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_web_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_json_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_test_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_autoconfigure_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jdk8_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_tomcat_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_starter_logging_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_plugin_spring_plugin_core_2_0_0_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_datatype_jackson_datatype_jsr310_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_vaadin_external_google_android_json_0_0_20131108_vaadin1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/ocr/OcrProperties.java:
--------------------------------------------------------------------------------
1 | package com.sy.ocr;
2 |
3 | import lombok.Data;
4 | import org.springframework.boot.context.properties.ConfigurationProperties;
5 | import org.springframework.context.annotation.Configuration;
6 |
7 | /**
8 | * @author sy
9 | * @date 2022/9/13 22:24
10 | */
11 | @Data
12 | @ConfigurationProperties(prefix = "doc.ai.ocr")
13 | @Configuration
14 | public class OcrProperties {
15 | private String detectUrl = "/model/ocr/ocr_det_model.onnx";
16 | private String recognizeUrl = "/model/ocr/ocr_rec_model.onnx";
17 | private String recognizerUrl = "/model/ocr/ch_ppocr_mobile_v2.0_cls_infer.zip";
18 | private String deviceType = "cpu";
19 | private String ppocrKeysV1Path = "/model/ocr/ppocr_keys_v1.txt";
20 | private double rotateThreshold = 0.8;
21 | }
22 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_test_autoconfigure_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_plugin_spring_plugin_metadata_2_0_0_RELEASE.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__com_fasterxml_jackson_module_jackson_module_parameter_names_2_13_1.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/libraries/Maven__org_springframework_boot_spring_boot_configuration_processor_2_6_4.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/.idea/compiler.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
--------------------------------------------------------------------------------
/src/main/java/com/utils/PropertiesReader.java:
--------------------------------------------------------------------------------
1 | package com.utils;
2 |
3 | import org.slf4j.Logger;
4 | import org.slf4j.LoggerFactory;
5 |
6 | import java.io.IOException;
7 | import java.io.InputStreamReader;
8 | import java.util.Properties;
9 |
10 | /**
11 | * @author sy
12 | * @date 2022/9/14 19:07
13 | */
14 | public class PropertiesReader {
15 |
16 | private static final Logger LOGGER = LoggerFactory.getLogger(PropertiesReader.class);
17 |
18 | private static Properties properties = new Properties();
19 |
20 | static {
21 | try {
22 | properties.load(new InputStreamReader(PropertiesReader.class.getClassLoader().getResourceAsStream("properties.properties"), "UTF-8"));
23 |
24 | } catch (IOException e) {
25 | e.printStackTrace();
26 | }
27 | }
28 |
29 | public static String get(String keyName) {
30 | return properties.getProperty(keyName, "");
31 | }
32 |
33 | }
34 |
--------------------------------------------------------------------------------
/.idea/jarRepositories.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/main/java/com/utils/FileUploadConfig.java:
--------------------------------------------------------------------------------
1 | package com.utils;
2 |
3 | import ai.djl.training.dataset.Dataset;
4 | import org.springframework.beans.factory.annotation.Value;
5 | import org.springframework.boot.context.properties.ConfigurationProperties;
6 | import org.springframework.boot.web.servlet.MultipartConfigFactory;
7 | import org.springframework.context.annotation.Bean;
8 | import org.springframework.context.annotation.Configuration;
9 | import org.springframework.util.unit.DataSize;
10 |
11 | import javax.servlet.MultipartConfigElement;
12 |
13 | /**
14 | * @author sy
15 | * @date 2022/11/11 22:57
16 | */
17 | @Configuration
18 | public class FileUploadConfig {
19 | @Bean
20 | public MultipartConfigElement multipartConfigElement() {
21 | MultipartConfigFactory multipartConfigFactory = new MultipartConfigFactory();
22 | // 单个文件大小为5MB
23 | multipartConfigFactory.setMaxFileSize(DataSize.ofMegabytes(5));
24 | // 总上传数据大小10MB
25 | multipartConfigFactory.setMaxRequestSize(DataSize.ofMegabytes(10));
26 | return multipartConfigFactory.createMultipartConfig();
27 | }
28 | }
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/common/ModelUrlUtils.java:
--------------------------------------------------------------------------------
1 | package com.sy.common;
2 |
3 | import lombok.SneakyThrows;
4 | import lombok.experimental.UtilityClass;
5 | import lombok.extern.slf4j.Slf4j;
6 | import org.springframework.core.io.ClassPathResource;
7 |
8 | import java.io.IOException;
9 | import java.net.URI;
10 |
11 | /**
12 | * @author sy
13 | * @date 2022/9/13 15:24
14 | */
15 | @UtilityClass
16 | @Slf4j
17 | public class ModelUrlUtils {
18 |
19 | /**
20 | * 获取模型url,如果是http或file开头,直接返回
21 | * @param name 模型名称
22 | * @return url
23 | */
24 | @SneakyThrows
25 | public static String getRealUrl(String name) {
26 | if (name.startsWith("http") || name.startsWith("file:")) {
27 | System.out.println("model url is : " + name);
28 | return name;
29 | }
30 |
31 | URI uri = null;
32 | try {
33 | uri = new ClassPathResource(name).getURI();
34 | } catch (IOException e) {
35 | e.printStackTrace();
36 | }
37 |
38 | System.out.println("model uri of " + name + " is " + uri);
39 | if (uri.toString().startsWith("jar:")) {
40 | return "jar://" + name;
41 | }
42 |
43 | return uri.toString();
44 | }
45 |
46 | }
47 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | DJL for document AI
2 |
3 |
4 |
5 | Table of Contents
6 |
7 | -
8 | About
9 |
10 | -
11 | Getting Started
12 |
13 | -
14 | Result
15 |
16 | -
17 | Contact
18 |
19 | -
20 | Reference
21 |
22 |
23 |
24 |
25 |
26 | #### About
27 |
28 | 这里将paddle中的ocr等模型转为onnx格式,并利用java版深度框架djl加载这些onnx模型进行推理预测尝试。
29 |
30 | #### Getting started
31 | onnx模型下载:
32 |
33 | 链接:https://pan.baidu.com/s/1Vcsn-VPTU_GHB_KU4pQFPg
34 |
35 | 提取码:uepl
36 |
37 | 项目启动后可以进入swagger进行接口使用 http://localhost:8080/swagger-ui/
38 |
39 | #### Result
40 | 
41 |
42 | 
43 |
44 |
45 | #### Contact
46 | 如有问题,联系我:
47 |
48 | 1、github:https://github.com/jiangnanboy
49 |
50 | 2、QQ:2229029156
51 |
52 | #### Reference
53 | https://github.com/PaddlePaddle/PaddleOCR
54 |
55 | https://github.com/deepjavalibrary/djl
56 |
57 |
58 |
--------------------------------------------------------------------------------
/src/main/java/com/utils/CollectionUtil.java:
--------------------------------------------------------------------------------
1 | package com.utils;
2 |
3 | import java.util.*;
4 |
5 | /**
6 | * @author sy
7 | * @date 2022/9/14 21:36
8 | */
9 | public class CollectionUtil {
10 |
11 | public static List newArrayList() {
12 | return new ArrayList<>();
13 | }
14 |
15 | public static LinkedList newLinkedList() {
16 | return new LinkedList<>();
17 | }
18 |
19 | public static List newArrayList(int N) {
20 | return new ArrayList<>(N);
21 | }
22 |
23 | public static List newArrayList(Set entry) {
24 | return new ArrayList<>(entry);
25 | }
26 |
27 | public static Set newHashset() {
28 | return new HashSet<>();
29 | }
30 |
31 | public static Set newHashset(List entry) {
32 | return new HashSet<>(entry);
33 | }
34 |
35 | public static Map newHashMap() {
36 | return new HashMap<>();
37 | }
38 |
39 | public static LinkedHashMap newLinkedHashMap() {
40 | return new LinkedHashMap<>();
41 | }
42 |
43 | public static Map newTreeMap() {
44 | return new TreeMap<>();
45 | }
46 |
47 | public static List newArrayList(List asList) {
48 | return asList;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/common/DetectObjectDto.java:
--------------------------------------------------------------------------------
1 | package com.sy.common;
2 |
3 | import ai.djl.modality.Classifications;
4 | import ai.djl.modality.cv.output.DetectedObjects;
5 | import lombok.Data;
6 | import lombok.NoArgsConstructor;
7 | import lombok.experimental.Accessors;
8 |
9 | import java.util.HashMap;
10 | import java.util.Map;
11 |
12 | import static java.util.Objects.isNull;
13 |
14 | /**
15 | * @author sy
16 | * @date 2022/9/13 19:24
17 | */
18 | @Data
19 | @Accessors(chain = true)
20 | @NoArgsConstructor
21 | public class DetectObjectDto {
22 | private String className;
23 | private Double probability;
24 | private Double x;
25 | private Double y;
26 | private Double width;
27 | private Double height;
28 | private Map data;
29 |
30 | public DetectObjectDto(Classifications.Classification item) {
31 | if (!(item instanceof DetectedObjects.DetectedObject)) {
32 | throw new IllegalArgumentException("item is not DetectedObject");
33 | }
34 |
35 | DetectedObjects.DetectedObject i = (DetectedObjects.DetectedObject) item;
36 |
37 | this.className = i.getClassName();
38 | this.x = i.getBoundingBox().getBounds().getX();
39 | this.y = i.getBoundingBox().getBounds().getY();
40 | this.width = i.getBoundingBox().getBounds().getWidth();
41 | this.height = i.getBoundingBox().getBounds().getHeight();
42 | }
43 |
44 | public Map getData() {
45 | if (isNull(data)) {
46 | data = new HashMap<>();
47 | }
48 | return data;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/ocr/MyRotateTranslator.java:
--------------------------------------------------------------------------------
1 | package com.sy.ocr;
2 |
3 | import ai.djl.modality.Classifications;
4 | import ai.djl.modality.cv.Image;
5 | import ai.djl.modality.cv.util.NDImageUtils;
6 | import ai.djl.ndarray.NDArray;
7 | import ai.djl.ndarray.NDList;
8 | import ai.djl.translate.NoBatchifyTranslator;
9 | import ai.djl.translate.TranslatorContext;
10 | import com.utils.CollectionUtil;
11 |
12 | import java.util.Arrays;
13 | import java.util.List;
14 |
15 | /**
16 | * @author sy
17 | * @date 2022/11/9 23:59
18 | */
19 | public class MyRotateTranslator implements NoBatchifyTranslator {
20 | List rotateCls = Arrays.asList("No Rotate", "Rotate");
21 |
22 | public MyRotateTranslator() {
23 | }
24 |
25 | @Override
26 | public Classifications processOutput(TranslatorContext ctx, NDList list) {
27 | NDArray prob = list.singletonOrThrow();
28 | float[] probDoub = prob.toFloatArray();
29 | List probabilities = CollectionUtil.newArrayList();
30 | probabilities.add((double) probDoub[0]);
31 | probabilities.add((double) probDoub[1]);
32 | System.out.println("prob: " + probabilities.get(0) + " " + probabilities.get(1));
33 | return new Classifications(this.rotateCls, probabilities);
34 | }
35 |
36 | @Override
37 | public NDList processInput(TranslatorContext ctx, Image input) {
38 | NDArray img = input.toNDArray(ctx.getNDManager());
39 | int[] hw = this.resize32((double) input.getHeight(), (double) input.getWidth());
40 | img = NDImageUtils.resize(img, hw[1], hw[0]);
41 | img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F);
42 | img = img.expandDims(0);
43 | return new NDList(new NDArray[]{img});
44 | }
45 |
46 | private int[] resize32(double h, double w) {
47 | double min = Math.min(h, w);
48 | if (min < 32.0D) {
49 | h = 32.0D / min * h;
50 | w = 32.0D / min * w;
51 | }
52 |
53 | int h32 = (int) h / 32;
54 | int w32 = (int) w / 32;
55 | return new int[]{h32 * 32, w32 * 32};
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/ocr/MyRecognitionTranslator.java:
--------------------------------------------------------------------------------
1 | package com.sy.ocr;
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.translate.NoBatchifyTranslator;
8 | import ai.djl.translate.TranslatorContext;
9 |
10 | import java.io.BufferedReader;
11 | import java.io.IOException;
12 | import java.nio.charset.StandardCharsets;
13 | import java.nio.file.Files;
14 | import java.nio.file.Paths;
15 | import java.util.List;
16 | import java.util.stream.Collectors;
17 |
18 | /**
19 | * @author sy
20 | * @date 2022/11/8 22:00
21 | */
22 | public class MyRecognitionTranslator implements NoBatchifyTranslator {
23 |
24 | private List synset;
25 |
26 | public MyRecognitionTranslator(String keysPath) {
27 | try(BufferedReader br = Files.newBufferedReader(Paths.get(keysPath), StandardCharsets.UTF_8)) {
28 | synset = br.lines().collect(Collectors.toList());
29 | synset.add(0, "blank");
30 | synset.add("");
31 | } catch (IOException i) {
32 | i.printStackTrace();
33 | }
34 | }
35 |
36 | @Override
37 | public String processOutput(TranslatorContext ctx, NDList list) {
38 | StringBuilder sb = new StringBuilder();
39 | NDArray tokens = list.singletonOrThrow();
40 | long[] indices = tokens.get(new long[]{0L}).argMax(1).toLongArray();
41 | int lastIdx = 0;
42 | for(int i = 0; i < indices.length; ++i) {
43 | if (indices[i] > 0L && (i <= 0 || indices[i] != (long)lastIdx)) {
44 | sb.append((String)this.synset.get((int)indices[i]));
45 | }
46 | }
47 | return sb.toString();
48 | }
49 |
50 | @Override
51 | public NDList processInput(TranslatorContext ctx, Image image) {
52 | NDArray img = image.toNDArray(ctx.getNDManager());
53 | int[] hw = this.resize32((double)image.getWidth());
54 | img = NDImageUtils.resize(img, hw[1], hw[0]);
55 | img = NDImageUtils.toTensor(img).sub(0.5F).div(0.5F);
56 | img = img.expandDims(0);
57 | return new NDList(new NDArray[]{img});
58 | }
59 |
60 | private int[] resize32(double w) {
61 | int width = (int)Math.max(32.0D, w) / 32 * 32;
62 | return new int[]{48, width};
63 | }
64 |
65 | }
66 |
67 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/ocr/OcrController.java:
--------------------------------------------------------------------------------
1 | package com.sy.ocr;
2 |
3 | import ai.djl.modality.cv.Image;
4 | import ai.djl.modality.cv.ImageFactory;
5 | import ai.djl.modality.cv.output.DetectedObjects;
6 | import com.sy.common.DetectObjectDto;
7 | import com.sy.common.ImageUtils;
8 | import io.swagger.annotations.ApiOperation;
9 | import lombok.RequiredArgsConstructor;
10 | import lombok.extern.slf4j.Slf4j;
11 | import org.apache.commons.lang3.tuple.Pair;
12 | import org.springframework.web.bind.annotation.*;
13 | import org.springframework.web.multipart.MultipartFile;
14 |
15 | import javax.imageio.ImageIO;
16 | import javax.servlet.ServletOutputStream;
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.awt.image.BufferedImage;
19 | import java.io.IOException;
20 | import java.util.List;
21 | import java.util.stream.Collectors;
22 |
23 | //import static com.sy.common.ImageUtils.evalAngle;
24 |
25 |
26 | /**
27 | * @author sy
28 | * @date 2022/9/13 21:43
29 | */
30 | @RestController
31 | @RequestMapping("ocr")
32 | @RequiredArgsConstructor
33 | @Slf4j
34 | public class OcrController {
35 |
36 | private final OcrService ocrService;
37 |
38 | /**
39 | * 返回文字识别后的图片
40 | *
41 | * @param image
42 | * @param response
43 | * @throws IOException
44 | */
45 | @PostMapping("image")
46 | @ApiOperation("文字识别,返回图片结果")
47 | public void ocrImage(@RequestPart MultipartFile image, HttpServletResponse response) throws IOException {
48 | Image img = ImageFactory.getInstance().fromInputStream(image.getInputStream());
49 | img = ImageUtils.checkSize(img);
50 | DetectedObjects result = ocrService.ocr(img);
51 | BufferedImage resultImage = ocrService.createResultImage(img, result);
52 | response.setContentType("image/png");
53 | ServletOutputStream os = response.getOutputStream();
54 | ImageIO.write(resultImage, "PNG", os);
55 | os.flush();
56 | }
57 |
58 | /**
59 | * @param image
60 | * @return
61 | * @throws IOException
62 | */
63 | @PostMapping
64 | @ApiOperation("文字识别,返回对象结果")
65 | public List ocr(@RequestPart MultipartFile image) throws IOException {
66 | Image img = ImageFactory.getInstance().fromInputStream(image.getInputStream());
67 | img = ImageUtils.checkSize(img);
68 | DetectedObjects result = ocrService.ocr(img);
69 | return result.items().stream().map(DetectObjectDto::new).collect(Collectors.toList());
70 | }
71 |
72 | }
73 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/layout/LayoutTranslator.java:
--------------------------------------------------------------------------------
1 | package com.sy.layout;
2 |
3 | import ai.djl.modality.cv.Image;
4 | import ai.djl.modality.cv.output.BoundingBox;
5 | import ai.djl.modality.cv.output.DetectedObjects;
6 | import ai.djl.modality.cv.output.Rectangle;
7 | import ai.djl.ndarray.NDList;
8 | import ai.djl.translate.Batchifier;
9 | import ai.djl.translate.Translator;
10 | import ai.djl.translate.TranslatorContext;
11 | import com.utils.CollectionUtil;
12 |
13 | import java.util.List;
14 |
15 | /**
16 | * @author sy
17 | * @date 2022/9/13 21:07
18 | */
19 | public class LayoutTranslator implements Translator {
20 |
21 | private final LayoutProperties layoutProperties;
22 |
23 | private final Translator delegated;
24 |
25 | public LayoutTranslator(Translator translator, LayoutProperties layoutProperties) {
26 | this.delegated = translator;
27 | this.layoutProperties = layoutProperties;
28 | }
29 |
30 | @Override
31 | public DetectedObjects processOutput(TranslatorContext ctx, NDList list) throws Exception {
32 | DetectedObjects output = delegated.processOutput(ctx, list);
33 | List classList = CollectionUtil.newArrayList();
34 | List probList = CollectionUtil.newArrayList();
35 | List rectList = CollectionUtil.newArrayList();
36 |
37 | final int width = layoutProperties.getWidth();
38 | final int height = layoutProperties.getHeight();
39 |
40 | final List items = output.items();
41 | items.forEach(item -> {
42 | classList.add(item.getClassName());
43 | probList.add(item.getProbability());
44 |
45 | Rectangle b = item.getBoundingBox().getBounds();
46 | Rectangle newBox = new Rectangle(b.getX() / width, b.getY() / height, b.getWidth() / width, b.getHeight() / height);
47 |
48 | rectList.add(newBox);
49 | });
50 | return new DetectedObjects(classList, probList, rectList);
51 | }
52 |
53 | @Override
54 | public NDList processInput(TranslatorContext ctx, Image input) throws Exception {
55 | return delegated.processInput(ctx, input);
56 | }
57 |
58 | @Override
59 | public void prepare(TranslatorContext ctx) throws Exception {
60 | delegated.prepare(ctx);
61 | }
62 |
63 | @Override
64 | public Batchifier getBatchifier() {
65 | return delegated.getBatchifier();
66 | }
67 |
68 | }
69 |
70 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/layout/LayoutController.java:
--------------------------------------------------------------------------------
1 | package com.sy.layout;
2 |
3 | import ai.djl.modality.cv.output.DetectedObjects;
4 | import com.sy.common.DetectObjectDto;
5 | import io.swagger.annotations.ApiOperation;
6 | import lombok.RequiredArgsConstructor;
7 | import lombok.extern.slf4j.Slf4j;
8 | import org.apache.commons.lang3.tuple.Pair;
9 | import org.springframework.web.bind.annotation.PostMapping;
10 | import org.springframework.web.bind.annotation.RequestMapping;
11 | import org.springframework.web.bind.annotation.RequestPart;
12 | import org.springframework.web.bind.annotation.RestController;
13 | import org.springframework.web.multipart.MultipartFile;
14 |
15 | import javax.imageio.ImageIO;
16 | import javax.servlet.ServletOutputStream;
17 | import javax.servlet.http.HttpServletResponse;
18 | import java.awt.image.BufferedImage;
19 | import java.io.IOException;
20 | import java.util.List;
21 | import java.util.stream.Collectors;
22 |
23 | import static com.sy.common.ImageUtils.evalAngle;
24 |
25 | /**
26 | * @author sy
27 | * @date 2022/9/13 22:00
28 | */
29 | @RestController
30 | @RequestMapping("layout_onnx")
31 | @RequiredArgsConstructor
32 | @Slf4j
33 | public class LayoutController {
34 |
35 | private final LayoutService layoutService;
36 |
37 | @PostMapping("image")
38 | @ApiOperation("图片文档版面检测,返回图片结果")
39 | public void ocr(@RequestPart MultipartFile file, HttpServletResponse response) throws IOException {
40 | BufferedImage image = ImageIO.read(file.getInputStream());
41 | Pair pair = evalAngle(image);
42 | double skew = pair.getLeft();
43 | BufferedImage imageRes = pair.getRight();
44 | if(skew != 0) {
45 | image = imageRes;
46 | }
47 | BufferedImage result = layoutService.getResultImage(image);
48 | response.setContentType("image/png");
49 | ServletOutputStream os = response.getOutputStream();
50 | ImageIO.write(result, "PNG", os);
51 | os.flush();
52 | }
53 |
54 | @PostMapping
55 | @ApiOperation("图片文档版面检测,返回结果对象")
56 | public List ocr(@RequestPart MultipartFile file) throws IOException {
57 | BufferedImage image = ImageIO.read(file.getInputStream());
58 | Pair pair = evalAngle(image);
59 | double skew = pair.getLeft();
60 | BufferedImage imageRes = pair.getRight();
61 | if(skew != 0) {
62 | image = imageRes;
63 | }
64 | DetectedObjects result = layoutService.detect(image);
65 | return result.items().stream().map(DetectObjectDto::new).collect(Collectors.toList());
66 | }
67 |
68 | }
69 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/layout/LayoutService.java:
--------------------------------------------------------------------------------
1 | package com.sy.layout;
2 |
3 | import ai.djl.Device;
4 | import ai.djl.MalformedModelException;
5 | import ai.djl.inference.Predictor;
6 | import ai.djl.modality.cv.Image;
7 | import ai.djl.modality.cv.ImageFactory;
8 | import ai.djl.modality.cv.output.DetectedObjects;
9 | import ai.djl.modality.cv.translator.YoloV5Translator;
10 | import ai.djl.repository.zoo.Criteria;
11 | import ai.djl.repository.zoo.ModelNotFoundException;
12 | import ai.djl.repository.zoo.ModelZoo;
13 | import ai.djl.repository.zoo.ZooModel;
14 | import ai.djl.translate.TranslateException;
15 | import ai.djl.translate.Translator;
16 | import com.sy.common.ImageUtils;
17 | import com.sy.common.ModelUrlUtils;
18 | import lombok.RequiredArgsConstructor;
19 | import lombok.SneakyThrows;
20 | import lombok.extern.slf4j.Slf4j;
21 | import org.springframework.stereotype.Service;
22 |
23 | import javax.annotation.PostConstruct;
24 | import javax.annotation.PreDestroy;
25 | import java.awt.image.BufferedImage;
26 | import java.io.IOException;
27 |
28 | import static com.sy.common.Constants.ENGINE_ONNX;
29 | import static com.sy.common.ImageUtils.scale;
30 | import static java.util.Objects.nonNull;
31 |
32 | /**
33 | * @author sy
34 | * @date 2022/9/13 19:32
35 | */
36 | @Slf4j
37 | @Service
38 | @RequiredArgsConstructor
39 | public class LayoutService {
40 |
41 | private final LayoutProperties layoutProperties;
42 | private ZooModel layoutModel;
43 | private Device device = null;
44 |
45 | @PostConstruct
46 | public void init() throws ModelNotFoundException, MalformedModelException, IOException {
47 | device = Device.Type.CPU.equalsIgnoreCase(layoutProperties.getDeviceType()) ? Device.cpu() : Device.gpu();
48 | System.out.println("开始加载YOLO模型");
49 | loadLayoutModel();
50 | System.out.println("YOLO模型加载完成");
51 | }
52 |
53 | /**
54 | * 加载layout model
55 | * @throws MalformedModelException
56 | * @throws ModelNotFoundException
57 | * @throws IOException
58 | */
59 | public void loadLayoutModel() throws MalformedModelException, ModelNotFoundException, IOException {
60 | Translator translator = YoloV5Translator
61 | .builder()
62 | .optThreshold(layoutProperties.getThreshold())
63 | .optSynsetArtifactName(layoutProperties.getNameList())
64 | .build();
65 | LayoutTranslator myTranslator = new LayoutTranslator(translator, layoutProperties);
66 | Criteria criteria = Criteria.builder()
67 | .setTypes(Image.class, DetectedObjects.class)
68 | .optDevice(device)
69 | .optModelUrls(ModelUrlUtils.getRealUrl(layoutProperties.getYoloUrl()))
70 | .optModelName(layoutProperties.getModelName())
71 | .optTranslator(myTranslator)
72 | .optEngine(ENGINE_ONNX)
73 | .build();
74 | layoutModel = ModelZoo.loadModel(criteria);
75 | }
76 |
77 | @PreDestroy
78 | public void destroy() {
79 | if (nonNull(layoutModel)) {
80 | layoutModel.close();
81 | }
82 | System.out.println("yolo model closed...");
83 | }
84 |
85 | /**
86 | * 对象检测函数
87 | * @param image 图片,尺寸需满足yolo网络入参大小
88 | */
89 | @SneakyThrows
90 | public DetectedObjects detect(BufferedImage image) {
91 | final BufferedImage scale = scale(image, layoutProperties.getWidth(), layoutProperties.getHeight());
92 | Image img = ImageFactory.getInstance().fromImage(scale);
93 | return detect(img);
94 | }
95 |
96 | /**
97 | * 对象检测函数
98 | * @param image
99 | */
100 | @SneakyThrows
101 | public DetectedObjects detect(Image image) {
102 | long startTime = System.currentTimeMillis();
103 | Image scaledImage = scale(image, layoutProperties.getWidth(), layoutProperties.getHeight());
104 | //开始检测图片
105 | DetectedObjects detections = null;
106 | try (Predictor predictor = layoutModel.newPredictor()) {
107 | detections = predictor.predict(scaledImage);
108 | } catch (TranslateException e) {
109 | e.printStackTrace();
110 | }
111 | System.out.println("results : " + detections);
112 | System.out.println("detect cost : " + (System.currentTimeMillis() - startTime) + " ms");
113 | return detections;
114 | }
115 |
116 | /**
117 | * 检测并绘制结果
118 | * @param image
119 | * @return 带有绘制结果的图片
120 | */
121 | public BufferedImage getResultImage(BufferedImage image) {
122 | //将图片大小设置为网络输入要求的大小
123 | BufferedImage scale = scale(image, layoutProperties.getWidth(), layoutProperties.getHeight());
124 | Image img = ImageFactory.getInstance().fromImage(scale);
125 | DetectedObjects detections = detect(img);
126 | //将结果绘制到图片中
127 | return ImageUtils.drawDetections(image, detections);
128 | }
129 |
130 | }
131 |
132 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
5 | 4.0.0
6 |
7 | org.example
8 | doc_ai
9 | 1.0-SNAPSHOT
10 |
11 |
12 | org.springframework.boot
13 | spring-boot-starter-parent
14 | 2.6.4
15 |
16 |
17 |
18 |
19 | 11
20 | 1.10.0
21 | 1.9.1
22 |
23 |
24 |
25 |
26 |
27 | ai.djl
28 | bom
29 | 0.15.0
30 | pom
31 | import
32 |
33 |
34 |
35 |
36 |
37 |
38 | org.springframework.boot
39 | spring-boot-starter-web
40 |
41 |
42 | org.springframework.boot
43 | spring-boot-configuration-processor
44 | true
45 |
46 |
47 | org.springframework.boot
48 | spring-boot-starter-test
49 |
50 |
51 |
52 | org.projectlombok
53 | lombok
54 | true
55 |
56 |
57 |
58 | io.springfox
59 | springfox-boot-starter
60 | 3.0.0
61 |
62 |
63 |
64 | ai.djl
65 | api
66 |
67 |
68 | ai.djl.paddlepaddle
69 | paddlepaddle-model-zoo
70 |
71 |
72 | ai.djl.pytorch
73 | pytorch-model-zoo
74 |
75 |
76 | ai.djl.pytorch
77 | pytorch-engine
78 | runtime
79 |
80 |
81 | ai.djl.pytorch
82 | pytorch-native-auto
83 | ${pytorch.version}
84 |
85 |
86 |
87 | ai.djl.onnxruntime
88 | onnxruntime-engine
89 |
90 |
91 | com.microsoft.onnxruntime
92 | onnxruntime
93 |
94 |
95 |
96 |
97 |
98 | com.microsoft.onnxruntime
99 | onnxruntime
100 | ${onnx.version}
101 | runtime
102 |
103 |
104 |
105 | org.apache.commons
106 | commons-lang3
107 | 3.7
108 |
109 |
110 |
111 | org.apache.poi
112 | poi
113 | 4.0.0
114 |
115 |
116 |
117 | dom4j
118 | dom4j
119 | 1.6.1
120 |
121 |
122 |
123 | commons-collections
124 | commons-collections
125 | 3.2.2
126 |
127 |
128 |
129 | com.aspose
130 | aspose-ocr
131 | 22.9
132 |
133 |
134 |
135 |
136 |
137 |
138 | AsposeJavaAPI
139 | Aspose Java API
140 | https://releases.aspose.com/java/repo/
141 |
142 |
143 |
144 |
145 |
146 |
147 |
148 | org.springframework.boot
149 | spring-boot-maven-plugin
150 |
151 |
152 |
153 | org.projectlombok
154 | lombok
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
--------------------------------------------------------------------------------
/.idea/workspace.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
56 |
57 |
58 |
59 |
60 |
61 | 1668221848189
62 |
63 |
64 | 1668221848189
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/ocr/OcrService.java:
--------------------------------------------------------------------------------
1 | package com.sy.ocr;
2 |
3 | import ai.djl.Device;
4 | import ai.djl.MalformedModelException;
5 | import ai.djl.inference.Predictor;
6 | import ai.djl.modality.Classifications;
7 | import ai.djl.modality.cv.Image;
8 | import ai.djl.modality.cv.ImageFactory;
9 | import ai.djl.modality.cv.output.BoundingBox;
10 | import ai.djl.modality.cv.output.DetectedObjects;
11 | import ai.djl.paddlepaddle.zoo.cv.imageclassification.PpWordRotateTranslator;
12 | import ai.djl.paddlepaddle.zoo.cv.objectdetection.PpWordDetectionTranslator;
13 | import ai.djl.repository.zoo.Criteria;
14 | import ai.djl.repository.zoo.ModelNotFoundException;
15 | import ai.djl.repository.zoo.ZooModel;
16 | import ai.djl.translate.TranslateException;
17 | import com.sy.common.ImageUtils;
18 | import com.sy.common.ModelUrlUtils;
19 | import com.utils.CollectionUtil;
20 | import lombok.RequiredArgsConstructor;
21 | import lombok.SneakyThrows;
22 | import lombok.extern.slf4j.Slf4j;
23 | import org.springframework.stereotype.Service;
24 |
25 | import javax.annotation.PostConstruct;
26 | import javax.annotation.PreDestroy;
27 | import java.awt.image.BufferedImage;
28 | import java.io.IOException;
29 | import java.util.List;
30 | import java.util.Optional;
31 | import java.util.concurrent.ConcurrentHashMap;
32 |
33 | import static com.sy.common.Constants.ENGINE_ONNX;
34 | import static com.sy.common.Constants.ENGINE_PADDLE;
35 | import static com.sy.common.ImageUtils.rotateImage;
36 |
37 |
38 | /**
39 | * @author sy
40 | * @date 2022/9/13 19:27
41 | */
42 | @Service
43 | @Slf4j
44 | @RequiredArgsConstructor
45 | public class OcrService {
46 | private final OcrProperties prop;
47 |
48 | // 文本检测
49 | private ZooModel detector = null;
50 | // 文本方向检测
51 | private ZooModel classifier = null;
52 | // 文字识别
53 | private ZooModel recognizer = null;
54 | private Device device = null;
55 |
56 | /**
57 | * 初始化加载ocr几个模型
58 | */
59 | @PostConstruct
60 | private void init() {
61 | device = Device.Type.CPU.equalsIgnoreCase(prop.getDeviceType()) ? Device.cpu() : Device.gpu();
62 | System.out.println("开始加载Ocr工具类");
63 | loadOcrDetModel();
64 | loadOcrClsModel();
65 | loadOcrRecModel();
66 | System.out.println("加载Ocr工具类完成");
67 | }
68 |
69 | /**
70 | * 文字识别
71 | * @param url
72 | * @return
73 | */
74 | @SneakyThrows
75 | public DetectedObjects ocr(String url) {
76 | Image image = null;
77 | try {
78 | image = ImageFactory.getInstance().fromUrl(url);
79 | } catch (IOException e) {
80 | e.printStackTrace();
81 | }
82 | return ocr(image);
83 | }
84 |
85 | /**
86 | * 文字识别
87 | * @param image
88 | * @return
89 | */
90 | public DetectedObjects ocr(Image image) {
91 | DetectedObjects detect = detect(image);
92 |
93 | List names = CollectionUtil.newArrayList();
94 | List prob = CollectionUtil.newArrayList();
95 | List rect = CollectionUtil.newArrayList();
96 |
97 | List list = detect.items();
98 | for (DetectedObjects.DetectedObject result : list) {
99 | BoundingBox box = result.getBoundingBox();
100 |
101 | //扩展文字块的大小,因为检测出来的文字块比实际文字块要小
102 | Image subImg = ImageUtils.getSubImage(image, ImageUtils.extendBox(box));
103 |
104 | // if (subImg.getHeight() * 1.0 / subImg.getWidth() > 1.5) {
105 | // subImg = ImageUtils.rotateImage(subImg);
106 | // }
107 |
108 | Classifications.Classification classifications = checkRotate(subImg);
109 | if ("Rotate".equals(classifications.getClassName()) && classifications.getProbability() > prop.getRotateThreshold()) {
110 | subImg = rotateImage(subImg);
111 | }
112 | String name = recognize(subImg);
113 | names.add(name);
114 | prob.add(1.0);
115 | rect.add(box);
116 | }
117 | return new DetectedObjects(names, prob, rect);
118 | }
119 |
120 | /**
121 | * 结果图片
122 | * @param image 图片
123 | * @return image
124 | */
125 | public BufferedImage createResultImage(Image image, DetectedObjects result) {
126 | image.drawBoundingBoxes(result);
127 | return (BufferedImage) image.getWrappedImage();
128 | }
129 |
130 | /**
131 | * 文字识别
132 | * @param image
133 | */
134 | @SneakyThrows
135 | private String recognize(Image image) {
136 | String result = null;
137 | try (Predictor predictor = recognizer.newPredictor()){
138 | result = predictor.predict(image);
139 | } catch (TranslateException e) {
140 | e.printStackTrace();
141 | }
142 | return result;
143 | }
144 |
145 | /**
146 | * 判断文字角度,如果需要旋转则进行相应处理
147 | * @return Classifications
148 | */
149 | @SneakyThrows
150 | private Classifications.Classification checkRotate(Image image) {
151 | Classifications.Classification result = null;
152 | try (Predictor predictor = classifier.newPredictor()){
153 | result = predictor.predict(image).best();
154 | } catch (TranslateException e) {
155 | e.printStackTrace();
156 | }
157 | return result;
158 | }
159 |
160 | /**
161 | * 检测文字所在区域
162 | * @param image
163 | * @return
164 | */
165 | @SneakyThrows
166 | public DetectedObjects detect(Image image) {
167 | DetectedObjects result = null;
168 | try (Predictor predictor = detector.newPredictor()){
169 | result = predictor.predict(image);
170 | } catch (TranslateException e) {
171 | e.printStackTrace();
172 | }
173 | return result;
174 | }
175 |
176 | /**
177 | * 加载检测模型
178 | */
179 | public void loadOcrDetModel() {
180 | Criteria criterial = Criteria.builder()
181 | .optEngine(ENGINE_ONNX)
182 | .optDevice(device)
183 | .setTypes(Image.class, DetectedObjects.class)
184 | .optModelUrls(ModelUrlUtils.getRealUrl(prop.getDetectUrl()))
185 | .optTranslator(new PpWordDetectionTranslator(new ConcurrentHashMap()))
186 | .build();
187 | try {
188 | detector = criterial.loadModel();
189 | } catch (IOException e) {
190 | e.printStackTrace();
191 | } catch (ModelNotFoundException e) {
192 | e.printStackTrace();
193 | } catch (MalformedModelException e) {
194 | e.printStackTrace();
195 | }
196 | if(Optional.ofNullable(detector).isPresent()) {
197 | logModelInfo(detector);
198 | }
199 | }
200 |
201 | /**
202 | * 加载方向检测模型
203 | */
204 | public void loadOcrClsModel() {
205 | Criteria criteria = Criteria.builder()
206 | .optEngine(ENGINE_PADDLE)
207 | .optDevice(device)
208 | .setTypes(Image.class, Classifications.class)
209 | .optModelUrls(ModelUrlUtils.getRealUrl(prop.getRecognizerUrl()))
210 | .optTranslator(new PpWordRotateTranslator())
211 | .build();
212 | try {
213 | classifier = criteria.loadModel();
214 | } catch (IOException e) {
215 | e.printStackTrace();
216 | } catch (ModelNotFoundException e) {
217 | e.printStackTrace();
218 | } catch (MalformedModelException e) {
219 | e.printStackTrace();
220 | }
221 | if(Optional.ofNullable(classifier).isPresent()) {
222 | logModelInfo(classifier);
223 | }
224 | }
225 |
226 | /**
227 | * 加载文字识别模型
228 | */
229 | public void loadOcrRecModel() {
230 | String ppocrKeysV1Path = ModelUrlUtils.getRealUrl(prop.getPpocrKeysV1Path());
231 | ppocrKeysV1Path = ppocrKeysV1Path.replace("file:/", "");
232 | Criteria criteria = Criteria.builder()
233 | .optEngine(ENGINE_ONNX)
234 | .optDevice(device)
235 | .setTypes(Image.class, String.class)
236 | .optModelUrls(ModelUrlUtils.getRealUrl(prop.getRecognizeUrl()))
237 | .optTranslator(new MyRecognitionTranslator(ppocrKeysV1Path))
238 | .build();
239 | try {
240 | recognizer = criteria.loadModel();
241 | } catch (IOException e) {
242 | e.printStackTrace();
243 | } catch (ModelNotFoundException e) {
244 | e.printStackTrace();
245 | } catch (MalformedModelException e) {
246 | e.printStackTrace();
247 | }
248 | if(Optional.ofNullable(recognizer).isPresent()) {
249 | logModelInfo(recognizer);
250 | }
251 | }
252 |
253 | /**
254 | * 服务停止关闭所有模型
255 | */
256 | @PreDestroy
257 | public void closeAll() {
258 | if(Optional.ofNullable(this.detector).isPresent()) {
259 | this.detector.close();
260 | }
261 | if(Optional.ofNullable(this.recognizer).isPresent()) {
262 | this.recognizer.close();
263 | }
264 | if(Optional.ofNullable(this.classifier).isPresent()) {
265 | this.classifier.close();
266 | }
267 | System.out.println("close all models");
268 | }
269 |
270 | /**
271 | * 打印model信息
272 | * @param model
273 | */
274 | private void logModelInfo(ZooModel, ?> model) {
275 | System.out.println("model name : " + model.getName() + "\n" +
276 | "model path : " + model.getModelPath());
277 | }
278 |
279 | }
280 |
--------------------------------------------------------------------------------
/src/main/java/com/sy/common/ImageUtils.java:
--------------------------------------------------------------------------------
1 | package com.sy.common;
2 |
3 | import ai.djl.modality.cv.Image;
4 | import ai.djl.modality.cv.ImageFactory;
5 | import ai.djl.modality.cv.output.BoundingBox;
6 | import ai.djl.modality.cv.output.DetectedObjects;
7 | import ai.djl.modality.cv.output.Rectangle;
8 | import ai.djl.modality.cv.util.NDImageUtils;
9 | import ai.djl.ndarray.NDArray;
10 | import ai.djl.ndarray.NDManager;
11 | import ai.djl.ndarray.types.DataType;
12 | import com.aspose.ocr.AsposeOCR;
13 | import com.aspose.ocr.PreprocessingFilter;
14 | import com.aspose.ocr.RecognitionResult;
15 | import com.aspose.ocr.RecognitionSettings;
16 | import lombok.experimental.UtilityClass;
17 | import org.apache.commons.lang3.tuple.Pair;
18 | import org.assertj.core.util.Files;
19 |
20 | import javax.imageio.ImageIO;
21 | import java.awt.*;
22 | import java.awt.image.BufferedImage;
23 | import java.io.File;
24 | import java.io.IOException;
25 | import java.nio.file.Paths;
26 | import java.util.List;
27 | import java.util.Map;
28 |
29 | import static java.awt.Image.SCALE_DEFAULT;
30 |
31 | /**
32 | * @author sy
33 | * @date 2022/9/13 21:24
34 | */
35 | @UtilityClass
36 | public class ImageUtils {
37 |
38 | private static final Map colorMap = Map.of(
39 | 0, new Color(200, 0, 0),
40 | 1, new Color(0, 200, 0),
41 | 2, new Color(0, 0, 200),
42 | 3, new Color(200, 200, 0),
43 | 4, new Color(200, 0, 200),
44 | 5, new Color(0, 200, 200)
45 | );
46 |
47 | /**
48 | * 旋转图片90度
49 | *
50 | * @param image 图片
51 | * @return 旋转90度后的图片
52 | */
53 | public static Image rotateImage(Image image) {
54 | try (NDManager manager = NDManager.newBaseManager()) {
55 | NDArray rotated = NDImageUtils.rotate90(image.toNDArray(manager), 1);
56 | return ImageFactory.getInstance().fromNDArray(rotated);
57 | }
58 | }
59 |
60 | public static Image readImg(String imgPath) {
61 | Image img = null;
62 | try {
63 | img = ImageFactory.getInstance().fromFile(Paths.get(imgPath));
64 | img.getWrappedImage();
65 | } catch (IOException e) {
66 | e.printStackTrace();
67 | }
68 | return img;
69 | }
70 |
71 | /**
72 | * 图片缩放
73 | *
74 | * @param original 原始图
75 | * @param width 宽
76 | * @param height 高
77 | * @return 缩放后的图片
78 | */
79 | public static BufferedImage scale(BufferedImage original, int width, int height) {
80 | if (width == original.getWidth() && height == original.getHeight()) {
81 | return original;
82 | }
83 |
84 | java.awt.Image scaledInstance = original.getScaledInstance(width, height, SCALE_DEFAULT);
85 | BufferedImage scaledImage = new BufferedImage(width, height, original.getType());
86 | scaledImage.getGraphics().drawImage(scaledInstance, 0, 0, null);
87 | return scaledImage;
88 | }
89 |
90 | /**
91 | * 图片缩放
92 | *
93 | * @param original 原始图
94 | * @param width 宽
95 | * @param height 高
96 | * @return 缩放后的图片
97 | */
98 | public static Image scale(Image original, int width, int height) {
99 | if (width == original.getWidth() && height == original.getHeight()) {
100 | return original;
101 | }
102 |
103 | try(NDManager manager = NDManager.newBaseManager()) {
104 | NDArray ndArray = original.toNDArray(manager);
105 | NDArray resize = NDImageUtils.resize(ndArray, width, height, Image.Interpolation.BILINEAR);
106 | resize = resize.toType(DataType.FLOAT32, false); // INT8
107 | resize = resize.div(255);
108 | return ImageFactory.getInstance().fromNDArray(resize);
109 | }
110 | }
111 |
112 | public static Image checkSize(Image image) {
113 | if((image.getHeight() > 960) && (image.getWidth() > 960)) {
114 | try (NDManager manager = NDManager.newBaseManager()) {
115 | NDArray ndArray = image.toNDArray(manager);
116 | ndArray = NDImageUtils.resize(ndArray, 960, 960);
117 | image = ImageFactory.getInstance().fromNDArray(ndArray.toType(DataType.UINT8, false));
118 | }
119 | }
120 | return image;
121 | }
122 |
123 | /**
124 | * 绘制检测结果
125 | * djl自带的绘制内容太少,只有名称,因此做了修改
126 | * 以下是djl自带的绘制方法
127 | * Image img = ImageFactory.getInstance().fromImage(image);
128 | * img.drawBoundingBoxes(detections);
129 | * return (BufferedImage) img.getWrappedImage();
130 | *
131 | * @param image 图片
132 | * @param detections 检测结果
133 | */
134 | public static BufferedImage drawDetections(BufferedImage image, DetectedObjects detections) {
135 |
136 | Graphics2D g = (Graphics2D) image.getGraphics();
137 | int stroke = 2;
138 | g.setStroke(new BasicStroke(stroke));
139 | g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
140 | int imageWidth = image.getWidth();
141 | int imageHeight = image.getHeight();
142 |
143 | List list = detections.items();
144 | for (DetectedObjects.DetectedObject result : list) {
145 | String className = result.getClassName();
146 | BoundingBox box = result.getBoundingBox();
147 | double probability = result.getProbability();
148 | Color color = colorMap.get(Math.abs(className.hashCode() % 6));
149 | g.setPaint(color);
150 |
151 | Rectangle rectangle = box.getBounds();
152 | int x = (int) (rectangle.getX() * imageWidth);
153 | int y = (int) (rectangle.getY() * imageHeight);
154 | int width = (int) (rectangle.getWidth() * imageWidth);
155 | int height = (int) (rectangle.getHeight() * imageHeight);
156 | g.drawRect(x, y, width, height);
157 |
158 | drawText(g, className, probability, x, y, width);
159 | }
160 | g.dispose();
161 |
162 | return image;
163 | }
164 |
165 | private static void drawText(Graphics2D g, String className, double probability, int x, int y, int width) {
166 | //设置水印的坐标
167 | String showText = String.format("%s %.0f%%", className, probability * 100);
168 | g.fillRect(x, y - 30, width, 30);
169 |
170 | g.setColor(Color.WHITE);
171 | g.setFont(new Font("Monospaced", Font.BOLD, 25));//设置字体
172 | g.drawString(showText, x, y - 10);
173 | }
174 |
175 | /**
176 | * 获取文字所在的区块图
177 | *
178 | * @param image 原始图片
179 | * @param box 子区块
180 | * @return 带有文字的image
181 | */
182 | public static Image getSubImage(Image image, BoundingBox box) {
183 | Rectangle rect = box.getBounds();
184 |
185 | int width = image.getWidth();
186 | int height = image.getHeight();
187 | int[] recovered = {
188 | (int) (rect.getX() * width),
189 | (int) (rect.getY() * height),
190 | (int) (rect.getWidth() * width),
191 | (int) (rect.getHeight() * height)
192 | };
193 | return image.getSubImage(recovered[0], recovered[1], recovered[2], recovered[3]);
194 | }
195 |
196 | public static Image getExtendSubImage(Image img, BoundingBox box) {
197 | Rectangle rect = box.getBounds();
198 | double[] extended = extendRect(rect.getX(), rect.getY(), rect.getWidth(), rect.getHeight());
199 | int width = img.getWidth();
200 | int height = img.getHeight();
201 | int[] recovered = {
202 | (int) (extended[0] * width),
203 | (int) (extended[1] * height),
204 | (int) (extended[2] * width),
205 | (int) (extended[3] * height)
206 | };
207 | return img.getSubImage(recovered[0], recovered[1], recovered[2], recovered[3]);
208 | }
209 |
210 | /**
211 | * 扩展矩形框
212 | *
213 | * @param box 矩形
214 | * @return 扩展后的大小
215 | */
216 | public static BoundingBox extendBox(BoundingBox box) {
217 | Rectangle rect = box.getBounds();
218 | double x = rect.getX();
219 | double y = rect.getY();
220 | double width = rect.getWidth();
221 | double height = rect.getHeight();
222 |
223 | double centerX = x + width / 2;
224 | double centerY = y + height / 2;
225 | if (width > height) {
226 | width += height * 2.0;
227 | height *= 3.0;
228 | } else {
229 | height += width * 2.0;
230 | width *= 3.0;
231 | }
232 | double newX = centerX - width / 2 < 0 ? 0 : centerX - width / 2;
233 | double newY = centerY - height / 2 < 0 ? 0 : centerY - height / 2;
234 | double newWidth = newX + width > 1 ? 1 - newX : width;
235 | double newHeight = newY + height > 1 ? 1 - newY : height;
236 | return new Rectangle(newX, newY, newWidth, newHeight);
237 | }
238 |
239 | public static double[] extendRect(double xmin, double ymin, double width, double height) {
240 | double centerx = xmin + width / 2;
241 | double centery = ymin + height / 2;
242 | if (width > height) {
243 | width += height * 2.0;
244 | height *= 3.0;
245 | } else {
246 | height += width * 2.0;
247 | width *= 3.0;
248 | }
249 | double newX = centerx - width / 2 < 0 ? 0 : centerx - width / 2;
250 | double newY = centery - height / 2 < 0 ? 0 : centery - height / 2;
251 | double newWidth = newX + width > 1 ? 1 - newX : width;
252 | double newHeight = newY + height > 1 ? 1 - newY : height;
253 | return new double[] {newX, newY, newWidth, newHeight};
254 | }
255 |
256 | public static Pair evalAngle(BufferedImage image) {
257 | AsposeOCR asposeOCR = new AsposeOCR();
258 | double skew=0;
259 | try {
260 | skew = asposeOCR.CalcSkewImage(image);
261 | } catch (IOException e) {
262 | e.printStackTrace();
263 | }
264 | // 添加纠偏过滤器
265 | PreprocessingFilter filters = new PreprocessingFilter();
266 | filters.add(PreprocessingFilter.AutoSkew());
267 | BufferedImage imageRes = asposeOCR.PreprocessImage(image, filters);
268 | // 获取Graphics2D
269 | Graphics2D g2d = image.createGraphics();
270 | //消除锯齿
271 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
272 | g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
273 | // 释放对象
274 | g2d.dispose();
275 |
276 | return Pair.of(skew, imageRes);
277 | }
278 |
279 | }
280 |
281 |
--------------------------------------------------------------------------------
/doc_ai.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------
/.idea/doc_ai.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
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 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
127 |
128 |
129 |
130 |
131 |
132 |
--------------------------------------------------------------------------------