mirror of
https://gitee.com/mymagicpower/AIAS.git
synced 2024-11-29 18:58:16 +08:00
no message
This commit is contained in:
parent
8812056b5c
commit
079f0ad71a
41
archive/1_image_sdks/image_kit/imagekit_java/README_cn.md
Normal file
41
archive/1_image_sdks/image_kit/imagekit_java/README_cn.md
Normal file
@ -0,0 +1,41 @@
|
||||
## 目录:
|
||||
https://aias.top/
|
||||
|
||||
# 图像预处理SDK
|
||||
在OCR文字识别的时候,我们得到的图像一般情况下都不是正的,多少都会有一定的倾斜。
|
||||
所以需要将图片转正。并且图片有可能是透视视角拍摄,需要重新矫正。
|
||||
|
||||
### SDK功能
|
||||
-图像转正
|
||||
-图像二值化,灰度化,去燥等经典算法。
|
||||
|
||||
### 完善中的功能:
|
||||
-完善透视矫正
|
||||
-完善文字方向检测算法,判断转正后的图片角度,以便进一步旋转图片使得文字水平。
|
||||
|
||||
## 运行例子
|
||||
运行成功后,命令行应该看到下面的信息:
|
||||
```text
|
||||
319.0 , 865.0
|
||||
319.0 , 113.0
|
||||
785.0 , 113.0
|
||||
785.0 , 865.0
|
||||
startLeft = 319
|
||||
startUp = 113
|
||||
width = 467
|
||||
height = 753
|
||||
```
|
||||
输出图片效果如下:
|
||||
![ocr_result](https://aias-home.oss-cn-beijing.aliyuncs.com/AIAS/image_sdk/images/rotation.png)
|
||||
|
||||
|
||||
### 帮助
|
||||
引擎定制化配置,可以提升首次运行的引擎下载速度,解决外网无法访问或者带宽过低的问题。
|
||||
[引擎定制化配置](https://aias.top/engine_cpu.html)
|
||||
|
||||
### 官网:
|
||||
[官网链接](https://www.aias.top/)
|
||||
|
||||
### Git地址:
|
||||
[Github链接](https://github.com/mymagicpower/AIAS)
|
||||
[Gitee链接](https://gitee.com/mymagicpower/AIAS)
|
188
archive/1_image_sdks/image_kit/imagekit_java/image_sdk.iml
Normal file
188
archive/1_image_sdks/image_kit/imagekit_java/image_sdk.iml
Normal file
@ -0,0 +1,188 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="CheckStyle-IDEA-Module">
|
||||
<option name="configuration">
|
||||
<map />
|
||||
</option>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/java" isTestSource="true" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.30" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.12.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.12.1" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.logging.log4j:log4j-core:2.12.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacv-platform:1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacv:1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:0.200-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86_64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-arm64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-x86_64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86_64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-armhf:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-arm64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-ppc64le:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-x86_64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86_64:0.3.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv-platform:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86_64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-arm64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-x86_64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86_64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-armhf:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-arm64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-ppc64le:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:macosx-x86_64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86_64:4.1.2-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg-platform:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86_64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86_64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-armhf:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-arm64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-ppc64le:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:macosx-x86_64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86_64:4.2.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture-platform:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86_64:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-armhf:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-arm64:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86_64:2.13.3.31-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394-platform:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86_64:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-armhf:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-arm64:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-ppc64le:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:macosx-x86_64:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86_64:2.2.6-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect-platform:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86_64:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-armhf:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-arm64:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-ppc64le:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:macosx-x86_64:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86_64:0.5.7-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2-platform:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86_64:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:macosx-x86_64:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:windows-x86_64:0.2.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense-platform:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86_64:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:macosx-x86_64:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86_64:1.12.4-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2-platform:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-x86:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-x86_64:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:macosx-x86_64:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:windows-x86:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:windows-x86_64:2.29.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput-platform:0.200-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86:0.200-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86_64:0.200-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus-platform:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86_64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86_64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-armhf:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-arm64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-ppc64le:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:macosx-x86_64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86_64:2.3.1-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark-platform:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86_64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86_64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-armhf:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-arm64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-ppc64le:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:macosx-x86_64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86_64:1.07-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica-platform:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86_64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86_64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-armhf:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-arm64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-ppc64le:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:macosx-x86_64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86_64:1.78.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract-platform:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86_64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86_64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-armhf:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-arm64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-ppc64le:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:macosx-x86_64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86_64:4.1.0-1.5.2" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
|
||||
<orderEntry type="library" name="Maven: junit:junit:4.13.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
<orderEntry type="library" name="aais-image-lib-0.1.0" level="project" />
|
||||
</component>
|
||||
</module>
|
213
archive/1_image_sdks/image_kit/imagekit_java/imagekit_java.iml
Normal file
213
archive/1_image_sdks/image_kit/imagekit_java/imagekit_java.iml
Normal file
@ -0,0 +1,213 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module org.jetbrains.idea.maven.project.MavenProjectsManager.isMavenModule="true" type="JAVA_MODULE" version="4">
|
||||
<component name="CheckStyle-IDEA-Module">
|
||||
<option name="configuration">
|
||||
<map />
|
||||
</option>
|
||||
</component>
|
||||
<component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_8">
|
||||
<output url="file://$MODULE_DIR$/target/classes" />
|
||||
<output-test url="file://$MODULE_DIR$/target/test-classes" />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/java" isTestSource="false" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/main/resources" type="java-resource" />
|
||||
<sourceFolder url="file://$MODULE_DIR$/src/test/resources" type="java-test-resource" />
|
||||
<excludeFolder url="file://$MODULE_DIR$/target" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="Maven: com.google.code.gson:gson:2.8.6" level="project" />
|
||||
<orderEntry type="library" name="Maven: commons-cli:commons-cli:1.4" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-slf4j-impl:2.17.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.slf4j:slf4j-api:1.7.25" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.apache.logging.log4j:log4j-api:2.17.2" level="project" />
|
||||
<orderEntry type="library" scope="RUNTIME" name="Maven: org.apache.logging.log4j:log4j-core:2.17.2" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacv-platform:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacv:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:0.200-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-graphics:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.openjfx:javafx-base:mac:11" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas-platform:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp-platform:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-arm:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-arm64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-x86:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:android-x86_64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:ios-arm64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:ios-x86_64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:linux-armhf:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:linux-arm64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:linux-ppc64le:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:linux-x86:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:linux-x86_64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:macosx-arm64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:macosx-x86_64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:windows-x86:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:javacpp:windows-x86_64:1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-arm64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:android-x86_64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-arm64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:ios-x86_64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-x86_64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-armhf:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-arm64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:linux-ppc64le:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-arm64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:macosx-x86_64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:openblas:windows-x86_64:0.3.19-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv-platform:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-arm64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:android-x86_64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-arm64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:ios-x86_64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-x86_64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-armhf:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-arm64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:linux-ppc64le:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:macosx-arm64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:macosx-x86_64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:opencv:windows-x86_64:4.5.5-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg-platform:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-arm64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:android-x86_64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-x86_64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-armhf:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-arm64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:linux-ppc64le:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:macosx-arm64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:macosx-x86_64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:ffmpeg:windows-x86_64:5.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture-platform:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-x86_64:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-armhf:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:linux-arm64:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flycapture:windows-x86_64:2.13.3.31-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394-platform:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-x86_64:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-armhf:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-arm64:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:linux-ppc64le:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:macosx-x86_64:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libdc1394:windows-x86_64:2.2.6-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect-platform:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-x86_64:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-armhf:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-arm64:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:linux-ppc64le:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:macosx-x86_64:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect:windows-x86_64:0.5.7-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2-platform:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:linux-x86_64:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:macosx-x86_64:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:libfreenect2:windows-x86_64:0.2.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense-platform:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-armhf:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-arm64:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:linux-x86_64:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:macosx-x86_64:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense:windows-x86_64:1.12.4-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2-platform:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-armhf:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-arm64:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-x86:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:linux-x86_64:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:macosx-x86_64:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:windows-x86:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:librealsense2:windows-x86_64:2.50.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput-platform:0.200-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86:0.200-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:videoinput:windows-x86_64:0.200-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus-platform:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-arm64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:android-x86_64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-x86_64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-armhf:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-arm64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:linux-ppc64le:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:macosx-x86_64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:artoolkitplus:windows-x86_64:2.3.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark-platform:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-arm64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:android-x86_64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-x86_64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-armhf:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-arm64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:linux-ppc64le:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:macosx-x86_64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:flandmark:windows-x86_64:1.07-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica-platform:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-arm64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:android-x86_64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-x86_64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-armhf:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-arm64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:linux-ppc64le:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:macosx-x86_64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:leptonica:windows-x86_64:1.82.0-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract-platform:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-arm64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:android-x86_64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-x86_64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-armhf:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-arm64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:linux-ppc64le:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:macosx-x86_64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.bytedeco:tesseract:windows-x86_64:5.0.1-1.5.7" level="project" />
|
||||
<orderEntry type="library" scope="PROVIDED" name="Maven: org.projectlombok:lombok:1.18.18" level="project" />
|
||||
<orderEntry type="library" name="Maven: junit:junit:4.13.1" level="project" />
|
||||
<orderEntry type="library" name="Maven: org.hamcrest:hamcrest-core:1.3" level="project" />
|
||||
</component>
|
||||
</module>
|
83
archive/1_image_sdks/image_kit/imagekit_java/pom.xml
Normal file
83
archive/1_image_sdks/image_kit/imagekit_java/pom.xml
Normal file
@ -0,0 +1,83 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ Licensed to the Apache Software Foundation (ASF) under one
|
||||
~ or more contributor license agreements. See the NOTICE file
|
||||
~ distributed with this work for additional information
|
||||
~ regarding copyright ownership. The ASF licenses this file
|
||||
~ to you under the Apache License, Version 2.0 (the
|
||||
~ "License"); you may not use this file except in compliance
|
||||
~ with the License. You may obtain a copy of the License at
|
||||
~
|
||||
~ http://www.apache.org/licenses/LICENSE-2.0
|
||||
~
|
||||
~ Unless required by applicable law or agreed to in writing,
|
||||
~ software distributed under the License is distributed on an
|
||||
~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
~ KIND, either express or implied. See the License for the
|
||||
~ specific language governing permissions and limitations
|
||||
~ under the License.
|
||||
-->
|
||||
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<groupId>aias</groupId>
|
||||
<artifactId>image-sdk</artifactId>
|
||||
<version>0.17.0</version>
|
||||
|
||||
<properties>
|
||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||
<maven.compiler.source>1.8</maven.compiler.source>
|
||||
<maven.compiler.target>1.8</maven.compiler.target>
|
||||
</properties>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-compiler-plugin</artifactId>
|
||||
<configuration>
|
||||
<source>8</source>
|
||||
<target>8</target>
|
||||
</configuration>
|
||||
<version>3.8.1</version>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
<version>2.8.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.logging.log4j</groupId>
|
||||
<artifactId>log4j-slf4j-impl</artifactId>
|
||||
<version>2.17.2</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.bytedeco</groupId>
|
||||
<artifactId>javacv-platform</artifactId>
|
||||
<version>1.5.7</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<version>1.18.18</version>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.13.1</version>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
</project>
|
@ -0,0 +1,47 @@
|
||||
package me.aias;
|
||||
|
||||
import me.aias.util.BinaryUtils;
|
||||
import me.aias.util.GeneralUtils;
|
||||
import me.aias.util.GrayUtils;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.junit.Test;
|
||||
|
||||
public class TestBinaryUtils {
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试opencv自带的二值化
|
||||
* Test OpenCV's built-in binary method
|
||||
*/
|
||||
public void testBinaryNative(){
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/binary/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByAdapThreshold(src);
|
||||
|
||||
src = BinaryUtils.binaryNative(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "binaryNative.png");
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试自定义二值化
|
||||
* Test custom binary method
|
||||
*/
|
||||
public void testBinaryzation(){
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/binary/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByAdapThreshold(src);
|
||||
|
||||
src = BinaryUtils.binaryzation(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "binaryzation.png");
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,105 @@
|
||||
package me.aias;
|
||||
|
||||
import me.aias.util.GeneralUtils;
|
||||
import me.aias.util.GrayUtils;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.junit.Test;
|
||||
|
||||
|
||||
/**
|
||||
* 测试灰度化
|
||||
* Testing grayscale
|
||||
*/
|
||||
public class TestGrayUtils {
|
||||
@Test
|
||||
/**
|
||||
* 测试opencv自带的灰度化方法
|
||||
* Testing OpenCV's built-in grayscale method
|
||||
*/
|
||||
public void testGrayNative(){
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/gray/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayNative(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "grayNative.png");
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试细粒度灰度化方法
|
||||
* Testing fine-grained grayscale method
|
||||
* 均值灰度化减噪
|
||||
* Mean grayscale denoising
|
||||
*/
|
||||
public void testGrayColByMidle() {
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/gray/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByMidle(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "grayRowByMidle.png");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试细粒度灰度化方法
|
||||
* Testing fine-grained grayscale method
|
||||
* k值灰度化减噪
|
||||
* K-value grayscale denoising
|
||||
*/
|
||||
public void testGrayColByKLargest() {
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/gray/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByKLargest(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "grayRowByKLargest.png");
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试细粒度灰度化方法
|
||||
* Testing fine-grained grayscale method
|
||||
* 局部自适应阀值灰度化减噪
|
||||
* Local adaptive threshold grayscale denoising
|
||||
*/
|
||||
public void testGrayColByPartAdapThreshold() {
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/gray/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByPartAdapThreshold(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "grayColByPartAdapThreshold.png");
|
||||
}
|
||||
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试细粒度灰度化方法
|
||||
* Testing fine-grained grayscale method
|
||||
* 全局自适应阀值灰度化减噪
|
||||
* Global adaptive threshold grayscale denoising
|
||||
*/
|
||||
public void testGrayColByAdapThreshold() {
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/gray/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByAdapThreshold(src);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "grayColByAdapThreshold.png");
|
||||
}
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package me.aias;
|
||||
|
||||
import me.aias.util.BinaryUtils;
|
||||
import me.aias.util.GeneralUtils;
|
||||
import me.aias.util.GrayUtils;
|
||||
import me.aias.util.NoiseUtils;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.junit.Test;
|
||||
|
||||
/**
|
||||
* 测试降噪
|
||||
* Test denoising
|
||||
*/
|
||||
public class TestRemoveNoiseUtils {
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 测试8邻域降噪
|
||||
* Test 8-neighborhood denoising
|
||||
*/
|
||||
public void testNativeRemoveNoise(){
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/noise/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByPartAdapThreshold(src);
|
||||
|
||||
src = BinaryUtils.binaryzation(src);
|
||||
|
||||
// 8邻域降噪
|
||||
// 8-neighborhood denoising
|
||||
src = NoiseUtils.navieRemoveNoise(src , 1);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "nativeRemoveNoise.png");
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
/**
|
||||
* 连通域降噪
|
||||
* Connected domain denoising
|
||||
*/
|
||||
public void testConnectedRemoveNoise(){
|
||||
String imgPath = "src/test/resources/1.png";
|
||||
String destPath = "build/output/noise/";
|
||||
|
||||
Mat src = GeneralUtils.matFactory(imgPath);
|
||||
|
||||
src = GrayUtils.grayColByPartAdapThreshold(src);
|
||||
|
||||
src = BinaryUtils.binaryzation(src);
|
||||
|
||||
// 连通域降噪 - Connected domain denoising
|
||||
src = NoiseUtils.connectedRemoveNoise(src , 1);
|
||||
|
||||
GeneralUtils.saveImg(src , destPath + "connectedRemoveNoise.png");
|
||||
|
||||
}
|
||||
}
|
@ -0,0 +1,62 @@
|
||||
package me.aias;
|
||||
|
||||
import me.aias.util.*;
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.stream.LongStream;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.*;
|
||||
import static org.bytedeco.opencv.helper.opencv_imgcodecs.cvLoadImage;
|
||||
|
||||
public class TestRotation {
|
||||
|
||||
public static void main(String[] args) throws IOException {
|
||||
IplImage marcel_ = cvLoadImage("src/test/resources/ticket_r2.png");
|
||||
Mat marcel = new Mat(marcel_);
|
||||
|
||||
GeneralUtils.saveImg(marcel, "build/output/srcImg.jpg");
|
||||
|
||||
// 边缘检测
|
||||
// Edge detection
|
||||
Mat cannyMat = GeneralUtils.canny(marcel);
|
||||
GeneralUtils.saveImg(cannyMat, "build/output/canny.jpg");
|
||||
|
||||
// 获取所有轮廓
|
||||
// Get all the contours
|
||||
MatVector contours = ContourUtils.getContours(cannyMat);
|
||||
|
||||
Mat resultImage = cannyMat.clone();
|
||||
LongStream.range(0, contours.size())
|
||||
.mapToObj(contours::get)
|
||||
.forEach(
|
||||
contour -> {
|
||||
Mat points = new Mat();
|
||||
approxPolyDP(contour, points, arcLength(contour, true) * 0.02, true);
|
||||
drawContours(resultImage, new MatVector(points), -1, Scalar.BLUE);
|
||||
});
|
||||
GeneralUtils.saveImg(resultImage, "build/output/contours.jpg");
|
||||
|
||||
// 获取最大外接矩形
|
||||
// Get the maximum bounding rectangle
|
||||
RotatedRect rect = RectUtils.getMaxRect(contours);
|
||||
Mat rectMat = marcel.clone();
|
||||
Scalar scalar = new Scalar(255, 0, 0, 1);
|
||||
Rect r = rect.boundingRect();
|
||||
rectMat = DrawUtils.drawRect(rectMat, r, scalar);
|
||||
GeneralUtils.saveImg(rectMat, "build/output/maxRect.jpg");
|
||||
|
||||
// 旋转矩形
|
||||
// Rotate the rectangle
|
||||
Mat rotatedImg = RotationUtils.rotation(cannyMat, rect);
|
||||
GeneralUtils.saveImg(rotatedImg, "build/output/rotatedImg.jpg");
|
||||
|
||||
Mat nativeRotatedImg = RotationUtils.rotation(marcel, rect);
|
||||
GeneralUtils.saveImg(nativeRotatedImg, "build/output/nativeRotatedImg.jpg");
|
||||
|
||||
// 裁剪矩形
|
||||
// Crop the rectangle
|
||||
Mat cutMat = RectUtils.cutRect(rotatedImg, nativeRotatedImg);
|
||||
GeneralUtils.saveImg(cutMat, "build/output/cutRect.jpg");
|
||||
}
|
||||
}
|
@ -0,0 +1,198 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
/**
|
||||
* 二值化的工具类
|
||||
*/
|
||||
public class BinaryUtils {
|
||||
|
||||
/**
|
||||
* opencv自带的二值化
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat binaryNative(Mat src){
|
||||
Mat dst = src.clone();
|
||||
opencv_imgproc.adaptiveThreshold(src, dst, 255, opencv_imgproc.ADAPTIVE_THRESH_MEAN_C, opencv_imgproc.THRESH_BINARY, 25, 10);
|
||||
return dst;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 图像二值化 阀值自适应确定
|
||||
*
|
||||
* @param src
|
||||
* Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static Mat binaryzation(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
throw new RuntimeException("不是单通道图,需要先灰度话!!!");
|
||||
}
|
||||
int threshold = getAdapThreshold(src);
|
||||
return binaryzation(src, threshold);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 图像二值化
|
||||
*
|
||||
* @param src
|
||||
* Mat矩阵图像
|
||||
* @param b
|
||||
* [true/false] true:表示白底黑字,false表示黑底白字
|
||||
* @return
|
||||
*/
|
||||
public static Mat binaryzation(Mat src, boolean b) {
|
||||
if (src.channels() != 1) {
|
||||
throw new RuntimeException("不是单通道图,需要先灰度话!!!");
|
||||
}
|
||||
int threshold = getAdapThreshold(src);
|
||||
return binaryzation(src, threshold, b);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图像二值化
|
||||
*
|
||||
* @param src
|
||||
* Mat矩阵图像
|
||||
* @param threshold
|
||||
* 阀值
|
||||
* @return
|
||||
*/
|
||||
public static Mat binaryzation(Mat src, int threshold) {
|
||||
if (src.channels() != 1) {
|
||||
throw new RuntimeException("不是单通道图,需要先灰度化");
|
||||
}
|
||||
return binaryzation(src, threshold, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 图像二值化
|
||||
*
|
||||
* @param src
|
||||
* Mat矩阵图像
|
||||
* @param threshold
|
||||
* 阀值
|
||||
* @param b
|
||||
* [true/false] true:表示白底黑字,false表示黑底白字
|
||||
* @return
|
||||
*/
|
||||
public static Mat binaryzation(Mat src, int threshold, boolean b) {
|
||||
if (src.channels() != 1 || threshold < 0) {
|
||||
System.out.println("不是单通道图像或者阀值异常");
|
||||
return src;
|
||||
}
|
||||
int nWhite_sum = 0, nBlack_sum = 0;
|
||||
int i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int value;
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value > threshold) {
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getWHITE());
|
||||
nWhite_sum++;
|
||||
} else {
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getBLACK());
|
||||
nBlack_sum++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b) {
|
||||
// 白底黑字
|
||||
if (nBlack_sum > nWhite_sum) {
|
||||
src = GeneralUtils.turnPixel(src);
|
||||
}
|
||||
} else {
|
||||
// 黑底白字
|
||||
if (nWhite_sum > nBlack_sum) {
|
||||
src = GeneralUtils.turnPixel(src);
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:自适应选取阀值
|
||||
*
|
||||
* @param src
|
||||
* Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static int getAdapThreshold(Mat src) {
|
||||
int threshold = 0, threshold_new = 127;
|
||||
int nWhite_count, nBlack_count;
|
||||
int nWhite_sum, nBlack_sum;
|
||||
int value, i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
if(width == 0 || height == 0){
|
||||
System.out.println("图像加载异常");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (threshold != threshold_new) {
|
||||
nWhite_sum = nBlack_sum = 0;
|
||||
nWhite_count = nBlack_count = 0;
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value > threshold_new) {
|
||||
nWhite_count++;
|
||||
nWhite_sum += value;
|
||||
} else {
|
||||
nBlack_count++;
|
||||
nBlack_sum += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
threshold = threshold_new;
|
||||
if(nWhite_count == 0 || nBlack_count == 0){
|
||||
threshold_new = (nWhite_sum + nBlack_sum) / (nWhite_count + nBlack_count);
|
||||
}else{
|
||||
threshold_new = (nWhite_sum / nWhite_count + nBlack_sum / nBlack_count) / 2;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 局部自适应二值化
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat partBinaryzation(Mat src){
|
||||
int width = GeneralUtils.getImgWidth(src);
|
||||
int height = GeneralUtils.getImgHeight(src);
|
||||
int value;
|
||||
for(int i = 0 ; i < width ; i++){
|
||||
Mat partMat = src.col(i);
|
||||
int thresold = getAdapThreshold(partMat);
|
||||
int black_num = 0 , white_num = 0;
|
||||
|
||||
|
||||
for(int j = 0 ; j < height ; j++){
|
||||
value = GeneralUtils.getPixel(src , j , i);
|
||||
if(value > thresold){
|
||||
GeneralUtils.setPixel(src , j , i , GeneralUtils.getWHITE());
|
||||
white_num++;
|
||||
}else{
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getBLACK());
|
||||
black_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,112 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.MatVector;
|
||||
import org.bytedeco.opencv.opencv_core.Point;
|
||||
import org.bytedeco.opencv.opencv_core.RotatedRect;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.*;
|
||||
|
||||
/** 轮廓工具类 */
|
||||
public class ContourUtils {
|
||||
|
||||
/**
|
||||
* 寻找轮廓
|
||||
*
|
||||
* @param cannyMat
|
||||
* @return
|
||||
*/
|
||||
public static MatVector getContours(Mat cannyMat) {
|
||||
MatVector contours = new MatVector();
|
||||
Mat hierarchy = new Mat();
|
||||
|
||||
// 寻找轮廓
|
||||
// CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE
|
||||
// CV_RETR_TREE
|
||||
findContours(
|
||||
cannyMat,
|
||||
contours,
|
||||
hierarchy,
|
||||
opencv_imgproc.RETR_LIST,
|
||||
opencv_imgproc.CHAIN_APPROX_SIMPLE,
|
||||
new Point(0, 0));
|
||||
|
||||
if (contours.size() <= 0) {
|
||||
throw new RuntimeException("未找到图像轮廓");
|
||||
} else {
|
||||
return contours;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:返回边缘检测之后的最大轮廓
|
||||
*
|
||||
* @param contours
|
||||
* @return
|
||||
*/
|
||||
public static Mat getMaxContour(MatVector contours) {
|
||||
// 找出匹配到的最大轮廓
|
||||
double area = boundingRect(contours.get(0)).area();
|
||||
int index = 0;
|
||||
|
||||
// 找出匹配到的最大轮廓
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
double tempArea = boundingRect(contours.get(i)).area();
|
||||
if (tempArea > area) {
|
||||
area = tempArea;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return contours.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:返回边缘检测之后的最大轮廓
|
||||
*
|
||||
* @param cannyMat Canny之后的Mat矩阵
|
||||
* @return
|
||||
*/
|
||||
public static Mat getMaxContour(Mat cannyMat) {
|
||||
MatVector contours = getContours(cannyMat);
|
||||
// 找出匹配到的最大轮廓
|
||||
double area = boundingRect(contours.get(0)).area();
|
||||
int index = 0;
|
||||
|
||||
// 找出匹配到的最大轮廓
|
||||
for (int i = 0; i < contours.size(); i++) {
|
||||
double tempArea = boundingRect(contours.get(i)).area();
|
||||
if (tempArea > area) {
|
||||
area = tempArea;
|
||||
index = i;
|
||||
}
|
||||
}
|
||||
return contours.get(index);
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用函数approxPolyDP来对指定的点集进行逼近 精确度设置好,效果还是比较好的
|
||||
*
|
||||
* @param cannyMat
|
||||
*/
|
||||
public static Mat useApproxPolyDPFindPoints(Mat cannyMat) {
|
||||
return useApproxPolyDPFindPoints(cannyMat, 0.01);
|
||||
}
|
||||
|
||||
/**
|
||||
* 利用函数approxPolyDP来对指定的点集进行逼近 精确度设置好,效果还是比较好的
|
||||
*
|
||||
* @param cannyMat
|
||||
* @param threshold 阀值(精确度)
|
||||
* @return
|
||||
*/
|
||||
public static Mat useApproxPolyDPFindPoints(Mat cannyMat, double threshold) {
|
||||
|
||||
Mat maxContour = getMaxContour(cannyMat);
|
||||
Mat approxCurve = new Mat();
|
||||
|
||||
// 原始曲线与近似曲线之间的最大距离设置为0.01,true表示是闭合的曲线
|
||||
opencv_imgproc.approxPolyDP(maxContour, approxCurve, threshold, true);
|
||||
return approxCurve;
|
||||
}
|
||||
}
|
@ -0,0 +1,104 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.minAreaRect;
|
||||
|
||||
/** 画图工具类 */
|
||||
public class DrawUtils {
|
||||
/**
|
||||
* 画出所有的矩形
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat drawContours(Mat src, String filePath) {
|
||||
Mat cannyMat = GeneralUtils.canny(src);
|
||||
MatVector contours = ContourUtils.getContours(cannyMat);
|
||||
|
||||
Mat rectMat = src.clone();
|
||||
Scalar scalar = new Scalar(255, 0, 0, 1);
|
||||
|
||||
for (long i = contours.size() - 1; i >= 0; i--) {
|
||||
Mat mat = contours.get(i);
|
||||
RotatedRect rect = minAreaRect(mat);
|
||||
|
||||
Rect r = rect.boundingRect();
|
||||
|
||||
System.out.println(r.area() + " --- " + i);
|
||||
|
||||
rectMat = drawRect(rectMat, r, scalar);
|
||||
}
|
||||
|
||||
GeneralUtils.saveImg(rectMat, filePath);
|
||||
return rectMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* 画出最大的矩形
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static void drawMaxRect(Mat src, String filePath) {
|
||||
Mat cannyMat = GeneralUtils.canny(src);
|
||||
|
||||
RotatedRect rect = RectUtils.getMaxRect(cannyMat);
|
||||
|
||||
Rect r = rect.boundingRect();
|
||||
|
||||
Mat rectMat = src.clone();
|
||||
Scalar scalar = new Scalar(255, 0, 0, 1);
|
||||
|
||||
rectMat = drawRect(rectMat, r, scalar);
|
||||
|
||||
GeneralUtils.saveImg(rectMat, filePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 画矩形
|
||||
*
|
||||
* @param src
|
||||
* @param r
|
||||
* @param scalar
|
||||
* @return
|
||||
*/
|
||||
public static Mat drawRect(Mat src, Rect r, Scalar scalar) {
|
||||
Point pt1 = new Point(r.x(), r.y());
|
||||
Point pt2 = new Point(r.x() + r.width(), r.y());
|
||||
Point pt3 = new Point(r.x() + r.width(), r.y() + r.height());
|
||||
Point pt4 = new Point(r.x(), r.y() + r.height());
|
||||
|
||||
opencv_imgproc.line(src, pt1, pt2, scalar);
|
||||
opencv_imgproc.line(src, pt2, pt3, scalar);
|
||||
opencv_imgproc.line(src, pt3, pt4, scalar);
|
||||
opencv_imgproc.line(src, pt4, pt1, scalar);
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 画实心圆
|
||||
*
|
||||
* @param src
|
||||
* @param point 点
|
||||
* @param size 点的尺寸
|
||||
* @param scalar 颜色
|
||||
* @param path 保存路径
|
||||
*/
|
||||
public static boolean drawCircle(Mat src, Point[] point, int size, Scalar scalar, String path) {
|
||||
if (src == null || point == null) {
|
||||
throw new RuntimeException("Mat 或者 Point 数组不能为NULL");
|
||||
}
|
||||
for (Point p : point) {
|
||||
opencv_imgproc.circle(src, p, size, scalar);
|
||||
}
|
||||
|
||||
if (path != null && !"".equals(path)) {
|
||||
return GeneralUtils.saveImg(src, path);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
@ -0,0 +1,201 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.javacpp.indexer.UByteRawIndexer;
|
||||
import org.bytedeco.opencv.global.opencv_imgcodecs;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Size;
|
||||
|
||||
/** opencv的一些通用方法工具类 */
|
||||
public class GeneralUtils {
|
||||
|
||||
private static final int BLACK = 0;
|
||||
private static final int WHITE = 255;
|
||||
|
||||
// 设置归一化图像的固定大小
|
||||
private static final Size dsize = new Size(32, 32);
|
||||
|
||||
/**
|
||||
* 作用:输入图像路径,返回mat矩阵
|
||||
*
|
||||
* @param imgPath 图像路径
|
||||
* @return
|
||||
*/
|
||||
public static Mat matFactory(String imgPath) {
|
||||
return opencv_imgcodecs.imread(imgPath);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:输入图像Mat矩阵对象,返回图像的宽度
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static int getImgWidth(Mat src) {
|
||||
return src.cols();
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:输入图像Mat矩阵,返回图像的高度
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static int getImgHeight(Mat src) {
|
||||
return src.rows();
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:获取图像(y,x)点的像素,我们只针对单通道(灰度图)
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @param y y坐标轴
|
||||
* @param x x坐标轴
|
||||
* @return
|
||||
*/
|
||||
public static int getPixel(Mat src, int y, int x) {
|
||||
UByteRawIndexer ldIdx = src.createIndexer();
|
||||
int result = ldIdx.get(y, x);
|
||||
ldIdx.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:设置图像(y,x)点的像素,我们只针对单通道(灰度图)
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @param y y坐标轴 row
|
||||
* @param x x坐标轴 col
|
||||
* @param color 颜色值[0-255]
|
||||
*/
|
||||
public static void setPixel(Mat src, int y, int x, int color) {
|
||||
UByteRawIndexer ldIdx = src.createIndexer();
|
||||
ldIdx.put(y, x, color);
|
||||
ldIdx.release();
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:保存图像
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @param filePath 要保存图像的路径及名字
|
||||
* @return
|
||||
*/
|
||||
public static boolean saveImg(Mat src, String filePath) {
|
||||
return opencv_imgcodecs.imwrite(filePath, src);
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:翻转图像像素
|
||||
* 确保白底黑字或者黑底白字
|
||||
*
|
||||
* @param src
|
||||
* @param b true:表示白底黑字 , false相反
|
||||
* @return
|
||||
*/
|
||||
public static Mat turnPixel(Mat src, boolean b) {
|
||||
if (src != null) {
|
||||
int width = GeneralUtils.getImgWidth(src);
|
||||
int height = GeneralUtils.getImgHeight(src);
|
||||
int value;
|
||||
int black_num = 0;
|
||||
int white_num = 0;
|
||||
int i, j;
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value == GeneralUtils.getWHITE()) {
|
||||
white_num++;
|
||||
} else if (value == GeneralUtils.getBLACK()) {
|
||||
black_num++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (b && black_num > white_num) {
|
||||
// 反转
|
||||
src = turnPixel(src);
|
||||
} else if (!b && white_num > black_num) {
|
||||
// 反转
|
||||
src = turnPixel(src);
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:翻转图像像素
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static Mat turnPixel(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
throw new RuntimeException("不是单通道图,需要先灰度化");
|
||||
}
|
||||
int j, i, value;
|
||||
int width = getImgWidth(src), height = getImgHeight(src);
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
value = getPixel(src, j, i);
|
||||
if (value == 0) {
|
||||
setPixel(src, j, i, WHITE);
|
||||
} else {
|
||||
setPixel(src, j, i, BLACK);
|
||||
}
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/** 图像腐蚀/膨胀处理 腐蚀和膨胀对处理没有噪声的图像很有利,慎用 */
|
||||
public static Mat erodeDilateImg(Mat src) {
|
||||
Mat outImage = new Mat();
|
||||
|
||||
// size 越小,腐蚀的单位越小,图片越接近原图
|
||||
Mat structImage =
|
||||
opencv_imgproc.getStructuringElement(opencv_imgproc.MORPH_RECT, new Size(2, 2));
|
||||
|
||||
/**
|
||||
* 图像腐蚀 腐蚀说明: 图像的一部分区域与指定的核进行卷积, 求核的最`小`值并赋值给指定区域。 腐蚀可以理解为图像中`高亮区域`的'领域缩小'。
|
||||
* 意思是高亮部分会被不是高亮部分的像素侵蚀掉,使高亮部分越来越少。
|
||||
*/
|
||||
opencv_imgproc.erode(src, outImage, structImage);
|
||||
// opencv_imgproc.erode(src, outImage, structImage, new Point(-1, -1), 2);
|
||||
src = outImage;
|
||||
|
||||
/**
|
||||
* 膨胀 膨胀说明: 图像的一部分区域与指定的核进行卷积, 求核的最`大`值并赋值给指定区域。 膨胀可以理解为图像中`高亮区域`的'领域扩大'。
|
||||
* 意思是高亮部分会侵蚀不是高亮的部分,使高亮部分越来越多。
|
||||
*/
|
||||
opencv_imgproc.dilate(src, outImage, structImage);
|
||||
// opencv_imgproc.dilate(src, outImage, structImage, new Point(-1, -1), 2);
|
||||
src = outImage;
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* canny算法,边缘检测
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat canny(Mat src) {
|
||||
Mat mat = src.clone();
|
||||
opencv_imgproc.Canny(src, mat, 60, 200);
|
||||
return mat;
|
||||
}
|
||||
|
||||
public static int getBLACK() {
|
||||
return BLACK;
|
||||
}
|
||||
|
||||
public static int getWHITE() {
|
||||
return WHITE;
|
||||
}
|
||||
|
||||
public static Size getDsize() {
|
||||
return dsize;
|
||||
}
|
||||
}
|
@ -0,0 +1,266 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.javacpp.indexer.UByteRawIndexer;
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
/** 对图像灰度化处理的工具类 默认有效数据的灰度值小于底色,即有效数据更清晰 */
|
||||
public class GrayUtils {
|
||||
/**
|
||||
* 作用:灰度化
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayNative(Mat src) {
|
||||
Mat gray = src.clone();
|
||||
if (src.channels() == 3) {
|
||||
// 进行灰度化
|
||||
opencv_imgproc.cvtColor(src, gray, opencv_imgproc.COLOR_BGR2GRAY);
|
||||
src = gray;
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 均值灰度化减噪 细粒度灰度化,只降低噪声,不对有效数据做任何的加强的处理 根据灰度化后的图像每一列的像素值的平均值(默认)或者其他表达式值作为阀值,把大于阀值的像素都改为255
|
||||
* 可以在一定程度上降低噪声,而不对有效数据造成任何影响
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByMidle(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
List<List<Double>> data = MathUtils.MatPixelToList(src);
|
||||
return grayColByMidle(src, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据灰度化后的图像每一列的像素值的平均值作为阀值,把大于阀值的像素都改为255
|
||||
*
|
||||
* @param data List<Double>中存储图像灰度化后的每一列的像素值
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByMidle(Mat src, List<List<Double>> data) {
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
UByteRawIndexer ldIdx = src.createIndexer();
|
||||
// IntRawIndexer ldIdx = src.createIndexer();
|
||||
|
||||
for (int j = 0; j < data.size(); j++) {
|
||||
List<Double> list = data.get(j);
|
||||
|
||||
int avg = (int) ((MathUtils.getSumInList(list) / list.size()) * 0.95);
|
||||
|
||||
// 随机的更新像素值
|
||||
int count = 3 * list.size() / 4;
|
||||
int time = 0;
|
||||
while (count > 0) {
|
||||
|
||||
int index = new Random().nextInt(list.size());
|
||||
|
||||
if (list.get(index) >= avg) {
|
||||
ldIdx.put(index, j, 255);
|
||||
count--;
|
||||
}
|
||||
|
||||
if (count == count) {
|
||||
time++;
|
||||
}
|
||||
// 避免程序进入死循环
|
||||
if (time == list.size() / 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ldIdx.release();
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* k值灰度化减噪 根据灰度化后的图像每一列的像素值的第k大值作为阀值,把大于阀值的像素都改为255 默认选取第1/3大的值作为阀值
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByKLargest(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
List<List<Double>> data = MathUtils.MatPixelToList(src);
|
||||
return grayColByKLargest(src, 3, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据灰度化后的图像每一列的像素值的第k大值作为阀值,把大于阀值的像素都改为255
|
||||
*
|
||||
* @param src
|
||||
* @param k 分母
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByKLargest(Mat src, int k) {
|
||||
if (k == 0) {
|
||||
throw new RuntimeException("k不能为0");
|
||||
}
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
List<List<Double>> data = MathUtils.MatPixelToList(src);
|
||||
return grayColByKLargest(src, k, data);
|
||||
}
|
||||
|
||||
/**
|
||||
* 根据灰度化后的图像每一列的像素值的第k大值作为阀值,把大于阀值的像素都改为255
|
||||
*
|
||||
* @param src
|
||||
* @param k
|
||||
* @param data
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByKLargest(Mat src, int k, List<List<Double>> data) {
|
||||
if (k == 0) {
|
||||
throw new RuntimeException("k不能为0");
|
||||
}
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
UByteRawIndexer ldIdx = src.createIndexer();
|
||||
// IntRawIndexer ldIdx = src.createIndexer();
|
||||
|
||||
for (int j = 0; j < data.size(); j++) {
|
||||
List<Double> list = data.get(j);
|
||||
Object[] doubles = list.toArray();
|
||||
Double[] doubles1 = new Double[doubles.length];
|
||||
for (int i = 0; i < doubles.length; i++) {
|
||||
doubles1[i] = (Double) doubles[i];
|
||||
}
|
||||
double d = MathUtils.findKthLargest(doubles1, list.size() / k);
|
||||
|
||||
// 随机的更新像素值
|
||||
int count = 3 * doubles.length / 4;
|
||||
int time = 0;
|
||||
while (count > 0) {
|
||||
|
||||
int index = new Random().nextInt(list.size());
|
||||
|
||||
if (list.get(index) >= d) {
|
||||
ldIdx.put(index, j, 255);
|
||||
count--;
|
||||
}
|
||||
|
||||
if (count == count) {
|
||||
time++;
|
||||
}
|
||||
// 避免程序进入死循环
|
||||
if (time == list.size() / 2) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ldIdx.release();
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 作用:自适应选取阀值
|
||||
*
|
||||
* @param src Mat矩阵图像
|
||||
* @return
|
||||
*/
|
||||
public static int getAdapThreshold(Mat src) {
|
||||
int threshold = 0, threshold_new = 127;
|
||||
int nWhite_count, nBlack_count;
|
||||
int nWhite_sum, nBlack_sum;
|
||||
int value, i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
if (width == 0 || height == 0) {
|
||||
System.out.println("图像加载异常");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (threshold != threshold_new) {
|
||||
nWhite_sum = nBlack_sum = 0;
|
||||
nWhite_count = nBlack_count = 0;
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value > threshold_new) {
|
||||
nWhite_count++;
|
||||
nWhite_sum += value;
|
||||
} else {
|
||||
nBlack_count++;
|
||||
nBlack_sum += value;
|
||||
}
|
||||
}
|
||||
}
|
||||
threshold = threshold_new;
|
||||
if (nWhite_count == 0 || nBlack_count == 0) {
|
||||
threshold_new = (nWhite_sum + nBlack_sum) / (nWhite_count + nBlack_count);
|
||||
} else {
|
||||
threshold_new = (nWhite_sum / nWhite_count + nBlack_sum / nBlack_count) / 2;
|
||||
}
|
||||
}
|
||||
|
||||
return threshold;
|
||||
}
|
||||
|
||||
/**
|
||||
* 局部自适应阀值灰度化降噪
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByPartAdapThreshold(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
int width = GeneralUtils.getImgWidth(src);
|
||||
int height = GeneralUtils.getImgHeight(src);
|
||||
int value;
|
||||
for (int i = 0; i < width; i++) {
|
||||
Mat partMat = src.col(i);
|
||||
int thresold = getAdapThreshold(partMat);
|
||||
for (int j = 0; j < height; j++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value > thresold) {
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getWHITE());
|
||||
}
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 全局自适应阀值灰度化降噪
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat grayColByAdapThreshold(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
src = grayNative(src);
|
||||
}
|
||||
int i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int value;
|
||||
|
||||
int threshold = getAdapThreshold(src);
|
||||
for (j = 0; j < height; j++) {
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value > threshold) {
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getWHITE());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
}
|
@ -0,0 +1,89 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.javacv.Java2DFrameConverter;
|
||||
import org.bytedeco.javacv.OpenCVFrameConverter;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.DataBufferByte;
|
||||
|
||||
/**
|
||||
* 图片类型转换
|
||||
*
|
||||
* @author Calvin
|
||||
*/
|
||||
public class ImageUtils {
|
||||
|
||||
/**
|
||||
* 将 BufferedImage 转 Mat
|
||||
*
|
||||
* @param original
|
||||
*/
|
||||
public static Mat bufferedImage2Mat(BufferedImage original) {
|
||||
OpenCVFrameConverter.ToMat cv = new OpenCVFrameConverter.ToMat();
|
||||
return cv.convertToMat(new Java2DFrameConverter().convert(original));
|
||||
}
|
||||
|
||||
/**
|
||||
* 将mat转BufferedImage
|
||||
*
|
||||
* @param matrix
|
||||
*/
|
||||
public static BufferedImage mat2BufferedImage(Mat matrix) {
|
||||
int cols = matrix.cols();
|
||||
int rows = matrix.rows();
|
||||
int elemSize = (int) matrix.elemSize();
|
||||
byte[] data = new byte[cols * rows * elemSize];
|
||||
|
||||
matrix.data().get(data);
|
||||
|
||||
int type = 0;
|
||||
switch (matrix.channels()) {
|
||||
case 1:
|
||||
type = BufferedImage.TYPE_BYTE_GRAY;
|
||||
break;
|
||||
case 3:
|
||||
type = BufferedImage.TYPE_3BYTE_BGR;
|
||||
byte b;
|
||||
for (int i = 0; i < data.length; i = i + 3) {
|
||||
b = data[i];
|
||||
data[i] = data[i + 2];
|
||||
data[i + 2] = b;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
BufferedImage image = new BufferedImage(cols, rows, type);
|
||||
// BufferedImage对象中最重要的两个组件为Raster和ColorModel,分别用于存储图像的像素数据与颜色数据。
|
||||
// 表示像素矩形数组的类。Raster 封装存储样本值的 DataBuffer,以及描述如何在 DataBuffer 中定位给定样本值的 SampleModel。
|
||||
// 由于Raster对象是BufferedImage对象中的像素数据存储对象,因此,BufferedImage支持从Raster对象中获取任意位置(x,y)点的像素值p(x,y)。
|
||||
image.getRaster().setDataElements(0, 0, cols, rows, data);
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* 将bufferImage转Mat
|
||||
*
|
||||
* @param original
|
||||
* @param matType
|
||||
* @param msg
|
||||
* @param x
|
||||
* @param y
|
||||
*/
|
||||
public static Mat bufferedImage2Mat(
|
||||
BufferedImage original, int matType, String msg, int x, int y) {
|
||||
Graphics2D g = original.createGraphics();
|
||||
try {
|
||||
g.setComposite(AlphaComposite.Src);
|
||||
g.drawImage(original, 0, 0, null);
|
||||
g.drawString(msg, x, y);
|
||||
} finally {
|
||||
g.dispose();
|
||||
}
|
||||
Mat mat = new Mat(original.getHeight(), original.getWidth(), matType);
|
||||
mat.data().put(((DataBufferByte) original.getRaster().getDataBuffer()).getData());
|
||||
return mat;
|
||||
}
|
||||
}
|
@ -0,0 +1,374 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.javacpp.indexer.DoubleRawIndexer;
|
||||
import org.bytedeco.javacpp.indexer.UByteRawIndexer;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 一些数学计算工具类
|
||||
*/
|
||||
public class MathUtils {
|
||||
|
||||
/**
|
||||
* 把opencv的灰度图Mat转化为List<List<Double>> , 即数组对象
|
||||
* List<Double>是每一列的灰度值
|
||||
* @param gray
|
||||
* @return
|
||||
*/
|
||||
public static List<List<Double>> MatPixelToList(Mat gray){
|
||||
if(gray == null){
|
||||
throw new RuntimeException("不能传入空对象");
|
||||
}
|
||||
return MatPixelToList(gray , true);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把opencv的灰度图Mat转化为List<List<Double>> , 即数组对象
|
||||
* @param gray
|
||||
* @param b true 表示List<Double>是每一列的灰度值,否则List<Double>是每一行的灰度值
|
||||
* @return
|
||||
*/
|
||||
public static List<List<Double>> MatPixelToList(Mat gray , boolean b){
|
||||
if(gray == null){
|
||||
throw new RuntimeException("不能传入空对象");
|
||||
}
|
||||
List<List<Double>> result = new ArrayList<>();
|
||||
int x , y;
|
||||
int i , j;
|
||||
double value;
|
||||
if(b){
|
||||
//List<Double>是每一列的灰度值
|
||||
x = gray.cols();
|
||||
y = gray.rows();
|
||||
}else{
|
||||
//List<Double>是每一行的灰度值
|
||||
x = gray.rows();
|
||||
y = gray.cols();
|
||||
}
|
||||
|
||||
UByteRawIndexer ldIdx = gray.createIndexer();
|
||||
for(i = 0 ; i < x ; i++){
|
||||
List<Double> oneLine = new ArrayList<>();
|
||||
for(j = 0 ; j < y ; j++){
|
||||
if(b){
|
||||
value = ldIdx.get(j, i);
|
||||
}else{
|
||||
value = ldIdx.get(i , j);
|
||||
}
|
||||
|
||||
oneLine.add(value);
|
||||
}
|
||||
result.add(oneLine);
|
||||
}
|
||||
ldIdx.release();
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回Mat每一列的平均值
|
||||
* @param grayMat
|
||||
* @return
|
||||
*/
|
||||
public static List<Double> avgColMat(Mat grayMat){
|
||||
List<List<Double>> data = MatPixelToList(grayMat);
|
||||
|
||||
List<Double> result = new ArrayList<>();
|
||||
|
||||
for(List<Double> col : data) {
|
||||
double sum = getSumInList(col);
|
||||
result.add(sum / col.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 返回Mat每一行的平均值
|
||||
* @param grayMat
|
||||
* @return
|
||||
*/
|
||||
public static List<Double> avgRowMat(Mat grayMat){
|
||||
List<List<Double>> data = MatPixelToList(grayMat , false);
|
||||
|
||||
List<Double> result = new ArrayList<>();
|
||||
|
||||
for(List<Double> row : data) {
|
||||
double sum = getSumInList(row);
|
||||
result.add(sum / row.size());
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* 返回list集合中最大的那个数
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static double getMaxInList(List<Double> list){
|
||||
if(list == null){
|
||||
throw new RuntimeException("不能传入空对象");
|
||||
}
|
||||
double max = list.get(0);
|
||||
for(double d : list){
|
||||
if(d > max){
|
||||
max = d;
|
||||
}
|
||||
}
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回list集合中最大的那个数
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static double getMinInList(List<Double> list){
|
||||
if(list == null){
|
||||
throw new RuntimeException("不能传入空对象");
|
||||
}
|
||||
double min = list.get(0);
|
||||
for(double d : list){
|
||||
if(d < min){
|
||||
min = d;
|
||||
}
|
||||
}
|
||||
return min;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回list集合中总和
|
||||
* @param list
|
||||
* @return
|
||||
*/
|
||||
public static double getSumInList(List<Double> list){
|
||||
if(list == null){
|
||||
throw new RuntimeException("不能传入空对象");
|
||||
}
|
||||
double sum = 0;
|
||||
for(double d : list){
|
||||
sum += d;
|
||||
}
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找第k大的元素,快速排序实现
|
||||
* @param nums
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public static double findKthLargest(List<Double> nums , int k){
|
||||
int len = nums.size();
|
||||
Double[] doubles1 = new Double[len];
|
||||
for(int i = 0 ; i < len ; i++){
|
||||
doubles1[i] = (Double)nums.get(i);
|
||||
}
|
||||
|
||||
return findKthLargest(doubles1 , k);
|
||||
}
|
||||
|
||||
/**
|
||||
* 寻找第k大的元素,快速排序实现
|
||||
* @param nums
|
||||
* @param k
|
||||
* @return
|
||||
*/
|
||||
public static double findKthLargest(Double[] nums, int k) {
|
||||
if (k < 1 || nums == null || k > nums.length) {
|
||||
return -1;
|
||||
}
|
||||
return getKth(nums.length - k + 1, nums, 0, nums.length - 1);
|
||||
}
|
||||
|
||||
public static double getKth(int k, Double[] nums, int start, int end) {
|
||||
double pivot = nums[end];
|
||||
int left = start;
|
||||
int right = end;
|
||||
while (true) {
|
||||
while (nums[left] < pivot && left < right) {
|
||||
left++;
|
||||
}
|
||||
while (nums[right] >= pivot && right > left) {
|
||||
right--;
|
||||
}
|
||||
if (left == right) {
|
||||
break;
|
||||
}
|
||||
swap(left, right , nums);
|
||||
}
|
||||
swap(left, end , nums);
|
||||
if (k == left + 1) { return pivot; }
|
||||
else if (k < left + 1) { return getKth(k, nums, start, left - 1); }
|
||||
else { return getKth(k, nums, left + 1, end); }
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 交换数组中l1和l2的数据
|
||||
* @param l1
|
||||
* @param l2
|
||||
* @param arr
|
||||
* @return
|
||||
*/
|
||||
private static void swap(int l1 , int l2 , Double[] arr){
|
||||
double temp = arr[l1];
|
||||
arr[l1] = arr[l2];
|
||||
arr[l2] = temp;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算指定范围的List的和
|
||||
* @param data
|
||||
* @param start
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public static int sumList(List<Integer> data, int start , int end){
|
||||
if(start < 0 || start >= data.size() || end < start || end > data.size()){
|
||||
throw new RuntimeException("参数不合法");
|
||||
}
|
||||
int sum = 0;
|
||||
|
||||
for(int i = start ; i < end ; i++){
|
||||
sum += data.get(i);
|
||||
}
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定范围List的最大值
|
||||
* @param data
|
||||
* @param start
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public static int maxList(List<Integer> data, int start , int end){
|
||||
if(start < 0 || start >= data.size() || end < start || end > data.size()){
|
||||
throw new RuntimeException("参数不合法");
|
||||
}
|
||||
int max = data.get(start);
|
||||
|
||||
for(int i = start + 1; i < end ; i++){
|
||||
int value = data.get(i);
|
||||
if(max < value){
|
||||
max = value;
|
||||
}
|
||||
}
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
/**
|
||||
* 计算指定范围List的最小值
|
||||
* @param data
|
||||
* @param start
|
||||
* @param end
|
||||
* @return
|
||||
*/
|
||||
public static int minList(List<Integer> data, int start , int end){
|
||||
if(start < 0 || start >= data.size() || end < start || end > data.size()){
|
||||
throw new RuntimeException("参数不合法");
|
||||
}
|
||||
int min = data.get(start);
|
||||
|
||||
for(int i = start + 1; i < end ; i++){
|
||||
int value = data.get(i);
|
||||
if(min > value){
|
||||
min = value;
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
//。。。。。。。。。。。。。。。。。。。。。。。。TODO
|
||||
|
||||
/**
|
||||
* 返回切割片段中最小的片段的起始下标
|
||||
* @param cutPoint 图像上的切割点
|
||||
* @param width 图像宽度
|
||||
* @return
|
||||
*/
|
||||
public static int minChoicedPart(List<Integer> cutPoint , int width){
|
||||
|
||||
int preValue = cutPoint.get(0);
|
||||
int curValue = -1;
|
||||
int minPart = Integer.MAX_VALUE;
|
||||
int preIndex = -1;
|
||||
int partWidth = -1;
|
||||
for(int i = 1 ; i <= cutPoint.size() ; i++){
|
||||
if(i == cutPoint.size()){
|
||||
curValue = width;
|
||||
}else{
|
||||
curValue = cutPoint.get(i);
|
||||
}
|
||||
partWidth = curValue - preValue;
|
||||
preValue = curValue;
|
||||
if(partWidth < minPart){
|
||||
minPart = partWidth;
|
||||
preIndex = i - 1;
|
||||
}
|
||||
}
|
||||
return preIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回切割片段中最大的片段的起始下标
|
||||
* @param cutPoint 图像上的切割点
|
||||
* @param width 图像的宽度
|
||||
* @return
|
||||
*/
|
||||
public static int maxChoicedPart(List<Integer> cutPoint , int width){
|
||||
int preValue = cutPoint.get(0);
|
||||
int curValue = -1;
|
||||
int maxPart = Integer.MIN_VALUE;
|
||||
int preIndex = -1;
|
||||
int partWidth = -1;
|
||||
for(int i = 1 ; i <= cutPoint.size() ; i++){
|
||||
if(i == cutPoint.size()){
|
||||
curValue = width;
|
||||
}else{
|
||||
curValue = cutPoint.get(i);
|
||||
}
|
||||
partWidth = curValue - preValue;
|
||||
preValue = curValue;
|
||||
if(partWidth > maxPart){
|
||||
maxPart = partWidth;
|
||||
preIndex = i - 1;
|
||||
}
|
||||
}
|
||||
return preIndex;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 计算指定范围的List中大于avg的值的个数
|
||||
* @param data
|
||||
* @param start
|
||||
* @param end
|
||||
* @param avg
|
||||
* @return
|
||||
*/
|
||||
public static int countLargeThanAvgInList(List<Integer> data, int start , int end , int avg){
|
||||
if(start < 0 || start >= data.size() || end < start || end > data.size()){
|
||||
throw new RuntimeException("参数不合法");
|
||||
}
|
||||
int count = 0;
|
||||
for(int i = start ; i < end ; i++){
|
||||
if(data.get(i) > avg){
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@ -0,0 +1,251 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Point;
|
||||
import org.bytedeco.opencv.opencv_core.Scalar;
|
||||
|
||||
/**
|
||||
* 降噪工具类
|
||||
* Noise reduction utility class
|
||||
*/
|
||||
public class NoiseUtils {
|
||||
private static final int WHITE = 255;
|
||||
|
||||
/**
|
||||
* 作用:给单通道的图像边缘预处理,降噪(默认白底黑字)
|
||||
* Function: Preprocess the edges of a single-channel image and reduce noise (default white background and black text)
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat matrix object
|
||||
* @return
|
||||
*/
|
||||
public static Mat strokeWhite(Mat src) {
|
||||
if (src.channels() != 1) {
|
||||
throw new RuntimeException("不是单通道图,需要先灰度化 - It is not a single-channel image and needs to be grayscale first");
|
||||
}
|
||||
int i, width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
for (i = 0; i < width; i++) {
|
||||
GeneralUtils.setPixel(src, i, 0, WHITE);
|
||||
GeneralUtils.setPixel(src, i, height - 1, WHITE);
|
||||
}
|
||||
for (i = 0; i < height; i++) {
|
||||
GeneralUtils.setPixel(src, 0, i, WHITE);
|
||||
GeneralUtils.setPixel(src, width - 1, i, WHITE);
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* 8邻域降噪,又有点像9宫格降噪;即如果9宫格中心被异色包围,则同化 作用:降噪(默认白底黑字)
|
||||
* 8-neighborhood noise reduction, similar to 9-grid noise reduction; that is, if the center of the 9-grid is surrounded by different colors, it is homogenized. Function: Noise reduction (default white background and black text)
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat matrix object
|
||||
* @param pNum 阀值 默认取1即可 - Threshold, the default value is 1
|
||||
* @return
|
||||
*/
|
||||
public static Mat navieRemoveNoise(Mat src, int pNum) {
|
||||
int i, j, m, n, nValue, nCount;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
// 如果一个点的周围都是白色的,自己确实黑色的,同化
|
||||
// If the surroundings of a point are all white and it is indeed black, homogenize
|
||||
for (j = 1; j < height - 1; j++) {
|
||||
for (i = 1; i < width - 1; i++) {
|
||||
nValue = GeneralUtils.getPixel(src, j, i);
|
||||
if (nValue == 0) {
|
||||
nCount = 0;
|
||||
// 比较(j , i)周围的9宫格,如果周围都是白色,同化
|
||||
// Compare the 9-grid around (j, i), and homogenize if the surrounding is white
|
||||
for (m = j - 1; m <= j + 1; m++) {
|
||||
for (n = i - 1; n <= i + 1; n++) {
|
||||
if (GeneralUtils.getPixel(src, m, n) == 0) {
|
||||
nCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nCount <= pNum) {
|
||||
// 周围黑色点的个数小于阀值pNum,把自己设置成白色
|
||||
// If the number of black points around is less than the threshold pNum, set it to white
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getWHITE());
|
||||
}
|
||||
} else {
|
||||
nCount = 0;
|
||||
// 比较(j , i)周围的9宫格,如果周围都是黑色,同化
|
||||
// Compare the 9-grid around (j, i), and homogenize if the surrounding is black
|
||||
for (m = j - 1; m <= j + 1; m++) {
|
||||
for (n = i - 1; n <= i + 1; n++) {
|
||||
if (GeneralUtils.getPixel(src, m, n) == 0) {
|
||||
nCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nCount >= 8 - pNum) {
|
||||
// 周围黑色点的个数大于等于(8 - pNum),把自己设置成黑色
|
||||
// If the number of black points around is greater than or equal to (8 - pNum), set it to black
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getBLACK());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连通域降噪 作用:降噪(默认白底黑字)
|
||||
* Connected domain noise reduction Function: Noise reduction (default white background and black text)
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat matrix object
|
||||
* @param pArea 阀值 默认取1即可 - Threshold, the default value is 1
|
||||
* @return
|
||||
*/
|
||||
public static Mat connectedRemoveNoise(Mat src, double pArea) {
|
||||
int i, j, color = 1;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
Result result = floodFill(new Result(src), pArea);
|
||||
src = result.mat;
|
||||
|
||||
// 二值化 - Binaryzation
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (GeneralUtils.getPixel(src, j, i) < GeneralUtils.getWHITE()) {
|
||||
GeneralUtils.setPixel(src, j, i, GeneralUtils.getBLACK());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (result.status == false && result.count <= 100) {
|
||||
connectedRemoveNoise(src, pArea);
|
||||
}
|
||||
|
||||
return src;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连通域填充颜色
|
||||
* Flood fill color of connected domains
|
||||
*
|
||||
* @param result
|
||||
* @return
|
||||
*/
|
||||
public static Result floodFill(Result result, double pArea) {
|
||||
Mat src = result.mat;
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
int i, j, color = 1;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (GeneralUtils.getPixel(src, j, i) == GeneralUtils.getBLACK()) {
|
||||
// 用不同的颜色填充连接区域中的每个黑色点
|
||||
// Fill each black point in the connected area with a different color
|
||||
// floodFill就是把与点(i , j)的所有相连通的区域都涂上color颜色
|
||||
// floodFill is to color all areas that are connected with point (i, j) with color
|
||||
int area = opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(color));
|
||||
if (area <= pArea) {
|
||||
opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(255));
|
||||
} else {
|
||||
color++;
|
||||
}
|
||||
if (color == 255) {
|
||||
result.status = false; // 连通域还没填充完 - The connected area is not completely filled
|
||||
result.mat = src;
|
||||
result.count = result.count + 1;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
result.mat = src;
|
||||
result.status = true; // 表示所有的连通域都已填充完毕 - Indicates that all connected domains have been filled
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 连通域填充颜色
|
||||
* Flood fill color of connected domains
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat floodFill(Mat src, double pArea) {
|
||||
if (src == null) {
|
||||
return null;
|
||||
}
|
||||
int i, j, color = 1;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (GeneralUtils.getPixel(src, j, i) == GeneralUtils.getBLACK()) {
|
||||
// 用不同的颜色填充连接区域中的每个黑色点
|
||||
// Fill each black point in the connected area with a different color
|
||||
// floodFill就是把与点(i , j)的所有相连通的区域都涂上color颜色
|
||||
// floodFill is to color all areas that are connected with point (i, j) with color
|
||||
int area = opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(color));
|
||||
if (area <= pArea) {
|
||||
System.out.println(color);
|
||||
opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(255));
|
||||
} else {
|
||||
color++;
|
||||
}
|
||||
System.out.println(color);
|
||||
}
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
// 只填充最大的连通域
|
||||
// Only fill the largest connected area
|
||||
public static Mat findMaxConnected(Mat src) {
|
||||
int i, j, color = 127;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int maxArea = Integer.MAX_VALUE;
|
||||
int maxI = -1, maxJ = -1;
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
if (GeneralUtils.getPixel(src, j, i) == GeneralUtils.getBLACK()) {
|
||||
// 用不同的颜色填充连接区域中的每个黑色点
|
||||
// Fill each black point in the connected area with a different color
|
||||
// floodFill就是把与点(i , j)的所有相连通的区域都涂上color颜色
|
||||
// floodFill is to color all areas that are connected with point (i, j) with color
|
||||
int area = opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(color));
|
||||
if (maxI != -1 && maxJ != -1) {
|
||||
if (area > maxArea) {
|
||||
maxArea = area;
|
||||
opencv_imgproc.floodFill(src, new Mat(), new Point(maxI, maxJ), new Scalar(255));
|
||||
maxI = i;
|
||||
maxJ = j;
|
||||
} else {
|
||||
opencv_imgproc.floodFill(src, new Mat(), new Point(i, j), new Scalar(255));
|
||||
}
|
||||
} else {
|
||||
maxI = i;
|
||||
maxJ = j;
|
||||
maxArea = area;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return src;
|
||||
}
|
||||
|
||||
private static class Result {
|
||||
Mat mat; // Mat对象 - Mat object
|
||||
boolean status; // 是否填充完毕 - Whether it is filled
|
||||
int count; // 记录填充的次数 - Number of fillings
|
||||
int height; // 记录上一次填充的height位置 - height position of the last filling
|
||||
int width; // 记录上一次填充的width位置 - width position of the last filling
|
||||
|
||||
public Result() {
|
||||
}
|
||||
|
||||
public Result(Mat src) {
|
||||
this.mat = src;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,110 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.minAreaRect;
|
||||
|
||||
/**
|
||||
* 矩形框工具类
|
||||
* Rectangle tool class
|
||||
*/
|
||||
|
||||
public class RectUtils {
|
||||
|
||||
/**
|
||||
* 返回边缘检测之后的最大矩形
|
||||
* Returns the maximum rectangle after edge detection
|
||||
*
|
||||
* @param contours
|
||||
* @return
|
||||
*/
|
||||
public static RotatedRect getMaxRect(MatVector contours) {
|
||||
// 找出匹配到的最大轮廓 - Find the largest contour
|
||||
Mat maxContour = ContourUtils.getMaxContour(contours);
|
||||
RotatedRect rect = minAreaRect(maxContour);
|
||||
return rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 返回边缘检测之后的最大矩形
|
||||
* Returns the maximum rectangle after edge detection
|
||||
*
|
||||
* @param cannyMat Canny之后的mat矩阵 - Canny's mat matrix
|
||||
* @return
|
||||
*/
|
||||
public static RotatedRect getMaxRect(Mat cannyMat) {
|
||||
// 找出匹配到的最大轮廓 - Find the largest contour
|
||||
Mat maxContour = ContourUtils.getMaxContour(cannyMat);
|
||||
RotatedRect rect = minAreaRect(maxContour);
|
||||
return rect;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把矫正后的图像切割出来
|
||||
* Cut the corrected image
|
||||
*
|
||||
* @param correctMat 图像矫正后的Mat矩阵 - The corrected Mat matrix of the image
|
||||
*/
|
||||
public static Mat cutRect(Mat correctMat, Mat nativeCorrectMat) {
|
||||
// 获取所有轮廓 - Obtain all contours
|
||||
MatVector contours = ContourUtils.getContours(correctMat);
|
||||
|
||||
// 获取最大矩形 - Obtain the largest rectangle
|
||||
RotatedRect rect = getMaxRect(contours);
|
||||
|
||||
Point2f rectPoint = new Point2f(4);
|
||||
rect.points(rectPoint);
|
||||
|
||||
for (int i = 0; i < rectPoint.limit(); i++) {
|
||||
System.out.println(rectPoint.position(i).x() + " , " + rectPoint.position(i).y());
|
||||
}
|
||||
|
||||
int x = rect.boundingRect().x();
|
||||
int y = rect.boundingRect().y();
|
||||
int width = rect.boundingRect().width();
|
||||
int height = rect.boundingRect().height();
|
||||
// int x = (int) Math.abs(rectPoint.position(2).x());
|
||||
// int y = (int) Math.abs(rectPoint.position(2).y() < rectPoint.position(3).y() ?
|
||||
// rectPoint.position(2).y() : rectPoint.position(3).y());
|
||||
// int width = (int) Math.abs(rectPoint.position(3).x() - rectPoint.position(2).x());
|
||||
// int height = (int) Math.abs(rectPoint.position(1).y() - rectPoint.position(2).y());
|
||||
|
||||
System.out.println("startLeft = " + x);
|
||||
System.out.println("startUp = " + y);
|
||||
System.out.println("width = " + width);
|
||||
System.out.println("height = " + height);
|
||||
|
||||
Mat temp = new Mat(nativeCorrectMat, new Rect(x, y, width, height));
|
||||
Mat t = new Mat();
|
||||
temp.copyTo(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* 把矫正后的图像切割出来--辅助函数(修复)
|
||||
* Cut the corrected image -- auxiliary function (repair)
|
||||
*
|
||||
* @param rectPoint 矩形的四个点 - The four points of the rectangle
|
||||
* @return int[startLeft , startUp , width , height]
|
||||
*/
|
||||
public static int[] cutRectHelp(Point2f rectPoint) {
|
||||
double minX = rectPoint.position(0).x();
|
||||
double maxX = rectPoint.position(0).x();
|
||||
double minY = rectPoint.position(0).y();
|
||||
double maxY = rectPoint.position(0).y();
|
||||
for (int i = 1; i < 4; i++) {
|
||||
minX = rectPoint.position(i).x() < minX ? rectPoint.position(i).x() : minX;
|
||||
maxX = rectPoint.position(i).x() > maxX ? rectPoint.position(i).x() : maxX;
|
||||
minY = rectPoint.position(i).y() < minY ? rectPoint.position(i).y() : minY;
|
||||
maxY = rectPoint.position(i).y() > maxY ? rectPoint.position(i).y() : maxY;
|
||||
}
|
||||
int[] roi = {
|
||||
(int) Math.abs(minX),
|
||||
(int) Math.abs(minY),
|
||||
(int) Math.abs(maxX - minX),
|
||||
(int) Math.abs(maxY - minY)
|
||||
};
|
||||
return roi;
|
||||
}
|
||||
}
|
@ -0,0 +1,200 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Rect;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 归一化工具类
|
||||
* Normalization utility class
|
||||
*/
|
||||
|
||||
public class ResizeUtils {
|
||||
// 设置归一化图像的固定大小
|
||||
// Set the fixed size of the normalized image
|
||||
private static final Size defaultDsize = new Size(32, 32);
|
||||
|
||||
/**
|
||||
* 把图片归一化到相同的大小
|
||||
* Normalize the image to the same size
|
||||
* @param src Mat矩阵对象 - Mat matrix object
|
||||
* @return
|
||||
*/
|
||||
public static Mat resize(Mat src) {
|
||||
return resize(src, defaultDsize);
|
||||
}
|
||||
|
||||
/**
|
||||
* 把图片归一化到相同的大小
|
||||
* Normalize the image to the same size
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat matrix object
|
||||
* @return
|
||||
*/
|
||||
public static Mat resize(Mat src, Size dsize) {
|
||||
src = trimImg(src);
|
||||
Mat dst = new Mat();
|
||||
// 区域插值(INTER_AREA):图像放大时类似于线性插值,图像缩小时可以避免波纹出现。
|
||||
// Area interpolation (INTER_AREA): similar to linear interpolation when the image is enlarged, and can avoid ripples when the image is reduced.
|
||||
opencv_imgproc.resize(src, dst, dsize, 0, 0, Imgproc.INTER_AREA);
|
||||
return dst;
|
||||
}
|
||||
|
||||
/**
|
||||
* 去除图像中的空白
|
||||
* Remove the blank space in the image
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static Mat trimImg(Mat src) {
|
||||
List<Double> colList = MathUtils.avgColMat(src); // 每一列的平均值 - Average value of each column
|
||||
List<Double> rowList = MathUtils.avgRowMat(src); // 每一行的平均值 - Average value of each row
|
||||
|
||||
double colAvg = MathUtils.getSumInList(colList) / colList.size();
|
||||
double rowAvg = MathUtils.getSumInList(rowList) / rowList.size();
|
||||
|
||||
int blankCol1 = -1; // 空白列的关键分割点(左) - Key segmentation point (left) of blank column
|
||||
int blankCol2 = -1; // 空白列的关键分割点(右) - Key segmentation point (right) of blank column
|
||||
int blankRow1 = -1; // 空白行的关键分割点(上) - Key segmentation point (up) of blank row
|
||||
int blankRow2 = -1; // 空白行的关键分割点(下) - Key segmentation point (down) of blank row
|
||||
|
||||
int preValue = -1;
|
||||
int curValue = -1;
|
||||
int count = 0;
|
||||
boolean b = true;
|
||||
for (int i = 0; i < colList.size(); i++) {
|
||||
if (b == false) {
|
||||
break;
|
||||
}
|
||||
if (colList.get(i) > colAvg) {
|
||||
// 求空白列的关键分割点(左) - Calculate the key segmentation point (left) of the blank column
|
||||
curValue = i;
|
||||
if (preValue != -1) {
|
||||
if (curValue - preValue == 1) {
|
||||
// 连续 - Continuous
|
||||
count++;
|
||||
} else {
|
||||
// 不连续 - Not continuous
|
||||
if (count > 10) {
|
||||
blankCol1 = 2 * i / 3;
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
preValue = i;
|
||||
}
|
||||
}
|
||||
|
||||
preValue = -1;
|
||||
curValue = -1;
|
||||
count = 0;
|
||||
b = true;
|
||||
for (int i = colList.size() - 1; i >= 0; i--) {
|
||||
if (b == false) {
|
||||
break;
|
||||
}
|
||||
if (colList.get(i) > colAvg) {
|
||||
// 求空白列的关键分割点(右)
|
||||
// Calculate the key segmentation point (right) of the blank column
|
||||
curValue = i;
|
||||
if (preValue != -1) {
|
||||
if (curValue - preValue == -1) {
|
||||
// 连续 - Continuous
|
||||
count++;
|
||||
} else {
|
||||
// 不连续 - Not continuous
|
||||
if (count > 10) {
|
||||
blankCol2 = i + (colList.size() - i) / 3;
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
preValue = i;
|
||||
}
|
||||
}
|
||||
|
||||
preValue = -1;
|
||||
curValue = -1;
|
||||
count = 0;
|
||||
b = true;
|
||||
for (int i = 0; i < rowList.size(); i++) {
|
||||
if (rowList.get(i) > rowAvg) {
|
||||
// 空白行的关键分割点(上)
|
||||
// Key segmentation point (up) of blank row
|
||||
if (b == false) {
|
||||
break;
|
||||
}
|
||||
if (rowList.get(i) > rowAvg) {
|
||||
curValue = i;
|
||||
if (preValue != -1) {
|
||||
if (curValue - preValue == 1) {
|
||||
// 连续 - Continuous
|
||||
count++;
|
||||
} else {
|
||||
// 不连续 - Not continuous
|
||||
if (count > 10) {
|
||||
blankRow1 = i / 2;
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
preValue = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
preValue = -1;
|
||||
curValue = -1;
|
||||
count = 0;
|
||||
b = true;
|
||||
for (int i = rowList.size() - 1; i >= 0; i--) {
|
||||
if (rowList.get(i) > rowAvg) {
|
||||
// 空白行的关键分割点(下)
|
||||
// Key segmentation point (down) of blank row
|
||||
if (b == false) {
|
||||
break;
|
||||
}
|
||||
if (rowList.get(i) > rowAvg) {
|
||||
curValue = i;
|
||||
if (preValue != -1) {
|
||||
if (curValue - preValue == -1) {
|
||||
// 连续 - Continuous
|
||||
count++;
|
||||
} else {
|
||||
// 不连续 - Not continuous
|
||||
if (count > 10) {
|
||||
blankRow2 = i + 2 * (rowList.size() - i) / 3;
|
||||
b = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
preValue = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// int blankCol1 = -1; 空白列的关键分割点(左) - Key splitting point (left) of the blank column
|
||||
// int blankCol2 = -1; 空白列的关键分割点(右) - Key splitting point (right) of the blank column
|
||||
// int blankRow1 = -1; 空白行的关键分割点(上) - Key splitting point (top) of the blank row
|
||||
// int blankRow2 = -1; 空白行的关键分割点(下) - Key splitting point (bottom) of the blank row
|
||||
// Select the area of interest
|
||||
|
||||
blankCol1 = blankCol1 == -1 ? 0 : blankCol1;
|
||||
blankCol2 = blankCol2 == -1 ? colList.size() : blankCol2;
|
||||
blankRow1 = blankRow1 == -1 ? 0 : blankRow1;
|
||||
blankRow2 = blankRow2 == -1 ? rowList.size() : blankRow2;
|
||||
|
||||
Mat temp =
|
||||
new Mat(
|
||||
src, new Rect(blankCol1, blankRow1, blankCol2 - blankCol1, blankRow2 - blankRow1));
|
||||
Mat t = new Mat();
|
||||
temp.copyTo(t);
|
||||
|
||||
return t;
|
||||
}
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Point2f;
|
||||
import org.bytedeco.opencv.opencv_core.RotatedRect;
|
||||
import org.bytedeco.opencv.opencv_core.Scalar;
|
||||
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.getRotationMatrix2D;
|
||||
import static org.bytedeco.opencv.global.opencv_imgproc.warpAffine;
|
||||
|
||||
/**
|
||||
* 旋转矩形工具类
|
||||
* Rotation Rectangle Tool Class
|
||||
*/
|
||||
public class RotationUtils {
|
||||
|
||||
/**
|
||||
* 旋转矩形 返回旋转后的Mat
|
||||
* Rotate rectangle and return rotated Mat
|
||||
* @param cannyMat mat矩阵 - matrix
|
||||
* @param rect 矩形 - rectangle
|
||||
* @return
|
||||
*/
|
||||
public static Mat rotation(Mat cannyMat, RotatedRect rect) {
|
||||
double angle = rect.angle();
|
||||
Point2f center = rect.center();
|
||||
Mat correctImg = new Mat(cannyMat.size(), cannyMat.type());
|
||||
cannyMat.copyTo(correctImg);
|
||||
|
||||
// 得到旋转矩阵算子 - Get the rotation matrix operator
|
||||
Mat matrix = getRotationMatrix2D(center, angle, 0.8);
|
||||
|
||||
warpAffine(correctImg, correctImg, matrix, correctImg.size(), 1, 0, new Scalar(0, 0, 0, 0));
|
||||
|
||||
return correctImg;
|
||||
}
|
||||
}
|
@ -0,0 +1,470 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.opencv_core.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* 图像处理工具类1.0.0(只针对几乎没有畸变的图像) 灰度话、二值化、降噪、切割、归一化
|
||||
* Image processing utility class 1.0.0 (only for images with almost no distortion) Grayscale, binarization, denoising, cutting, normalization
|
||||
*
|
||||
* @author admin
|
||||
*/
|
||||
public class TableUtils {
|
||||
private static final int BLACK = 0;
|
||||
|
||||
private TableUtils() {};
|
||||
|
||||
/**
|
||||
* 统计图像每行/每列黑色像素点的个数
|
||||
* Count the number of black pixels per row/column in the image
|
||||
* (n1,n2)=>(height,width),
|
||||
* b=true; 统计每行 - count per row
|
||||
* (n1,n2)=>(width,height),
|
||||
* b=false; 统计每列 - count per column
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat object
|
||||
* @param n1
|
||||
* @param n2
|
||||
* @param b true表示统计每行;false表示统计每列 - true to count each row; false to count each column
|
||||
* @return
|
||||
*/
|
||||
public static int[] countPixel(Mat src, int n1, int n2, boolean b) {
|
||||
int[] xNum = new int[n1];
|
||||
for (int i = 0; i < n1; i++) {
|
||||
for (int j = 0; j < n2; j++) {
|
||||
if (b) {
|
||||
if (GeneralUtils.getPixel(src, i, j) == BLACK) {
|
||||
xNum[i]++;
|
||||
}
|
||||
} else {
|
||||
if (GeneralUtils.getPixel(src, j, i) == BLACK) {
|
||||
xNum[i]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return xNum;
|
||||
}
|
||||
|
||||
/**
|
||||
* 压缩像素值数量;即统计zipLine行像素值的数量为一行
|
||||
* Compress the number of pixel values; count the number of pixel values of zipLine rows as one row
|
||||
* @param num
|
||||
* @param zipLine
|
||||
*/
|
||||
public static int[] zipLinePixel(int[] num, int zipLine) {
|
||||
int len = num.length / zipLine;
|
||||
int[] result = new int[len];
|
||||
int sum;
|
||||
for (int i = 0, j = 0; i < num.length && i + zipLine < num.length; i += zipLine) {
|
||||
sum = 0;
|
||||
for (int k = 0; k < zipLine; k++) {
|
||||
sum += num[i + k];
|
||||
}
|
||||
result[j++] = sum;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* 水平投影法切割,适用于类似表格的图像(默认白底黑字) 改进
|
||||
* Horizontal projection cutting, suitable for image like tables (default white background and black text) improvement
|
||||
* @param src Mat矩阵对象 - Mat object
|
||||
* @return
|
||||
*/
|
||||
public static List<Mat> cutImgX(Mat src) {
|
||||
int i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int[] xNum, cNum;
|
||||
int average = 0; // 记录黑色像素和的平均值 - Record the average value of black pixels
|
||||
|
||||
int zipLine = 3;
|
||||
// 压缩像素值数量;即统计三行像素值的数量为一行
|
||||
// Compress the number of pixel values;
|
||||
// 统计出每行黑色像素点的个数
|
||||
// count three rows of pixel values as one row
|
||||
xNum = zipLinePixel(countPixel(src, height, width, true), zipLine);
|
||||
|
||||
// 排序 - Sort
|
||||
cNum = Arrays.copyOf(xNum, xNum.length);
|
||||
Arrays.sort(cNum);
|
||||
|
||||
for (i = 31 * cNum.length / 32; i < cNum.length; i++) {
|
||||
average += cNum[i];
|
||||
}
|
||||
average /= (height / 32);
|
||||
|
||||
// 把需要切割的y轴点存到cutY中
|
||||
// Store the y-axis points that need to be cut in cutY
|
||||
List<Integer> cutY = new ArrayList<Integer>();
|
||||
for (i = 0; i < xNum.length; i++) {
|
||||
if (xNum[i] > average) {
|
||||
cutY.add(i * zipLine + 1);
|
||||
}
|
||||
}
|
||||
|
||||
// 优化cutY,把距离相差在30以内的都清除掉
|
||||
// Optimize cutY, remove all those whose distance is within 30
|
||||
if (cutY.size() != 0) {
|
||||
int temp = cutY.get(cutY.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// Optimize cutY because of the thickness of the line
|
||||
for (i = cutY.size() - 2; i >= 0; i--) {
|
||||
int k = temp - cutY.get(i);
|
||||
if (k <= 30) {
|
||||
cutY.remove(i + 1);
|
||||
} else {
|
||||
temp = cutY.get(i);
|
||||
}
|
||||
}
|
||||
temp = cutY.get(cutY.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// Optimize cutY because of the thickness of the line
|
||||
for (i = cutY.size() - 2; i >= 0; i--) {
|
||||
int k = temp - cutY.get(i);
|
||||
if (k <= 30) {
|
||||
cutY.remove(i + 1);
|
||||
} else {
|
||||
temp = cutY.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 把切割的图片保存到YMat中
|
||||
// Store the cut images in YMat
|
||||
List<Mat> YMat = new ArrayList<Mat>();
|
||||
for (i = 1; i < cutY.size(); i++) {
|
||||
// // 设置感兴趣区域 - Set the region of interest
|
||||
int startY = cutY.get(i - 1);
|
||||
int h = cutY.get(i) - startY;
|
||||
Mat temp = new Mat(src, new Rect(0, startY, width, h));
|
||||
Mat t = new Mat();
|
||||
temp.copyTo(t);
|
||||
YMat.add(t);
|
||||
}
|
||||
return YMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* 垂直投影法切割,适用于类似表格的图像(默认白底黑字) 改进
|
||||
* Vertical projection cutting, suitable for image like tables (default white background and black text) improvement
|
||||
*
|
||||
* @param src Mat矩阵对象 - Mat object
|
||||
* @return
|
||||
*/
|
||||
public static List<Mat> cutImgY(Mat src) {
|
||||
int i, j;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int[] yNum, cNum;
|
||||
int average = 0; // 记录黑色像素和的平均值 - Record the average value of black pixels
|
||||
|
||||
int zipLine = 2;
|
||||
// 压缩像素值数量;即统计三行像素值的数量为一行
|
||||
// Compress the number of pixel values
|
||||
// 统计出每列黑色像素点的个数
|
||||
// count three rows of pixel values as one row
|
||||
yNum = zipLinePixel(countPixel(src, width, height, false), zipLine);
|
||||
|
||||
// 经过测试这样得到的平均值最优,平均值的选取很重要
|
||||
// After testing, this is the optimal way to get the average value. The selection of the average value is very important.
|
||||
cNum = Arrays.copyOf(yNum, yNum.length);
|
||||
Arrays.sort(cNum);
|
||||
for (i = 31 * cNum.length / 32; i < cNum.length; i++) {
|
||||
average += cNum[i];
|
||||
}
|
||||
average /= (cNum.length / 32);
|
||||
|
||||
// 把需要切割的x轴的点存到cutX中
|
||||
// Store the x-axis points that need to be cut in cutX
|
||||
List<Integer> cutX = new ArrayList<Integer>();
|
||||
for (i = 0; i < yNum.length; i++) {
|
||||
if (yNum[i] >= average) {
|
||||
cutX.add(i * zipLine + 2);
|
||||
}
|
||||
}
|
||||
|
||||
// 优化cutX - Optimize cutX
|
||||
if (cutX.size() != 0) {
|
||||
int temp = cutX.get(cutX.size() - 1);
|
||||
// 因为线条有粗细,优化cutX
|
||||
// Optimize cutX because of the thickness of the line
|
||||
for (i = cutX.size() - 2; i >= 0; i--) {
|
||||
int k = temp - cutX.get(i);
|
||||
if (k <= 100) {
|
||||
cutX.remove(i);
|
||||
} else {
|
||||
temp = cutX.get(i);
|
||||
}
|
||||
}
|
||||
temp = cutX.get(cutX.size() - 1);
|
||||
// 因为线条有粗细,优化cutX
|
||||
// Optimize cutX because of the thickness of the line
|
||||
for (i = cutX.size() - 2; i >= 0; i--) {
|
||||
int k = temp - cutX.get(i);
|
||||
if (k <= 100) {
|
||||
cutX.remove(i);
|
||||
} else {
|
||||
temp = cutX.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 把切割的图片都保存到XMat中
|
||||
// Store the cut images in XMat
|
||||
List<Mat> XMat = new ArrayList<Mat>();
|
||||
for (i = 1; i < cutX.size(); i++) {
|
||||
// 设置感兴趣的区域
|
||||
// Set the region of interest
|
||||
int startX = cutX.get(i - 1);
|
||||
int w = cutX.get(i) - startX;
|
||||
Mat temp = new Mat(src, new Rect(startX, 0, w, height));
|
||||
Mat t = new Mat();
|
||||
temp.copyTo(t);
|
||||
XMat.add(t);
|
||||
}
|
||||
return XMat;
|
||||
}
|
||||
|
||||
/**
|
||||
* 切割 因为是表格图像,采用新的切割思路,中和水平切割和垂直切割一次性切割出所有的小格子
|
||||
* Cutting. Because it is a table image, a new cutting idea is used, which cuts out all small cells in one step by combining horizontal and vertical cutting.
|
||||
*
|
||||
* @param src
|
||||
* @return
|
||||
*/
|
||||
public static List<Mat> cut(Mat src) {
|
||||
if (src.channels() == 3) {
|
||||
// TODO
|
||||
}
|
||||
int i, j, k;
|
||||
int width = GeneralUtils.getImgWidth(src), height = GeneralUtils.getImgHeight(src);
|
||||
int[] xNum = new int[height], copy_xNum;
|
||||
int x_average = 0;
|
||||
int value = -1;
|
||||
// 统计每行每列的黑色像素值
|
||||
// Count the number of black pixels per row/column
|
||||
for (i = 0; i < width; i++) {
|
||||
for (j = 0; j < height; j++) {
|
||||
value = GeneralUtils.getPixel(src, j, i);
|
||||
if (value == BLACK) {
|
||||
xNum[j]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int zipXLine = 3;
|
||||
xNum = zipLinePixel(xNum, zipXLine);
|
||||
|
||||
// 排序 ............求水平切割点
|
||||
// Sort ............ to get horizontal cutting points
|
||||
copy_xNum = Arrays.copyOf(xNum, xNum.length);
|
||||
Arrays.sort(copy_xNum);
|
||||
|
||||
for (i = 31 * copy_xNum.length / 32; i < copy_xNum.length; i++) {
|
||||
x_average += copy_xNum[i];
|
||||
}
|
||||
x_average /= (height / 32);
|
||||
|
||||
// 把需要切割的y轴点存到cutY中
|
||||
// Store the y-axis points that need to be cut in cutY
|
||||
List<Integer> cutY = new ArrayList<Integer>();
|
||||
for (i = 0; i < xNum.length; i++) {
|
||||
if (xNum[i] > x_average) {
|
||||
cutY.add(i * zipXLine + zipXLine / 2);
|
||||
}
|
||||
}
|
||||
|
||||
// 优化cutY,把距离相差在30以内的都清除掉
|
||||
// Optimize cutY, remove all those whose distance is within 30
|
||||
if (cutY.size() != 0) {
|
||||
int temp = cutY.get(cutY.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// Optimize cutY because of the thickness of the line
|
||||
for (i = cutY.size() - 2; i >= 0; i--) {
|
||||
k = temp - cutY.get(i);
|
||||
if (k <= 10 * zipXLine) {
|
||||
cutY.remove(i + 1);
|
||||
} else {
|
||||
temp = cutY.get(i);
|
||||
}
|
||||
}
|
||||
temp = cutY.get(cutY.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// Optimize cutY because of the thickness of the line
|
||||
for (i = cutY.size() - 2; i >= 0; i--) {
|
||||
k = temp - cutY.get(i);
|
||||
if (k <= 10 * zipXLine) {
|
||||
cutY.remove(i + 1);
|
||||
} else {
|
||||
temp = cutY.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 把需要切割的x轴的点存到cutX中
|
||||
// Store the x-axis points that need to be cut in cutX
|
||||
// 新思路,因为不是很畸变的图像,y轴的割点还是比较好确定的 随机的挑选一个y轴割点,用一个滑动窗口去遍历选中点所在直线,确定x轴割点
|
||||
// New idea, because it is not a very distorted image, the y-axis cutting point is still relatively easy to determine.
|
||||
// Randomly select a y-axis cutting point, use a sliding window to traverse the straight line where the selected point is located, and determine the x-axis cutting point.
|
||||
List<Integer> cutX = new ArrayList<Integer>();
|
||||
int choiceY = cutY.size() > 1 ? cutY.get(1) : (cutY.size() > 0 ? cutY.get(0) : -1);
|
||||
if (choiceY == -1) {
|
||||
throw new RuntimeException("切割失败,没有找到水平切割点 - Cutting failed, no horizontal cutting point found");
|
||||
}
|
||||
|
||||
int winH = 5;
|
||||
List<Integer> LH1 = new ArrayList<Integer>();
|
||||
List<Integer> LH2 = new ArrayList<Integer>();
|
||||
if (choiceY - winH >= 0 && choiceY + winH <= height) {
|
||||
// 上下 - Up and down
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, choiceY - winH, i);
|
||||
if (value == BLACK) {
|
||||
LH1.add(i);
|
||||
}
|
||||
value = GeneralUtils.getPixel(src, choiceY + winH, i);
|
||||
if (value == BLACK) {
|
||||
LH2.add(i);
|
||||
}
|
||||
}
|
||||
} else if (choiceY + winH <= height && choiceY + 2 * winH <= height) {
|
||||
// 下 - Down
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, choiceY + 2 * winH, i);
|
||||
if (value == BLACK) {
|
||||
LH1.add(i);
|
||||
}
|
||||
value = GeneralUtils.getPixel(src, choiceY + winH, i);
|
||||
if (value == BLACK) {
|
||||
LH2.add(i);
|
||||
}
|
||||
}
|
||||
} else if (choiceY - winH >= 0 && choiceY - 2 * winH >= 0) {
|
||||
// 上 - Up
|
||||
for (i = 0; i < width; i++) {
|
||||
value = GeneralUtils.getPixel(src, choiceY - winH, i);
|
||||
if (value == BLACK) {
|
||||
LH1.add(i);
|
||||
}
|
||||
value = GeneralUtils.getPixel(src, choiceY - 2 * winH, i);
|
||||
if (value == BLACK) {
|
||||
LH2.add(i);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
throw new RuntimeException("切割失败,图像异常 - Cutting failed, image exception");
|
||||
}
|
||||
|
||||
// 优化LH1、LH2,把距离相差在30以内的都清除掉
|
||||
// Optimize LH1 and LH2, removing all distances within 30
|
||||
if (LH1.size() != 0) {
|
||||
int temp = LH1.get(LH1.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// optimize cutY because of line thickness
|
||||
for (i = LH1.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH1.get(i);
|
||||
if (k <= 50) {
|
||||
LH1.remove(i + 1);
|
||||
} else {
|
||||
temp = LH1.get(i);
|
||||
}
|
||||
}
|
||||
temp = LH1.get(LH1.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// optimize cutY because of line thickness
|
||||
for (i = LH1.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH1.get(i);
|
||||
if (k <= 50) {
|
||||
LH1.remove(i + 1);
|
||||
} else {
|
||||
temp = LH1.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (LH2.size() != 0) {
|
||||
int temp = LH2.get(LH2.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// optimize cutY because of line thickness
|
||||
for (i = LH2.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH2.get(i);
|
||||
if (k <= 50) {
|
||||
LH2.remove(i + 1);
|
||||
} else {
|
||||
temp = LH2.get(i);
|
||||
}
|
||||
}
|
||||
temp = LH2.get(LH2.size() - 1);
|
||||
// 因为线条有粗细,优化cutY
|
||||
// optimize cutY because of line thickness
|
||||
for (i = LH2.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH2.get(i);
|
||||
if (k <= 50) {
|
||||
LH2.remove(i + 1);
|
||||
} else {
|
||||
temp = LH2.get(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (LH1.size() < LH2.size()) {
|
||||
// 进一步优化LH1
|
||||
// further optimize LH1
|
||||
int avg = 0;
|
||||
for (k = 1; k < LH1.size() - 2; k++) {
|
||||
avg += LH1.get(k + 1) - LH1.get(k);
|
||||
}
|
||||
avg /= (LH1.size() - 2);
|
||||
|
||||
int temp = LH1.get(LH1.size() - 1);
|
||||
for (i = LH1.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH1.get(i);
|
||||
if (k <= avg) {
|
||||
LH1.remove(i + 1);
|
||||
} else {
|
||||
temp = LH1.get(i);
|
||||
}
|
||||
}
|
||||
cutX = LH1;
|
||||
} else {
|
||||
// 进一步优化LH2
|
||||
// further optimize LH2
|
||||
int avg = 0;
|
||||
for (k = 1; k < LH2.size() - 2; k++) {
|
||||
avg += LH2.get(k + 1) - LH2.get(k);
|
||||
}
|
||||
avg /= (LH2.size() - 2);
|
||||
|
||||
int temp = LH2.get(LH2.size() - 1);
|
||||
for (i = LH2.size() - 2; i >= 0; i--) {
|
||||
k = temp - LH2.get(i);
|
||||
if (k <= avg) {
|
||||
LH2.remove(i + 1);
|
||||
} else {
|
||||
temp = LH2.get(i);
|
||||
}
|
||||
}
|
||||
cutX = LH2;
|
||||
}
|
||||
|
||||
List<Mat> destMat = new ArrayList<Mat>();
|
||||
for (i = 1; i < cutY.size(); i++) {
|
||||
for (j = 1; j < cutX.size(); j++) {
|
||||
// 设置感兴趣的区域
|
||||
// set region of interest
|
||||
int startX = cutX.get(j - 1);
|
||||
int w = cutX.get(j) - startX;
|
||||
int startY = cutY.get(i - 1);
|
||||
int h = cutY.get(i) - startY;
|
||||
Mat temp = new Mat(src, new Rect(startX + 2, startY + 2, w - 2, h - 2));
|
||||
Mat t = new Mat();
|
||||
temp.copyTo(t);
|
||||
destMat.add(t);
|
||||
}
|
||||
}
|
||||
|
||||
return destMat;
|
||||
}
|
||||
}
|
@ -0,0 +1,52 @@
|
||||
package me.aias.util;
|
||||
|
||||
import org.bytedeco.opencv.global.opencv_imgproc;
|
||||
import org.bytedeco.opencv.opencv_core.Mat;
|
||||
import org.bytedeco.opencv.opencv_core.Point2f;
|
||||
import org.bytedeco.opencv.opencv_core.Scalar;
|
||||
import org.opencv.imgproc.Imgproc;
|
||||
|
||||
/**
|
||||
* 透视变换工具类
|
||||
* Perspective transformation
|
||||
*
|
||||
*/
|
||||
public class WarpPerspectiveUtils {
|
||||
|
||||
/**
|
||||
* 透视变换
|
||||
* Perspective transformation
|
||||
*
|
||||
* @param src
|
||||
* @param srcPoints
|
||||
* @param dstPoints
|
||||
* @return
|
||||
*/
|
||||
public static Mat warpPerspective(Mat src, Mat srcPoints, Mat dstPoints) {
|
||||
// srcPoints, dstPoints
|
||||
// 点的顺序[左上 ,右上 ,右下 ,左下]
|
||||
// Point order [top left, top right, bottom right, bottom left]
|
||||
Mat perspectiveMmat = opencv_imgproc.getPerspectiveTransform(srcPoints, dstPoints);
|
||||
|
||||
Mat dst = new Mat();
|
||||
|
||||
opencv_imgproc.warpPerspective(
|
||||
src,
|
||||
dst,
|
||||
perspectiveMmat,
|
||||
src.size(),
|
||||
Imgproc.INTER_LINEAR + Imgproc.WARP_INVERSE_MAP,
|
||||
1,
|
||||
new Scalar(0));
|
||||
|
||||
return dst;
|
||||
}
|
||||
|
||||
public static Mat perspectiveTransform(
|
||||
Mat src, Point2f srcPoints, Point2f dstPoints) {
|
||||
Mat dst = src.clone();
|
||||
Mat warp_mat = opencv_imgproc.getPerspectiveTransform(srcPoints.position(0), dstPoints.position(0));
|
||||
opencv_imgproc.warpPerspective(src, dst, warp_mat, dst.size());
|
||||
return dst;
|
||||
}
|
||||
}
|
@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<Configuration status="INFO">
|
||||
<Appenders>
|
||||
<Console name="console" target="SYSTEM_OUT">
|
||||
<PatternLayout
|
||||
pattern="[%-5level] - %msg%n"/>
|
||||
</Console>
|
||||
</Appenders>
|
||||
<Loggers>
|
||||
<Root level="info" additivity="false">
|
||||
<AppenderRef ref="console"/>
|
||||
</Root>
|
||||
<Logger name="me.calvin" level="${sys:me.calvin.logging.level:-info}" additivity="false">
|
||||
<AppenderRef ref="console"/>
|
||||
</Logger>
|
||||
</Loggers>
|
||||
</Configuration>
|
Loading…
Reference in New Issue
Block a user