Showing preview only (345K chars total). Download the full file or copy to clipboard to get everything.
Repository: FeiGeChuanShu/ncnn_paddleocr
Branch: main
Commit: 3e66eb7df5d8
Files: 29
Total size: 318.6 KB
Directory structure:
gitextract_zxhxyjoe/
├── README.md
├── app/
│ ├── build.gradle
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── assets/
│ │ ├── ch_PP-OCRv3_det.param
│ │ ├── ch_PP-OCRv3_rec.param
│ │ ├── cls-sim-op.param
│ │ ├── det-sim-op.param
│ │ ├── paddleocr_keys.txt
│ │ ├── pdocrv2.0_det-op.param
│ │ ├── pdocrv2.0_rec-op.param
│ │ └── rec-sim-op.param
│ ├── java/
│ │ └── com/
│ │ └── tencent/
│ │ └── paddleocrncnn/
│ │ ├── MainActivity.java
│ │ └── PaddleOCRNcnn.java
│ ├── jni/
│ │ ├── CMakeLists.txt
│ │ ├── clipper.cpp
│ │ ├── clipper.hpp
│ │ ├── common.cpp
│ │ ├── common.h
│ │ └── paddleocr_ncnn.cpp
│ └── res/
│ ├── layout/
│ │ └── main.xml
│ ├── values/
│ │ └── strings.xml
│ └── xml/
│ └── file_paths.xml
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: README.md
================================================
# ncnn_paddleocr
This is a sample paddleocr ncnn android project, it depends on ncnn library and opencv
https://github.com/Tencent/ncnn
https://github.com/nihui/opencv-mobile
convert paddleocr light model to ncnn,you can use it by ncnn.
the infer code you can use chineseocr_lite project.
PS:if you use angle model plz change the input shape dstHeight from 32 to 48
# model support
## text detection
1.mv3dbnet-sim-op(paddleocr_mobile)
2.pdocrv2.0_det-op(PP-OCRv2)
3.ch_PP-OCRv3_det(PP-OCRv3)
4.ch_PP-OCRv4_det(PP-OCRv4) [model](https://github.com/FeiGeChuanShu/ncnn_ppstructure)
## text angle cls
1.angle-sim-op
## text recognition
1.mv3rec-sim-op(paddleocr_mobile)
2.pdocrv2.0_rec-op(PP-OCRv2)
3.ch_PP-OCRv3_rec(PP-OCRv3)
4.ch_PP-OCRv4_rec(PP-OCRv4) [model](https://github.com/FeiGeChuanShu/ncnn_ppstructure)
## how to build and run
### step1
https://github.com/Tencent/ncnn/releases
* Download ncnn-YYYYMMDD-android-vulkan.zip or build ncnn for android yourself
* Extract ncnn-YYYYMMDD-android-vulkan.zip into **app/src/main/jni** and change the **ncnn_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**
### step2
https://github.com/nihui/opencv-mobile
* Download opencv-mobile-XYZ-android.zip
* Extract opencv-mobile-XYZ-android.zip into **app/src/main/jni** and change the **OpenCV_DIR** path to yours in **app/src/main/jni/CMakeLists.txt**
### step3
* Open this project with Android Studio, build it and enjoy!
## screenshot

1.https://github.com/DayBreak-u/chineseocr_lite/tree/onnx/cpp_projects/OcrLiteNcnn
2.https://github.com/frotms/PaddleOCR2Pytorch
3.https://github.com/PaddlePaddle/PaddleOCR#PP-OCRv2
4.https://github.com/nihui/ncnn-android-yolov5
5.https://github.com/PaddlePaddle/PaddleOCR/blob/release/2.5
================================================
FILE: app/build.gradle
================================================
apply plugin: 'com.android.application'
android {
compileSdkVersion 24
buildToolsVersion "29.0.2"
defaultConfig {
applicationId "com.tencent.paddleocrncnn"
archivesBaseName = "$applicationId"
ndk {
moduleName "ncnn"
abiFilters "armeabi-v7a", "arm64-v8a"
}
minSdkVersion 24
}
externalNativeBuild {
cmake {
version "3.10.2"
path file('src/main/jni/CMakeLists.txt')
}
}
dependencies {
implementation 'com.android.support:support-v4:24.0.0'
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tencent.paddleocrncnn"
android:versionCode="1"
android:versionName="1.1">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application android:label="@string/app_name" >
<activity android:name="MainActivity"
android:label="@string/app_name">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
<provider
android:name="android.support.v4.content.FileProvider"
android:authorities="com.tencent.paddleocrncnn.fileprovider"
android:exported="false"
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/file_paths" />
</provider>
</application>
</manifest>
================================================
FILE: app/src/main/assets/ch_PP-OCRv3_det.param
================================================
7767517
153 185
Input x 0 1 input
Convolution Conv_0 1 1 input hardswish_0.tmp_0 0=8 1=3 3=2 4=1 5=1 6=216 9=6 -23310=2,1.666667e-01,5.000000e-01
Split splitncnn_0 1 2 hardswish_0.tmp_0 hardswish_0.tmp_0_splitncnn_0 hardswish_0.tmp_0_splitncnn_1
Convolution Conv_1 1 1 hardswish_0.tmp_0_splitncnn_1 relu_0.tmp_0 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise Conv_2 1 1 relu_0.tmp_0 relu_1.tmp_0 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution Conv_3 1 1 relu_1.tmp_0 conv2d_213.tmp_0 0=8 1=1 5=1 6=64
BinaryOp Add_1 2 1 hardswish_0.tmp_0_splitncnn_0 conv2d_213.tmp_0 elementwise_add_0
Convolution Conv_4 1 1 elementwise_add_0 relu_2.tmp_0 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_5 1 1 relu_2.tmp_0 relu_3.tmp_0 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution Conv_6 1 1 relu_3.tmp_0 conv2d_215.tmp_0 0=16 1=1 5=1 6=512
Split splitncnn_1 1 2 conv2d_215.tmp_0 conv2d_215.tmp_0_splitncnn_0 conv2d_215.tmp_0_splitncnn_1
Convolution Conv_7 1 1 conv2d_215.tmp_0_splitncnn_1 relu_4.tmp_0 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_8 1 1 relu_4.tmp_0 relu_5.tmp_0 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution Conv_9 1 1 relu_5.tmp_0 conv2d_217.tmp_0 0=16 1=1 5=1 6=640
BinaryOp Add_2 2 1 conv2d_215.tmp_0_splitncnn_0 conv2d_217.tmp_0 elementwise_add_1
Split splitncnn_2 1 2 elementwise_add_1 elementwise_add_1_splitncnn_0 elementwise_add_1_splitncnn_1
Convolution Conv_10 1 1 elementwise_add_1_splitncnn_1 relu_6.tmp_0 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_11 1 1 relu_6.tmp_0 relu_7.tmp_0 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution Conv_12 1 1 relu_7.tmp_0 conv2d_219.tmp_0 0=24 1=1 5=1 6=960
Split splitncnn_3 1 2 conv2d_219.tmp_0 conv2d_219.tmp_0_splitncnn_0 conv2d_219.tmp_0_splitncnn_1
Convolution Conv_13 1 1 conv2d_219.tmp_0_splitncnn_1 relu_8.tmp_0 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_14 1 1 relu_8.tmp_0 relu_9.tmp_0 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_15 1 1 relu_9.tmp_0 conv2d_221.tmp_0 0=24 1=1 5=1 6=1536
BinaryOp Add_3 2 1 conv2d_219.tmp_0_splitncnn_0 conv2d_221.tmp_0 elementwise_add_2
Split splitncnn_4 1 2 elementwise_add_2 elementwise_add_2_splitncnn_0 elementwise_add_2_splitncnn_1
Convolution Conv_16 1 1 elementwise_add_2_splitncnn_1 relu_10.tmp_0 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_17 1 1 relu_10.tmp_0 relu_11.tmp_0 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_18 1 1 relu_11.tmp_0 conv2d_223.tmp_0 0=24 1=1 5=1 6=1536
BinaryOp Add_4 2 1 elementwise_add_2_splitncnn_0 conv2d_223.tmp_0 elementwise_add_3
Split splitncnn_5 1 2 elementwise_add_3 elementwise_add_3_splitncnn_0 elementwise_add_3_splitncnn_1
Convolution Conv_19 1 1 elementwise_add_3_splitncnn_1 hardswish_1.tmp_0 0=120 1=1 5=1 6=2880 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_20 1 1 hardswish_1.tmp_0 hardswish_2.tmp_0 0=120 1=3 3=2 4=1 5=1 6=1080 7=120 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_21 1 1 hardswish_2.tmp_0 conv2d_225.tmp_0 0=40 1=1 5=1 6=4800
Split splitncnn_6 1 2 conv2d_225.tmp_0 conv2d_225.tmp_0_splitncnn_0 conv2d_225.tmp_0_splitncnn_1
Convolution Conv_22 1 1 conv2d_225.tmp_0_splitncnn_1 hardswish_3.tmp_0 0=104 1=1 5=1 6=4160 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_23 1 1 hardswish_3.tmp_0 hardswish_4.tmp_0 0=104 1=3 4=1 5=1 6=936 7=104 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_24 1 1 hardswish_4.tmp_0 conv2d_227.tmp_0 0=40 1=1 5=1 6=4160
BinaryOp Add_9 2 1 conv2d_225.tmp_0_splitncnn_0 conv2d_227.tmp_0 elementwise_add_4
Split splitncnn_7 1 2 elementwise_add_4 elementwise_add_4_splitncnn_0 elementwise_add_4_splitncnn_1
Convolution Conv_25 1 1 elementwise_add_4_splitncnn_1 hardswish_5.tmp_0 0=96 1=1 5=1 6=3840 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_26 1 1 hardswish_5.tmp_0 hardswish_6.tmp_0 0=96 1=3 4=1 5=1 6=864 7=96 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_27 1 1 hardswish_6.tmp_0 conv2d_229.tmp_0 0=40 1=1 5=1 6=3840
BinaryOp Add_12 2 1 elementwise_add_4_splitncnn_0 conv2d_229.tmp_0 elementwise_add_5
Split splitncnn_8 1 2 elementwise_add_5 elementwise_add_5_splitncnn_0 elementwise_add_5_splitncnn_1
Convolution Conv_28 1 1 elementwise_add_5_splitncnn_1 hardswish_7.tmp_0 0=96 1=1 5=1 6=3840 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_29 1 1 hardswish_7.tmp_0 hardswish_8.tmp_0 0=96 1=3 4=1 5=1 6=864 7=96 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_30 1 1 hardswish_8.tmp_0 conv2d_231.tmp_0 0=40 1=1 5=1 6=3840
BinaryOp Add_15 2 1 elementwise_add_5_splitncnn_0 conv2d_231.tmp_0 elementwise_add_6
Convolution Conv_31 1 1 elementwise_add_6 hardswish_9.tmp_0 0=240 1=1 5=1 6=9600 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_32 1 1 hardswish_9.tmp_0 hardswish_10.tmp_0 0=240 1=3 4=1 5=1 6=2160 7=240 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_33 1 1 hardswish_10.tmp_0 conv2d_233.tmp_0 0=56 1=1 5=1 6=13440
Split splitncnn_9 1 2 conv2d_233.tmp_0 conv2d_233.tmp_0_splitncnn_0 conv2d_233.tmp_0_splitncnn_1
Convolution Conv_34 1 1 conv2d_233.tmp_0_splitncnn_1 hardswish_11.tmp_0 0=336 1=1 5=1 6=18816 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_35 1 1 hardswish_11.tmp_0 hardswish_12.tmp_0 0=336 1=3 4=1 5=1 6=3024 7=336 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_36 1 1 hardswish_12.tmp_0 conv2d_235.tmp_0 0=56 1=1 5=1 6=18816
BinaryOp Add_20 2 1 conv2d_233.tmp_0_splitncnn_0 conv2d_235.tmp_0 elementwise_add_7
Split splitncnn_10 1 2 elementwise_add_7 elementwise_add_7_splitncnn_0 elementwise_add_7_splitncnn_1
Convolution Conv_37 1 1 elementwise_add_7_splitncnn_1 hardswish_13.tmp_0 0=336 1=1 5=1 6=18816 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_38 1 1 hardswish_13.tmp_0 hardswish_14.tmp_0 0=336 1=5 3=2 4=2 5=1 6=8400 7=336 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_39 1 1 hardswish_14.tmp_0 conv2d_237.tmp_0 0=80 1=1 5=1 6=26880
Split splitncnn_11 1 2 conv2d_237.tmp_0 conv2d_237.tmp_0_splitncnn_0 conv2d_237.tmp_0_splitncnn_1
Convolution Conv_40 1 1 conv2d_237.tmp_0_splitncnn_1 hardswish_15.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_41 1 1 hardswish_15.tmp_0 hardswish_16.tmp_0 0=480 1=5 4=2 5=1 6=12000 7=480 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_42 1 1 hardswish_16.tmp_0 conv2d_239.tmp_0 0=80 1=1 5=1 6=38400
BinaryOp Add_25 2 1 conv2d_237.tmp_0_splitncnn_0 conv2d_239.tmp_0 elementwise_add_8
Split splitncnn_12 1 2 elementwise_add_8 elementwise_add_8_splitncnn_0 elementwise_add_8_splitncnn_1
Convolution Conv_43 1 1 elementwise_add_8_splitncnn_1 hardswish_17.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_44 1 1 hardswish_17.tmp_0 hardswish_18.tmp_0 0=480 1=5 4=2 5=1 6=12000 7=480 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_45 1 1 hardswish_18.tmp_0 conv2d_241.tmp_0 0=80 1=1 5=1 6=38400
BinaryOp Add_28 2 1 elementwise_add_8_splitncnn_0 conv2d_241.tmp_0 elementwise_add_9
Convolution Conv_46 1 1 elementwise_add_9 hardswish_19.tmp_0 0=480 1=1 5=1 6=38400 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_47 1 1 hardswish_19.tmp_0 conv2d_243.tmp_0 0=96 1=1 6=46080
Split splitncnn_13 1 3 conv2d_243.tmp_0 conv2d_243.tmp_0_splitncnn_0 conv2d_243.tmp_0_splitncnn_1 conv2d_243.tmp_0_splitncnn_2
Pooling GlobalAveragePool_0 1 1 conv2d_243.tmp_0_splitncnn_2 pool2d_0.tmp_0 0=1 4=1
InnerProduct Conv_48 1 1 pool2d_0.tmp_0 relu_12.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct Conv_49 1 1 relu_12.tmp_0 conv2d_245.tmp_0 0=96 1=1 2=2304
HardSigmoid HardSigmoid_0 1 1 conv2d_245.tmp_0 hardsigmoid_0.tmp_0
BinaryOp Mul_20 2 1 conv2d_243.tmp_0_splitncnn_1 hardsigmoid_0.tmp_0 tmp_0 0=2
BinaryOp Add_32 2 1 conv2d_243.tmp_0_splitncnn_0 tmp_0 tmp_1
Split splitncnn_14 1 2 tmp_1 tmp_1_splitncnn_0 tmp_1_splitncnn_1
Convolution Conv_50 1 1 elementwise_add_7_splitncnn_0 conv2d_246.tmp_0 0=96 1=1 6=5376
Split splitncnn_15 1 3 conv2d_246.tmp_0 conv2d_246.tmp_0_splitncnn_0 conv2d_246.tmp_0_splitncnn_1 conv2d_246.tmp_0_splitncnn_2
Pooling GlobalAveragePool_1 1 1 conv2d_246.tmp_0_splitncnn_2 pool2d_1.tmp_0 0=1 4=1
InnerProduct Conv_51 1 1 pool2d_1.tmp_0 relu_13.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct Conv_52 1 1 relu_13.tmp_0 conv2d_248.tmp_0 0=96 1=1 2=2304
HardSigmoid HardSigmoid_1 1 1 conv2d_248.tmp_0 hardsigmoid_1.tmp_0
BinaryOp Mul_21 2 1 conv2d_246.tmp_0_splitncnn_1 hardsigmoid_1.tmp_0 tmp_2 0=2
BinaryOp Add_35 2 1 conv2d_246.tmp_0_splitncnn_0 tmp_2 tmp_3
Convolution Conv_53 1 1 elementwise_add_3_splitncnn_0 conv2d_249.tmp_0 0=96 1=1 6=2304
Split splitncnn_16 1 3 conv2d_249.tmp_0 conv2d_249.tmp_0_splitncnn_0 conv2d_249.tmp_0_splitncnn_1 conv2d_249.tmp_0_splitncnn_2
Pooling GlobalAveragePool_2 1 1 conv2d_249.tmp_0_splitncnn_2 pool2d_2.tmp_0 0=1 4=1
InnerProduct Conv_54 1 1 pool2d_2.tmp_0 relu_14.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct Conv_55 1 1 relu_14.tmp_0 conv2d_251.tmp_0 0=96 1=1 2=2304
HardSigmoid HardSigmoid_2 1 1 conv2d_251.tmp_0 hardsigmoid_2.tmp_0
BinaryOp Mul_22 2 1 conv2d_249.tmp_0_splitncnn_1 hardsigmoid_2.tmp_0 tmp_4 0=2
BinaryOp Add_38 2 1 conv2d_249.tmp_0_splitncnn_0 tmp_4 tmp_5
Convolution Conv_56 1 1 elementwise_add_1_splitncnn_0 conv2d_252.tmp_0 0=96 1=1 6=1536
Split splitncnn_17 1 3 conv2d_252.tmp_0 conv2d_252.tmp_0_splitncnn_0 conv2d_252.tmp_0_splitncnn_1 conv2d_252.tmp_0_splitncnn_2
Pooling GlobalAveragePool_3 1 1 conv2d_252.tmp_0_splitncnn_2 pool2d_3.tmp_0 0=1 4=1
InnerProduct Conv_57 1 1 pool2d_3.tmp_0 relu_15.tmp_0 0=24 1=1 2=2304 9=1
InnerProduct Conv_58 1 1 relu_15.tmp_0 conv2d_254.tmp_0 0=96 1=1 2=2304
HardSigmoid HardSigmoid_3 1 1 conv2d_254.tmp_0 hardsigmoid_3.tmp_0
BinaryOp Mul_23 2 1 conv2d_252.tmp_0_splitncnn_1 hardsigmoid_3.tmp_0 tmp_6 0=2
BinaryOp Add_41 2 1 conv2d_252.tmp_0_splitncnn_0 tmp_6 tmp_7
Interp Resize_0 1 1 tmp_1_splitncnn_1 nearest_interp_v2_0.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_42 2 1 tmp_3 nearest_interp_v2_0.tmp_0 tmp_8
Split splitncnn_18 1 2 tmp_8 tmp_8_splitncnn_0 tmp_8_splitncnn_1
Interp Resize_1 1 1 tmp_8_splitncnn_1 nearest_interp_v2_1.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_43 2 1 tmp_5 nearest_interp_v2_1.tmp_0 tmp_9
Split splitncnn_19 1 2 tmp_9 tmp_9_splitncnn_0 tmp_9_splitncnn_1
Interp Resize_2 1 1 tmp_9_splitncnn_1 nearest_interp_v2_2.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_44 2 1 tmp_7 nearest_interp_v2_2.tmp_0 tmp_10
Convolution Conv_59 1 1 tmp_1_splitncnn_0 conv2d_255.tmp_0 0=24 1=3 4=1 6=20736
Split splitncnn_20 1 3 conv2d_255.tmp_0 conv2d_255.tmp_0_splitncnn_0 conv2d_255.tmp_0_splitncnn_1 conv2d_255.tmp_0_splitncnn_2
Pooling GlobalAveragePool_4 1 1 conv2d_255.tmp_0_splitncnn_2 pool2d_4.tmp_0 0=1 4=1
InnerProduct Conv_60 1 1 pool2d_4.tmp_0 relu_16.tmp_0 0=6 1=1 2=144 9=1
InnerProduct Conv_61 1 1 relu_16.tmp_0 conv2d_257.tmp_0 0=24 1=1 2=144
HardSigmoid HardSigmoid_4 1 1 conv2d_257.tmp_0 hardsigmoid_4.tmp_0
BinaryOp Mul_24 2 1 conv2d_255.tmp_0_splitncnn_1 hardsigmoid_4.tmp_0 tmp_11 0=2
BinaryOp Add_47 2 1 conv2d_255.tmp_0_splitncnn_0 tmp_11 tmp_12
Convolution Conv_62 1 1 tmp_8_splitncnn_0 conv2d_258.tmp_0 0=24 1=3 4=1 6=20736
Split splitncnn_21 1 3 conv2d_258.tmp_0 conv2d_258.tmp_0_splitncnn_0 conv2d_258.tmp_0_splitncnn_1 conv2d_258.tmp_0_splitncnn_2
Pooling GlobalAveragePool_5 1 1 conv2d_258.tmp_0_splitncnn_2 pool2d_5.tmp_0 0=1 4=1
InnerProduct Conv_63 1 1 pool2d_5.tmp_0 relu_17.tmp_0 0=6 1=1 2=144 9=1
InnerProduct Conv_64 1 1 relu_17.tmp_0 conv2d_260.tmp_0 0=24 1=1 2=144
HardSigmoid HardSigmoid_5 1 1 conv2d_260.tmp_0 hardsigmoid_5.tmp_0
BinaryOp Mul_25 2 1 conv2d_258.tmp_0_splitncnn_1 hardsigmoid_5.tmp_0 tmp_13 0=2
BinaryOp Add_50 2 1 conv2d_258.tmp_0_splitncnn_0 tmp_13 tmp_14
Convolution Conv_65 1 1 tmp_9_splitncnn_0 conv2d_261.tmp_0 0=24 1=3 4=1 6=20736
Split splitncnn_22 1 3 conv2d_261.tmp_0 conv2d_261.tmp_0_splitncnn_0 conv2d_261.tmp_0_splitncnn_1 conv2d_261.tmp_0_splitncnn_2
Pooling GlobalAveragePool_6 1 1 conv2d_261.tmp_0_splitncnn_2 pool2d_6.tmp_0 0=1 4=1
InnerProduct Conv_66 1 1 pool2d_6.tmp_0 relu_18.tmp_0 0=6 1=1 2=144 9=1
InnerProduct Conv_67 1 1 relu_18.tmp_0 conv2d_263.tmp_0 0=24 1=1 2=144
HardSigmoid HardSigmoid_6 1 1 conv2d_263.tmp_0 hardsigmoid_6.tmp_0
BinaryOp Mul_26 2 1 conv2d_261.tmp_0_splitncnn_1 hardsigmoid_6.tmp_0 tmp_15 0=2
BinaryOp Add_53 2 1 conv2d_261.tmp_0_splitncnn_0 tmp_15 tmp_16
Convolution Conv_68 1 1 tmp_10 conv2d_264.tmp_0 0=24 1=3 4=1 6=20736
Split splitncnn_23 1 3 conv2d_264.tmp_0 conv2d_264.tmp_0_splitncnn_0 conv2d_264.tmp_0_splitncnn_1 conv2d_264.tmp_0_splitncnn_2
Pooling GlobalAveragePool_7 1 1 conv2d_264.tmp_0_splitncnn_2 pool2d_7.tmp_0 0=1 4=1
InnerProduct Conv_69 1 1 pool2d_7.tmp_0 relu_19.tmp_0 0=6 1=1 2=144 9=1
InnerProduct Conv_70 1 1 relu_19.tmp_0 conv2d_266.tmp_0 0=24 1=1 2=144
HardSigmoid HardSigmoid_7 1 1 conv2d_266.tmp_0 hardsigmoid_7.tmp_0
BinaryOp Mul_27 2 1 conv2d_264.tmp_0_splitncnn_1 hardsigmoid_7.tmp_0 tmp_17 0=2
BinaryOp Add_56 2 1 conv2d_264.tmp_0_splitncnn_0 tmp_17 tmp_18
Interp Resize_3 1 1 tmp_12 nearest_interp_v2_3.tmp_0 0=1 1=8.000000e+00 2=8.000000e+00
Interp Resize_4 1 1 tmp_14 nearest_interp_v2_4.tmp_0 0=1 1=4.000000e+00 2=4.000000e+00
Interp Resize_5 1 1 tmp_16 nearest_interp_v2_5.tmp_0 0=1 1=2.000000e+00 2=2.000000e+00
Concat Concat_0 4 1 nearest_interp_v2_3.tmp_0 nearest_interp_v2_4.tmp_0 nearest_interp_v2_5.tmp_0 tmp_18 concat_0.tmp_0
Convolution Conv_71 1 1 concat_0.tmp_0 batch_norm_47.tmp_4 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution ConvTranspose_0 1 1 batch_norm_47.tmp_4 elementwise_add_10.tmp_0 0=24 1=2 3=2 5=1 6=2304
BatchNorm BatchNormalization_48 1 1 elementwise_add_10.tmp_0 batch_norm_48.tmp_3 0=24
ReLU Relu_21 1 1 batch_norm_48.tmp_3 batch_norm_48.tmp_4
Deconvolution ConvTranspose_1 1 1 batch_norm_48.tmp_4 output 0=1 1=2 3=2 5=1 6=96 9=4
================================================
FILE: app/src/main/assets/ch_PP-OCRv3_rec.param
================================================
7767517
116 127
Input input 0 1 input
Convolution Conv_0 1 1 input batch_norm_27.tmp_4 0=16 1=3 3=2 4=1 5=1 6=432 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_1 1 1 batch_norm_27.tmp_4 batch_norm_28.tmp_4 0=16 1=3 4=1 5=1 6=144 7=16 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_2 1 1 batch_norm_28.tmp_4 batch_norm_29.tmp_4 0=32 1=1 5=1 6=512 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_3 1 1 batch_norm_29.tmp_4 batch_norm_30.tmp_4 0=32 1=3 4=1 5=1 6=288 7=32 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_4 1 1 batch_norm_30.tmp_4 batch_norm_31.tmp_4 0=64 1=1 5=1 6=2048 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_5 1 1 batch_norm_31.tmp_4 batch_norm_32.tmp_4 0=64 1=3 4=1 5=1 6=576 7=64 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_6 1 1 batch_norm_32.tmp_4 batch_norm_33.tmp_4 0=64 1=1 5=1 6=4096 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_7 1 1 batch_norm_33.tmp_4 batch_norm_34.tmp_4 0=64 1=3 13=2 4=1 5=1 6=576 7=64 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_8 1 1 batch_norm_34.tmp_4 batch_norm_35.tmp_4 0=128 1=1 5=1 6=8192 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_9 1 1 batch_norm_35.tmp_4 batch_norm_36.tmp_4 0=128 1=3 4=1 5=1 6=1152 7=128 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_10 1 1 batch_norm_36.tmp_4 batch_norm_37.tmp_4 0=128 1=1 5=1 6=16384 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_11 1 1 batch_norm_37.tmp_4 batch_norm_38.tmp_4 0=128 1=3 13=2 4=1 5=1 6=1152 7=128 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_12 1 1 batch_norm_38.tmp_4 batch_norm_39.tmp_4 0=256 1=1 5=1 6=32768 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_13 1 1 batch_norm_39.tmp_4 batch_norm_40.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_14 1 1 batch_norm_40.tmp_4 batch_norm_41.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_15 1 1 batch_norm_41.tmp_4 batch_norm_42.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_16 1 1 batch_norm_42.tmp_4 batch_norm_43.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_17 1 1 batch_norm_43.tmp_4 batch_norm_44.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_18 1 1 batch_norm_44.tmp_4 batch_norm_45.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_19 1 1 batch_norm_45.tmp_4 batch_norm_46.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_20 1 1 batch_norm_46.tmp_4 batch_norm_47.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_21 1 1 batch_norm_47.tmp_4 batch_norm_48.tmp_4 0=256 1=5 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Convolution Conv_22 1 1 batch_norm_48.tmp_4 batch_norm_49.tmp_4 0=256 1=1 5=1 6=65536 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_23 1 1 batch_norm_49.tmp_4 batch_norm_50.tmp_4 0=256 1=5 13=2 4=2 5=1 6=6400 7=256 9=6 -23310=2,1.666667e-01,5.000000e-01
Split splitncnn_0 1 2 batch_norm_50.tmp_4 batch_norm_50.tmp_4_splitncnn_0 batch_norm_50.tmp_4_splitncnn_1
Pooling GlobalAveragePool_0 1 1 batch_norm_50.tmp_4_splitncnn_1 pool2d_3.tmp_0 0=1 4=1
InnerProduct Conv_24 1 1 pool2d_3.tmp_0 relu_2.tmp_0 0=64 1=1 2=16384 9=1
InnerProduct Conv_25 1 1 relu_2.tmp_0 conv2d_110.tmp_0 0=256 1=1 2=16384
HardSigmoid HardSigmoid_0 1 1 conv2d_110.tmp_0 hardsigmoid_2.tmp_0 0=1.666667e-01
BinaryOp Mul_24 2 1 batch_norm_50.tmp_4_splitncnn_0 hardsigmoid_2.tmp_0 elementwise_mul_2 0=2
Convolution Conv_26 1 1 elementwise_mul_2 batch_norm_51.tmp_4 0=512 1=1 5=1 6=131072 9=6 -23310=2,1.666667e-01,5.000000e-01
ConvolutionDepthWise Conv_27 1 1 batch_norm_51.tmp_4 batch_norm_52.tmp_4 0=512 1=5 3=2 13=1 4=2 5=1 6=12800 7=512 9=6 -23310=2,1.666667e-01,5.000000e-01
Split splitncnn_1 1 2 batch_norm_52.tmp_4 batch_norm_52.tmp_4_splitncnn_0 batch_norm_52.tmp_4_splitncnn_1
Pooling GlobalAveragePool_1 1 1 batch_norm_52.tmp_4_splitncnn_1 pool2d_4.tmp_0 0=1 4=1
InnerProduct Conv_28 1 1 pool2d_4.tmp_0 relu_3.tmp_0 0=128 1=1 2=65536 9=1
InnerProduct Conv_29 1 1 relu_3.tmp_0 conv2d_113.tmp_0 0=512 1=1 2=65536
HardSigmoid HardSigmoid_1 1 1 conv2d_113.tmp_0 hardsigmoid_3.tmp_0 0=1.666667e-01
BinaryOp Mul_27 2 1 batch_norm_52.tmp_4_splitncnn_0 hardsigmoid_3.tmp_0 elementwise_mul_3 0=2
Convolution Conv_30 1 1 elementwise_mul_3 batch_norm_53.tmp_4 0=512 1=1 5=1 6=262144 9=6 -23310=2,1.666667e-01,5.000000e-01
Pooling AveragePool_0 1 1 batch_norm_53.tmp_4 pool2d_5.tmp_0 0=1 1=2 2=2 5=1
Split splitncnn_2 1 2 pool2d_5.tmp_0 pool2d_5.tmp_0_splitncnn_0 pool2d_5.tmp_0_splitncnn_1
Convolution Conv_31 1 1 pool2d_5.tmp_0_splitncnn_1 conv2d_115.tmp_0 0=64 1=3 4=1 5=1 6=294912
Swish Mul_29 1 1 conv2d_115.tmp_0 swish_21.tmp_0
Convolution Conv_32 1 1 swish_21.tmp_0 conv2d_116.tmp_0 0=120 1=1 5=1 6=7680
Swish Mul_30 1 1 conv2d_116.tmp_0 swish_22.tmp_0
Reshape Reshape_4 1 1 swish_22.tmp_0 flatten_1.tmp_0 0=-1 1=120
Permute Transpose_0 1 1 flatten_1.tmp_0 transpose_9.tmp_0 0=1
Split splitncnn_3 1 2 transpose_9.tmp_0 transpose_9.tmp_0_splitncnn_0 transpose_9.tmp_0_splitncnn_1
LayerNorm Add_32 1 1 transpose_9.tmp_0_splitncnn_1 layer_norm_15.tmp_2 0=120 1=1.000000e-05
InnerProduct MatMul_0 1 1 layer_norm_15.tmp_2 linear_35.tmp_1 0=360 1=1 2=43200
Reshape Reshape_7 1 1 linear_35.tmp_1 reshape2_5.tmp_0 0=15 1=8 2=-1 11=3
Permute Transpose_1 1 1 reshape2_5.tmp_0 transpose_10.tmp_0 0=8
Split splitncnn_4 1 3 transpose_10.tmp_0 transpose_10.tmp_0_splitncnn_0 transpose_10.tmp_0_splitncnn_1 transpose_10.tmp_0_splitncnn_2
Crop Slice_2 1 1 transpose_10.tmp_0_splitncnn_2 Slice_2 -23309=1,0 -23310=1,1 -23311=1,0
Reshape Squeeze_0 1 1 Slice_2 transpose_10.tmp_0_slice_0 0=15 1=-1 2=8
BinaryOp Mul_32 1 1 transpose_10.tmp_0_slice_0 Mul_32 0=2 1=1 2=2.581989e-01
Crop Slice_3 1 1 transpose_10.tmp_0_splitncnn_1 Slice_3 -23309=1,1 -23310=1,2 -23311=1,0
Reshape Squeeze_1 1 1 Slice_3 transpose_10.tmp_0_slice_1 0=15 1=-1 2=8
Crop Slice_4 1 1 transpose_10.tmp_0_splitncnn_0 Slice_4 -23309=1,2 -23310=1,3 -23311=1,0
Reshape Squeeze_2 1 1 Slice_4 transpose_10.tmp_0_slice_2 0=15 1=-1 2=8
Permute Transpose_2 1 1 transpose_10.tmp_0_slice_1 transpose_11.tmp_0 0=1
MatMul MatMul_1 2 1 Mul_32 transpose_11.tmp_0 matmul_v2_4.tmp_0
Softmax Softmax_0 1 1 matmul_v2_4.tmp_0 softmax_3.tmp_0 0=-1 1=1
MatMul MatMul_2 2 1 softmax_3.tmp_0 transpose_10.tmp_0_slice_2 matmul_v2_5.tmp_0
Permute Transpose_3 1 1 matmul_v2_5.tmp_0 transpose_12.tmp_0 0=2
Reshape Reshape_8 1 1 transpose_12.tmp_0 reshape2_6.tmp_0 0=120 1=-1
InnerProduct MatMul_3 1 1 reshape2_6.tmp_0 linear_36.tmp_1 0=120 1=1 2=14400
BinaryOp Add_36 2 1 transpose_9.tmp_0_splitncnn_0 linear_36.tmp_1 tmp_7
Split splitncnn_5 1 2 tmp_7 tmp_7_splitncnn_0 tmp_7_splitncnn_1
LayerNorm Add_38 1 1 tmp_7_splitncnn_1 layer_norm_16.tmp_2 0=120 1=1.000000e-05
InnerProduct MatMul_4 1 1 layer_norm_16.tmp_2 linear_37.tmp_1 0=240 1=1 2=28800
Swish Mul_34 1 1 linear_37.tmp_1 swish_23.tmp_0
InnerProduct MatMul_5 1 1 swish_23.tmp_0 linear_38.tmp_1 0=120 1=1 2=28800
BinaryOp Add_41 2 1 tmp_7_splitncnn_0 linear_38.tmp_1 tmp_8
Split splitncnn_6 1 2 tmp_8 tmp_8_splitncnn_0 tmp_8_splitncnn_1
LayerNorm Add_43 1 1 tmp_8_splitncnn_1 layer_norm_17.tmp_2 0=120 1=1.000000e-05
InnerProduct MatMul_6 1 1 layer_norm_17.tmp_2 linear_39.tmp_1 0=360 1=1 2=43200
Reshape Reshape_13 1 1 linear_39.tmp_1 reshape2_7.tmp_0 0=15 1=8 2=-1 11=3
Permute Transpose_4 1 1 reshape2_7.tmp_0 transpose_13.tmp_0 0=8
Split splitncnn_7 1 3 transpose_13.tmp_0 transpose_13.tmp_0_splitncnn_0 transpose_13.tmp_0_splitncnn_1 transpose_13.tmp_0_splitncnn_2
Crop Slice_7 1 1 transpose_13.tmp_0_splitncnn_2 Slice_7 -23309=1,0 -23310=1,1 -23311=1,0
Reshape Squeeze_3 1 1 Slice_7 transpose_13.tmp_0_slice_0 0=15 1=-1 2=8
BinaryOp Mul_36 1 1 transpose_13.tmp_0_slice_0 Mul_36 0=2 1=1 2=2.581989e-01
Crop Slice_8 1 1 transpose_13.tmp_0_splitncnn_1 Slice_8 -23309=1,1 -23310=1,2 -23311=1,0
Reshape Squeeze_4 1 1 Slice_8 transpose_13.tmp_0_slice_1 0=15 1=-1 2=8
Crop Slice_9 1 1 transpose_13.tmp_0_splitncnn_0 Slice_9 -23309=1,2 -23310=1,3 -23311=1,0
Reshape Squeeze_5 1 1 Slice_9 transpose_13.tmp_0_slice_2 0=15 1=-1 2=8
Permute Transpose_5 1 1 transpose_13.tmp_0_slice_1 transpose_14.tmp_0 0=1
MatMul MatMul_7 2 1 Mul_36 transpose_14.tmp_0 matmul_v2_6.tmp_0
Softmax Softmax_1 1 1 matmul_v2_6.tmp_0 softmax_4.tmp_0 0=2 1=1
MatMul MatMul_8 2 1 softmax_4.tmp_0 transpose_13.tmp_0_slice_2 matmul_v2_7.tmp_0
Permute Transpose_6 1 1 matmul_v2_7.tmp_0 transpose_15.tmp_0 0=2
Reshape Reshape_14 1 1 transpose_15.tmp_0 reshape2_8.tmp_0 0=120 1=-1
InnerProduct MatMul_9 1 1 reshape2_8.tmp_0 linear_40.tmp_1 0=120 1=1 2=14400
BinaryOp Add_47 2 1 tmp_8_splitncnn_0 linear_40.tmp_1 tmp_10
Split splitncnn_8 1 2 tmp_10 tmp_10_splitncnn_0 tmp_10_splitncnn_1
LayerNorm Add_49 1 1 tmp_10_splitncnn_1 layer_norm_18.tmp_2 0=120 1=1.000000e-05
InnerProduct MatMul_10 1 1 layer_norm_18.tmp_2 linear_41.tmp_1 0=240 1=1 2=28800
Swish Mul_38 1 1 linear_41.tmp_1 swish_24.tmp_0
InnerProduct MatMul_11 1 1 swish_24.tmp_0 linear_42.tmp_1 0=120 1=1 2=28800
BinaryOp Add_52 2 1 tmp_10_splitncnn_0 linear_42.tmp_1 tmp_11
LayerNorm Add_54 1 1 tmp_11 layer_norm_19.tmp_2 0=120 1=1.000000e-06
Reshape Reshape_19 1 1 layer_norm_19.tmp_2 reshape2_9.tmp_0 0=120 1=-1 2=1
Permute Transpose_7 1 1 reshape2_9.tmp_0 transpose_16.tmp_0 0=4
Convolution Conv_33 1 1 transpose_16.tmp_0 conv2d_117.tmp_0 0=512 1=1 5=1 6=61440
Swish Mul_40 1 1 conv2d_117.tmp_0 swish_25.tmp_0
Concat Concat_1 2 1 pool2d_5.tmp_0_splitncnn_0 swish_25.tmp_0 concat_1.tmp_0
Convolution Conv_34 1 1 concat_1.tmp_0 conv2d_118.tmp_0 0=64 1=3 4=1 5=1 6=589824
Swish Mul_41 1 1 conv2d_118.tmp_0 swish_26.tmp_0
Convolution Conv_35 1 1 swish_26.tmp_0 conv2d_119.tmp_0 0=64 1=1 5=1 6=4096
Swish Mul_42 1 1 conv2d_119.tmp_0 swish_27.tmp_0
Permute Transpose_8 1 1 swish_27.tmp_0 squeeze_1.tmp_0 0=3
Squeeze Squeeze_6 1 1 squeeze_1.tmp_0 transpose_17.tmp_0 -23303=1,0
InnerProduct MatMul_12 1 1 transpose_17.tmp_0 linear_43.tmp_1 0=6625 1=1 2=424000
Softmax Softmax_2 1 1 linear_43.tmp_1 out 0=-1 1=1
================================================
FILE: app/src/main/assets/cls-sim-op.param
================================================
7767517
135 151
Input input 0 1 input
Convolution Conv_0 1 1 input 250 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish Div_9 1 1 250 258 0=1.666667e-01
Convolution Conv_10 1 1 258 261 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise Conv_13 1 1 261 264 0=8 1=3 13=2 4=1 5=1 6=72 7=8 9=1
Split splitncnn_0 1 2 264 264_splitncnn_0 264_splitncnn_1
Pooling GlobalAveragePool_16 1 1 264_splitncnn_1 265 0=1 4=1
InnerProduct Conv_17 1 1 265 267 0=2 1=1 2=16 9=1
InnerProduct Conv_19 1 1 267 268 0=8 1=1 2=16
BinaryOp Mul_21 1 1 268 270 0=2 1=1 2=1.200000e+00
HardSigmoid Div_28 1 1 270 277 0=1.666667e-01
BinaryOp Mul_29 2 1 264_splitncnn_0 277 278 0=2
Convolution Conv_30 1 1 278 280 0=8 1=1 5=1 6=64
Convolution Conv_32 1 1 280 283 0=24 1=1 5=1 6=192 9=1
ConvolutionDepthWise Conv_35 1 1 283 286 0=24 1=3 13=2 4=1 5=1 6=216 7=24 9=1
Convolution Conv_38 1 1 286 288 0=8 1=1 5=1 6=192
Split splitncnn_1 1 2 288 288_splitncnn_0 288_splitncnn_1
Convolution Conv_40 1 1 288_splitncnn_1 291 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_43 1 1 291 294 0=32 1=3 4=1 5=1 6=288 7=32 9=1
Convolution Conv_46 1 1 294 296 0=8 1=1 5=1 6=256
BinaryOp Add_48 2 1 288_splitncnn_0 296 297
Convolution Conv_49 1 1 297 299 0=32 1=1 5=1 6=256
HardSwish Div_58 1 1 299 307 0=1.666667e-01
ConvolutionDepthWise Conv_59 1 1 307 309 0=32 1=5 13=2 4=2 5=1 6=800 7=32
HardSwish Div_68 1 1 309 317 0=1.666667e-01
Split splitncnn_2 1 2 317 317_splitncnn_0 317_splitncnn_1
Pooling GlobalAveragePool_69 1 1 317_splitncnn_1 318 0=1 4=1
InnerProduct Conv_70 1 1 318 320 0=8 1=1 2=256 9=1
InnerProduct Conv_72 1 1 320 321 0=32 1=1 2=256
BinaryOp Mul_74 1 1 321 323 0=2 1=1 2=1.200000e+00
HardSigmoid Div_81 1 1 323 330 0=1.666667e-01
BinaryOp Mul_82 2 1 317_splitncnn_0 330 331 0=2
Convolution Conv_83 1 1 331 333 0=16 1=1 5=1 6=512
Split splitncnn_3 1 2 333 333_splitncnn_0 333_splitncnn_1
Convolution Conv_85 1 1 333_splitncnn_1 335 0=88 1=1 5=1 6=1408
HardSwish Div_94 1 1 335 343 0=1.666667e-01
ConvolutionDepthWise Conv_95 1 1 343 345 0=88 1=5 4=2 5=1 6=2200 7=88
HardSwish Div_104 1 1 345 353 0=1.666667e-01
Split splitncnn_4 1 2 353 353_splitncnn_0 353_splitncnn_1
Pooling GlobalAveragePool_105 1 1 353_splitncnn_1 354 0=1 4=1
InnerProduct Conv_106 1 1 354 356 0=22 1=1 2=1936 9=1
InnerProduct Conv_108 1 1 356 357 0=88 1=1 2=1936
BinaryOp Mul_110 1 1 357 359 0=2 1=1 2=1.200000e+00
HardSigmoid Div_117 1 1 359 366 0=1.666667e-01
BinaryOp Mul_118 2 1 353_splitncnn_0 366 367 0=2
Convolution Conv_119 1 1 367 369 0=16 1=1 5=1 6=1408
BinaryOp Add_121 2 1 333_splitncnn_0 369 370
Split splitncnn_5 1 2 370 370_splitncnn_0 370_splitncnn_1
Convolution Conv_122 1 1 370_splitncnn_1 372 0=88 1=1 5=1 6=1408
HardSwish Div_131 1 1 372 380 0=1.666667e-01
ConvolutionDepthWise Conv_132 1 1 380 382 0=88 1=5 4=2 5=1 6=2200 7=88
HardSwish Div_141 1 1 382 390 0=1.666667e-01
Split splitncnn_6 1 2 390 390_splitncnn_0 390_splitncnn_1
Pooling GlobalAveragePool_142 1 1 390_splitncnn_1 391 0=1 4=1
InnerProduct Conv_143 1 1 391 393 0=22 1=1 2=1936 9=1
InnerProduct Conv_145 1 1 393 394 0=88 1=1 2=1936
BinaryOp Mul_147 1 1 394 396 0=2 1=1 2=1.200000e+00
HardSigmoid Div_154 1 1 396 403 0=1.666667e-01
BinaryOp Mul_155 2 1 390_splitncnn_0 403 404 0=2
Convolution Conv_156 1 1 404 406 0=16 1=1 5=1 6=1408
BinaryOp Add_158 2 1 370_splitncnn_0 406 407
Split splitncnn_7 1 2 407 407_splitncnn_0 407_splitncnn_1
Convolution Conv_159 1 1 407_splitncnn_1 409 0=40 1=1 5=1 6=640
HardSwish Div_168 1 1 409 417 0=1.666667e-01
ConvolutionDepthWise Conv_169 1 1 417 419 0=40 1=5 4=2 5=1 6=1000 7=40
HardSwish Div_178 1 1 419 427 0=1.666667e-01
Split splitncnn_8 1 2 427 427_splitncnn_0 427_splitncnn_1
Pooling GlobalAveragePool_179 1 1 427_splitncnn_1 428 0=1 4=1
InnerProduct Conv_180 1 1 428 430 0=10 1=1 2=400 9=1
InnerProduct Conv_182 1 1 430 431 0=40 1=1 2=400
BinaryOp Mul_184 1 1 431 433 0=2 1=1 2=1.200000e+00
HardSigmoid Div_191 1 1 433 440 0=1.666667e-01
BinaryOp Mul_192 2 1 427_splitncnn_0 440 441 0=2
Convolution Conv_193 1 1 441 443 0=16 1=1 5=1 6=640
BinaryOp Add_195 2 1 407_splitncnn_0 443 444
Split splitncnn_9 1 2 444 444_splitncnn_0 444_splitncnn_1
Convolution Conv_196 1 1 444_splitncnn_1 446 0=48 1=1 5=1 6=768
HardSwish Div_205 1 1 446 454 0=1.666667e-01
ConvolutionDepthWise Conv_206 1 1 454 456 0=48 1=5 4=2 5=1 6=1200 7=48
HardSwish Div_215 1 1 456 464 0=1.666667e-01
Split splitncnn_10 1 2 464 464_splitncnn_0 464_splitncnn_1
Pooling GlobalAveragePool_216 1 1 464_splitncnn_1 465 0=1 4=1
InnerProduct Conv_217 1 1 465 467 0=12 1=1 2=576 9=1
InnerProduct Conv_219 1 1 467 468 0=48 1=1 2=576
BinaryOp Mul_221 1 1 468 470 0=2 1=1 2=1.200000e+00
HardSigmoid Div_228 1 1 470 477 0=1.666667e-01
BinaryOp Mul_229 2 1 464_splitncnn_0 477 478 0=2
Convolution Conv_230 1 1 478 480 0=16 1=1 5=1 6=768
BinaryOp Add_232 2 1 444_splitncnn_0 480 481
Convolution Conv_233 1 1 481 483 0=104 1=1 5=1 6=1664
HardSwish Div_242 1 1 483 491 0=1.666667e-01
ConvolutionDepthWise Conv_243 1 1 491 493 0=104 1=5 13=2 4=2 5=1 6=2600 7=104
HardSwish Div_252 1 1 493 501 0=1.666667e-01
Split splitncnn_11 1 2 501 501_splitncnn_0 501_splitncnn_1
Pooling GlobalAveragePool_253 1 1 501_splitncnn_1 502 0=1 4=1
InnerProduct Conv_254 1 1 502 504 0=26 1=1 2=2704 9=1
InnerProduct Conv_256 1 1 504 505 0=104 1=1 2=2704
BinaryOp Mul_258 1 1 505 507 0=2 1=1 2=1.200000e+00
HardSigmoid Div_265 1 1 507 514 0=1.666667e-01
BinaryOp Mul_266 2 1 501_splitncnn_0 514 515 0=2
Convolution Conv_267 1 1 515 517 0=32 1=1 5=1 6=3328
Split splitncnn_12 1 2 517 517_splitncnn_0 517_splitncnn_1
Convolution Conv_269 1 1 517_splitncnn_1 519 0=200 1=1 5=1 6=6400
HardSwish Div_278 1 1 519 527 0=1.666667e-01
ConvolutionDepthWise Conv_279 1 1 527 529 0=200 1=5 4=2 5=1 6=5000 7=200
HardSwish Div_288 1 1 529 537 0=1.666667e-01
Split splitncnn_13 1 2 537 537_splitncnn_0 537_splitncnn_1
Pooling GlobalAveragePool_289 1 1 537_splitncnn_1 538 0=1 4=1
InnerProduct Conv_290 1 1 538 540 0=50 1=1 2=10000 9=1
InnerProduct Conv_292 1 1 540 541 0=200 1=1 2=10000
BinaryOp Mul_294 1 1 541 543 0=2 1=1 2=1.200000e+00
HardSigmoid Div_301 1 1 543 550 0=1.666667e-01
BinaryOp Mul_302 2 1 537_splitncnn_0 550 551 0=2
Convolution Conv_303 1 1 551 553 0=32 1=1 5=1 6=6400
BinaryOp Add_305 2 1 517_splitncnn_0 553 554
Split splitncnn_14 1 2 554 554_splitncnn_0 554_splitncnn_1
Convolution Conv_306 1 1 554_splitncnn_1 556 0=200 1=1 5=1 6=6400
HardSwish Div_315 1 1 556 564 0=1.666667e-01
ConvolutionDepthWise Conv_316 1 1 564 566 0=200 1=5 4=2 5=1 6=5000 7=200
HardSwish Div_325 1 1 566 574 0=1.666667e-01
Split splitncnn_15 1 2 574 574_splitncnn_0 574_splitncnn_1
Pooling GlobalAveragePool_326 1 1 574_splitncnn_1 575 0=1 4=1
InnerProduct Conv_327 1 1 575 577 0=50 1=1 2=10000 9=1
InnerProduct Conv_329 1 1 577 578 0=200 1=1 2=10000
BinaryOp Mul_331 1 1 578 580 0=2 1=1 2=1.200000e+00
HardSigmoid Div_338 1 1 580 587 0=1.666667e-01
BinaryOp Mul_339 2 1 574_splitncnn_0 587 588 0=2
Convolution Conv_340 1 1 588 590 0=32 1=1 5=1 6=6400
BinaryOp Add_342 2 1 554_splitncnn_0 590 591
Convolution Conv_343 1 1 591 593 0=200 1=1 5=1 6=6400
HardSwish Div_352 1 1 593 601 0=1.666667e-01
Pooling MaxPool_353 1 1 601 602 1=2 2=2 5=1
Pooling GlobalAveragePool_354 1 1 602 613 0=1 4=1
InnerProduct Gemm_365 1 1 613 614 0=2 1=1 2=400
Softmax Softmax_366 1 1 614 out
================================================
FILE: app/src/main/assets/det-sim-op.param
================================================
7767517
115 131
Input input 0 1 input0
Convolution Conv_0 1 1 input0 322 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish Div_9 1 1 322 330 0=1.666667e-01
Split splitncnn_0 1 2 330 330_splitncnn_0 330_splitncnn_1
Convolution Conv_10 1 1 330_splitncnn_1 333 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise Conv_13 1 1 333 336 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution Conv_16 1 1 336 338 0=8 1=1 5=1 6=64
BinaryOp Add_18 2 1 330_splitncnn_0 338 339
Convolution Conv_19 1 1 339 342 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_22 1 1 342 345 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution Conv_25 1 1 345 347 0=16 1=1 5=1 6=512
Split splitncnn_1 1 2 347 347_splitncnn_0 347_splitncnn_1
Convolution Conv_27 1 1 347_splitncnn_1 350 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_30 1 1 350 353 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution Conv_33 1 1 353 355 0=16 1=1 5=1 6=640
BinaryOp Add_35 2 1 347_splitncnn_0 355 356
Split splitncnn_2 1 2 356 356_splitncnn_0 356_splitncnn_1
Convolution Conv_36 1 1 356_splitncnn_1 359 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_39 1 1 359 362 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution Conv_42 1 1 362 364 0=24 1=1 5=1 6=960
Split splitncnn_3 1 2 364 364_splitncnn_0 364_splitncnn_1
Convolution Conv_44 1 1 364_splitncnn_1 367 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_47 1 1 367 370 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_50 1 1 370 372 0=24 1=1 5=1 6=1536
BinaryOp Add_52 2 1 364_splitncnn_0 372 373
Split splitncnn_4 1 2 373 373_splitncnn_0 373_splitncnn_1
Convolution Conv_53 1 1 373_splitncnn_1 376 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_56 1 1 376 379 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_59 1 1 379 381 0=24 1=1 5=1 6=1536
BinaryOp Add_61 2 1 373_splitncnn_0 381 382
Split splitncnn_5 1 2 382 382_splitncnn_0 382_splitncnn_1
Convolution Conv_62 1 1 382_splitncnn_1 384 0=120 1=1 5=1 6=2880
HardSwish Div_71 1 1 384 392 0=1.666667e-01
ConvolutionDepthWise Conv_72 1 1 392 394 0=120 1=3 3=2 4=1 5=1 6=1080 7=120
HardSwish Div_81 1 1 394 402 0=1.666667e-01
Convolution Conv_82 1 1 402 404 0=40 1=1 5=1 6=4800
Split splitncnn_6 1 2 404 404_splitncnn_0 404_splitncnn_1
Convolution Conv_84 1 1 404_splitncnn_1 406 0=104 1=1 5=1 6=4160
HardSwish Div_93 1 1 406 414 0=1.666667e-01
ConvolutionDepthWise Conv_94 1 1 414 416 0=104 1=3 4=1 5=1 6=936 7=104
HardSwish Div_103 1 1 416 424 0=1.666667e-01
Convolution Conv_104 1 1 424 426 0=40 1=1 5=1 6=4160
BinaryOp Add_106 2 1 404_splitncnn_0 426 427
Split splitncnn_7 1 2 427 427_splitncnn_0 427_splitncnn_1
Convolution Conv_107 1 1 427_splitncnn_1 429 0=96 1=1 5=1 6=3840
HardSwish Div_116 1 1 429 437 0=1.666667e-01
ConvolutionDepthWise Conv_117 1 1 437 439 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish Div_126 1 1 439 447 0=1.666667e-01
Convolution Conv_127 1 1 447 449 0=40 1=1 5=1 6=3840
BinaryOp Add_129 2 1 427_splitncnn_0 449 450
Split splitncnn_8 1 2 450 450_splitncnn_0 450_splitncnn_1
Convolution Conv_130 1 1 450_splitncnn_1 452 0=96 1=1 5=1 6=3840
HardSwish Div_139 1 1 452 460 0=1.666667e-01
ConvolutionDepthWise Conv_140 1 1 460 462 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish Div_149 1 1 462 470 0=1.666667e-01
Convolution Conv_150 1 1 470 472 0=40 1=1 5=1 6=3840
BinaryOp Add_152 2 1 450_splitncnn_0 472 473
Convolution Conv_153 1 1 473 475 0=240 1=1 5=1 6=9600
HardSwish Div_162 1 1 475 483 0=1.666667e-01
ConvolutionDepthWise Conv_163 1 1 483 485 0=240 1=3 4=1 5=1 6=2160 7=240
HardSwish Div_172 1 1 485 493 0=1.666667e-01
Convolution Conv_173 1 1 493 495 0=56 1=1 5=1 6=13440
Split splitncnn_9 1 2 495 495_splitncnn_0 495_splitncnn_1
Convolution Conv_175 1 1 495_splitncnn_1 497 0=336 1=1 5=1 6=18816
HardSwish Div_184 1 1 497 505 0=1.666667e-01
ConvolutionDepthWise Conv_185 1 1 505 507 0=336 1=3 4=1 5=1 6=3024 7=336
HardSwish Div_194 1 1 507 515 0=1.666667e-01
Convolution Conv_195 1 1 515 517 0=56 1=1 5=1 6=18816
BinaryOp Add_197 2 1 495_splitncnn_0 517 518
Split splitncnn_10 1 2 518 518_splitncnn_0 518_splitncnn_1
Convolution Conv_198 1 1 518_splitncnn_1 520 0=336 1=1 5=1 6=18816
HardSwish Div_207 1 1 520 528 0=1.666667e-01
ConvolutionDepthWise Conv_208 1 1 528 530 0=336 1=5 3=2 4=2 5=1 6=8400 7=336
HardSwish Div_217 1 1 530 538 0=1.666667e-01
Convolution Conv_218 1 1 538 540 0=80 1=1 5=1 6=26880
Split splitncnn_11 1 2 540 540_splitncnn_0 540_splitncnn_1
Convolution Conv_220 1 1 540_splitncnn_1 542 0=480 1=1 5=1 6=38400
HardSwish Div_229 1 1 542 550 0=1.666667e-01
ConvolutionDepthWise Conv_230 1 1 550 552 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish Div_239 1 1 552 560 0=1.666667e-01
Convolution Conv_240 1 1 560 562 0=80 1=1 5=1 6=38400
BinaryOp Add_242 2 1 540_splitncnn_0 562 563
Split splitncnn_12 1 2 563 563_splitncnn_0 563_splitncnn_1
Convolution Conv_243 1 1 563_splitncnn_1 565 0=480 1=1 5=1 6=38400
HardSwish Div_252 1 1 565 573 0=1.666667e-01
ConvolutionDepthWise Conv_253 1 1 573 575 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish Div_262 1 1 575 583 0=1.666667e-01
Convolution Conv_263 1 1 583 585 0=80 1=1 5=1 6=38400
BinaryOp Add_265 2 1 563_splitncnn_0 585 586
Convolution Conv_266 1 1 586 588 0=480 1=1 5=1 6=38400
HardSwish Div_275 1 1 588 596 0=1.666667e-01
Convolution Conv_276 1 1 596 597 0=96 1=1 6=46080
Split splitncnn_13 1 2 597 597_splitncnn_0 597_splitncnn_1
Convolution Conv_277 1 1 518_splitncnn_0 598 0=96 1=1 6=5376
Convolution Conv_278 1 1 382_splitncnn_0 599 0=96 1=1 6=2304
Convolution Conv_279 1 1 356_splitncnn_0 600 0=96 1=1 6=1536
Interp Resize_281 1 1 597_splitncnn_1 610 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_282 2 1 598 610 611
Split splitncnn_14 1 2 611 611_splitncnn_0 611_splitncnn_1
Interp Resize_284 1 1 611_splitncnn_1 621 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_285 2 1 599 621 622
Split splitncnn_15 1 2 622 622_splitncnn_0 622_splitncnn_1
Interp Resize_287 1 1 622_splitncnn_1 632 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_288 2 1 600 632 633
Convolution Conv_289 1 1 597_splitncnn_0 634 0=24 1=3 4=1 6=20736
Convolution Conv_290 1 1 611_splitncnn_0 635 0=24 1=3 4=1 6=20736
Convolution Conv_291 1 1 622_splitncnn_0 636 0=24 1=3 4=1 6=20736
Convolution Conv_292 1 1 633 637 0=24 1=3 4=1 6=20736
Interp Resize_294 1 1 634 647 0=1 1=8.000000e+00 2=8.000000e+00
Interp Resize_296 1 1 635 657 0=1 1=4.000000e+00 2=4.000000e+00
Interp Resize_298 1 1 636 667 0=1 1=2.000000e+00 2=2.000000e+00
Concat Concat_299 4 1 647 657 667 637 668
Convolution Conv_300 1 1 668 671 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution ConvTranspose_303 1 1 671 674 0=24 1=2 3=2 5=1 6=2304 9=1
Deconvolution ConvTranspose_306 1 1 674 out1 0=1 1=2 3=2 5=1 6=96 9=4
================================================
FILE: app/src/main/assets/paddleocr_keys.txt
================================================
'
疗
绚
诚
娇
溜
题
贿
者
廖
更
纳
加
奉
公
一
就
汴
计
与
路
房
原
妇
2
0
8
-
7
其
>
:
]
,
,
骑
刈
全
消
昏
傈
安
久
钟
嗅
不
影
处
驽
蜿
资
关
椤
地
瘸
专
问
忖
票
嫉
炎
韵
要
月
田
节
陂
鄙
捌
备
拳
伺
眼
网
盎
大
傍
心
东
愉
汇
蹿
科
每
业
里
航
晏
字
平
录
先
1
3
彤
鲶
产
稍
督
腴
有
象
岳
注
绍
在
泺
文
定
核
名
水
过
理
让
偷
率
等
这
发
”
为
含
肥
酉
相
鄱
七
编
猥
锛
日
镀
蒂
掰
倒
辆
栾
栗
综
涩
州
雌
滑
馀
了
机
块
司
宰
甙
兴
矽
抚
保
用
沧
秩
如
收
息
滥
页
疑
埠
!
!
姥
异
橹
钇
向
下
跄
的
椴
沫
国
绥
獠
报
开
民
蜇
何
分
凇
长
讥
藏
掏
施
羽
中
讲
派
嘟
人
提
浼
间
世
而
古
多
倪
唇
饯
控
庚
首
赛
蜓
味
断
制
觉
技
替
艰
溢
潮
夕
钺
外
摘
枋
动
双
单
啮
户
枇
确
锦
曜
杜
或
能
效
霜
盒
然
侗
电
晁
放
步
鹃
新
杖
蜂
吒
濂
瞬
评
总
隍
对
独
合
也
是
府
青
天
诲
墙
组
滴
级
邀
帘
示
已
时
骸
仄
泅
和
遨
店
雇
疫
持
巍
踮
境
只
亨
目
鉴
崤
闲
体
泄
杂
作
般
轰
化
解
迂
诿
蛭
璀
腾
告
版
服
省
师
小
规
程
线
海
办
引
二
桧
牌
砺
洄
裴
修
图
痫
胡
许
犊
事
郛
基
柴
呼
食
研
奶
律
蛋
因
葆
察
戏
褒
戒
再
李
骁
工
貂
油
鹅
章
啄
休
场
给
睡
纷
豆
器
捎
说
敏
学
会
浒
设
诊
格
廓
查
来
霓
室
溆
¢
诡
寥
焕
舜
柒
狐
回
戟
砾
厄
实
翩
尿
五
入
径
惭
喹
股
宇
篝
|
;
美
期
云
九
祺
扮
靠
锝
槌
系
企
酰
阊
暂
蚕
忻
豁
本
羹
执
条
钦
H
獒
限
进
季
楦
于
芘
玖
铋
茯
未
答
粘
括
样
精
欠
矢
甥
帷
嵩
扣
令
仔
风
皈
行
支
部
蓉
刮
站
蜡
救
钊
汗
松
嫌
成
可
.
鹤
院
从
交
政
怕
活
调
球
局
验
髌
第
韫
谗
串
到
圆
年
米
/
*
友
忿
检
区
看
自
敢
刃
个
兹
弄
流
留
同
没
齿
星
聆
轼
湖
什
三
建
蛔
儿
椋
汕
震
颧
鲤
跟
力
情
璺
铨
陪
务
指
族
训
滦
鄣
濮
扒
商
箱
十
召
慷
辗
所
莞
管
护
臭
横
硒
嗓
接
侦
六
露
党
馋
驾
剖
高
侬
妪
幂
猗
绺
骐
央
酐
孝
筝
课
徇
缰
门
男
西
项
句
谙
瞒
秃
篇
教
碲
罚
声
呐
景
前
富
嘴
鳌
稀
免
朋
啬
睐
去
赈
鱼
住
肩
愕
速
旁
波
厅
健
茼
厥
鲟
谅
投
攸
炔
数
方
击
呋
谈
绩
别
愫
僚
躬
鹧
胪
炳
招
喇
膨
泵
蹦
毛
结
5
4
谱
识
陕
粽
婚
拟
构
且
搜
任
潘
比
郢
妨
醪
陀
桔
碘
扎
选
哈
骷
楷
亿
明
缆
脯
监
睫
逻
婵
共
赴
淝
凡
惦
及
达
揖
谩
澹
减
焰
蛹
番
祁
柏
员
禄
怡
峤
龙
白
叽
生
闯
起
细
装
谕
竟
聚
钙
上
导
渊
按
艾
辘
挡
耒
盹
饪
臀
记
邮
蕙
受
各
医
搂
普
滇
朗
茸
带
翻
酚
(
光
堤
墟
蔷
万
幻
〓
瑙
辈
昧
盏
亘
蛀
吉
铰
请
子
假
闻
税
井
诩
哨
嫂
好
面
琐
校
馊
鬣
缂
营
访
炖
占
农
缀
否
经
钚
棵
趟
张
亟
吏
茶
谨
捻
论
迸
堂
玉
信
吧
瞠
乡
姬
寺
咬
溏
苄
皿
意
赉
宝
尔
钰
艺
特
唳
踉
都
荣
倚
登
荐
丧
奇
涵
批
炭
近
符
傩
感
道
着
菊
虹
仲
众
懈
濯
颞
眺
南
释
北
缝
标
既
茗
整
撼
迤
贲
挎
耱
拒
某
妍
卫
哇
英
矶
藩
治
他
元
领
膜
遮
穗
蛾
飞
荒
棺
劫
么
市
火
温
拈
棚
洼
转
果
奕
卸
迪
伸
泳
斗
邡
侄
涨
屯
萋
胭
氡
崮
枞
惧
冒
彩
斜
手
豚
随
旭
淑
妞
形
菌
吲
沱
争
驯
歹
挟
兆
柱
传
至
包
内
响
临
红
功
弩
衡
寂
禁
老
棍
耆
渍
织
害
氵
渑
布
载
靥
嗬
虽
苹
咨
娄
库
雉
榜
帜
嘲
套
瑚
亲
簸
欧
边
6
腿
旮
抛
吹
瞳
得
镓
梗
厨
继
漾
愣
憨
士
策
窑
抑
躯
襟
脏
参
贸
言
干
绸
鳄
穷
藜
音
折
详
)
举
悍
甸
癌
黎
谴
死
罩
迁
寒
驷
袖
媒
蒋
掘
模
纠
恣
观
祖
蛆
碍
位
稿
主
澧
跌
筏
京
锏
帝
贴
证
糠
才
黄
鲸
略
炯
饱
四
出
园
犀
牧
容
汉
杆
浈
汰
瑷
造
虫
瘩
怪
驴
济
应
花
沣
谔
夙
旅
价
矿
以
考
s
u
呦
晒
巡
茅
准
肟
瓴
詹
仟
褂
译
桌
混
宁
怦
郑
抿
些
余
鄂
饴
攒
珑
群
阖
岔
琨
藓
预
环
洮
岌
宀
杲
瀵
最
常
囡
周
踊
女
鼓
袭
喉
简
范
薯
遐
疏
粱
黜
禧
法
箔
斤
遥
汝
奥
直
贞
撑
置
绱
集
她
馅
逗
钧
橱
魉
[
恙
躁
唤
9
旺
膘
待
脾
惫
购
吗
依
盲
度
瘿
蠖
俾
之
镗
拇
鲵
厝
簧
续
款
展
啃
表
剔
品
钻
腭
损
清
锶
统
涌
寸
滨
贪
链
吠
冈
伎
迥
咏
吁
览
防
迅
失
汾
阔
逵
绀
蔑
列
川
凭
努
熨
揪
利
俱
绉
抢
鸨
我
即
责
膦
易
毓
鹊
刹
玷
岿
空
嘞
绊
排
术
估
锷
违
们
苟
铜
播
肘
件
烫
审
鲂
广
像
铌
惰
铟
巳
胍
鲍
康
憧
色
恢
想
拷
尤
疳
知
S
Y
F
D
A
峄
裕
帮
握
搔
氐
氘
难
墒
沮
雨
叁
缥
悴
藐
湫
娟
苑
稠
颛
簇
后
阕
闭
蕤
缚
怎
佞
码
嘤
蔡
痊
舱
螯
帕
赫
昵
升
烬
岫
、
疵
蜻
髁
蕨
隶
烛
械
丑
盂
梁
强
鲛
由
拘
揉
劭
龟
撤
钩
呕
孛
费
妻
漂
求
阑
崖
秤
甘
通
深
补
赃
坎
床
啪
承
吼
量
暇
钼
烨
阂
擎
脱
逮
称
P
神
属
矗
华
届
狍
葑
汹
育
患
窒
蛰
佼
静
槎
运
鳗
庆
逝
曼
疱
克
代
官
此
麸
耧
蚌
晟
例
础
榛
副
测
唰
缢
迹
灬
霁
身
岁
赭
扛
又
菡
乜
雾
板
读
陷
徉
贯
郁
虑
变
钓
菜
圾
现
琢
式
乐
维
渔
浜
左
吾
脑
钡
警
T
啵
拴
偌
漱
湿
硕
止
骼
魄
积
燥
联
踢
玛
则
窿
见
振
畿
送
班
钽
您
赵
刨
印
讨
踝
籍
谡
舌
崧
汽
蔽
沪
酥
绒
怖
财
帖
肱
私
莎
勋
羔
霸
励
哼
帐
将
帅
渠
纪
婴
娩
岭
厘
滕
吻
伤
坝
冠
戊
隆
瘁
介
涧
物
黍
并
姗
奢
蹑
掣
垸
锴
命
箍
捉
病
辖
琰
眭
迩
艘
绌
繁
寅
若
毋
思
诉
类
诈
燮
轲
酮
狂
重
反
职
筱
县
委
磕
绣
奖
晋
濉
志
徽
肠
呈
獐
坻
口
片
碰
几
村
柿
劳
料
获
亩
惕
晕
厌
号
罢
池
正
鏖
煨
家
棕
复
尝
懋
蜥
锅
岛
扰
队
坠
瘾
钬
@
卧
疣
镇
譬
冰
彷
频
黯
据
垄
采
八
缪
瘫
型
熹
砰
楠
襁
箐
但
嘶
绳
啤
拍
盥
穆
傲
洗
盯
塘
怔
筛
丿
台
恒
喂
葛
永
¥
烟
酒
桦
书
砂
蚝
缉
态
瀚
袄
圳
轻
蛛
超
榧
遛
姒
奘
铮
右
荽
望
偻
卡
丶
氰
附
做
革
索
戚
坨
桷
唁
垅
榻
岐
偎
坛
莨
山
殊
微
骇
陈
爨
推
嗝
驹
澡
藁
呤
卤
嘻
糅
逛
侵
郓
酌
德
摇
※
鬃
被
慨
殡
羸
昌
泡
戛
鞋
河
宪
沿
玲
鲨
翅
哽
源
铅
语
照
邯
址
荃
佬
顺
鸳
町
霭
睾
瓢
夸
椁
晓
酿
痈
咔
侏
券
噎
湍
签
嚷
离
午
尚
社
锤
背
孟
使
浪
缦
潍
鞅
军
姹
驶
笑
鳟
鲁
》
孽
钜
绿
洱
礴
焯
椰
颖
囔
乌
孔
巴
互
性
椽
哞
聘
昨
早
暮
胶
炀
隧
低
彗
昝
铁
呓
氽
藉
喔
癖
瑗
姨
权
胱
韦
堑
蜜
酋
楝
砝
毁
靓
歙
锲
究
屋
喳
骨
辨
碑
武
鸠
宫
辜
烊
适
坡
殃
培
佩
供
走
蜈
迟
翼
况
姣
凛
浔
吃
飘
债
犟
金
促
苛
崇
坂
莳
畔
绂
兵
蠕
斋
根
砍
亢
欢
恬
崔
剁
餐
榫
快
扶
‖
濒
缠
鳜
当
彭
驭
浦
篮
昀
锆
秸
钳
弋
娣
瞑
夷
龛
苫
拱
致
%
嵊
障
隐
弑
初
娓
抉
汩
累
蓖
"
唬
助
苓
昙
押
毙
破
城
郧
逢
嚏
獭
瞻
溱
婿
赊
跨
恼
璧
萃
姻
貉
灵
炉
密
氛
陶
砸
谬
衔
点
琛
沛
枳
层
岱
诺
脍
榈
埂
征
冷
裁
打
蹴
素
瘘
逞
蛐
聊
激
腱
萘
踵
飒
蓟
吆
取
咙
簋
涓
矩
曝
挺
揣
座
你
史
舵
焱
尘
苏
笈
脚
溉
榨
诵
樊
邓
焊
义
庶
儋
蟋
蒲
赦
呷
杞
诠
豪
还
试
颓
茉
太
除
紫
逃
痴
草
充
鳕
珉
祗
墨
渭
烩
蘸
慕
璇
镶
穴
嵘
恶
骂
险
绋
幕
碉
肺
戳
刘
潞
秣
纾
潜
銮
洛
须
罘
销
瘪
汞
兮
屉
r
林
厕
质
探
划
狸
殚
善
煊
烹
〒
锈
逯
宸
辍
泱
柚
袍
远
蹋
嶙
绝
峥
娥
缍
雀
徵
认
镱
谷
=
贩
勉
撩
鄯
斐
洋
非
祚
泾
诒
饿
撬
威
晷
搭
芍
锥
笺
蓦
候
琊
档
礁
沼
卵
荠
忑
朝
凹
瑞
头
仪
弧
孵
畏
铆
突
衲
车
浩
气
茂
悖
厢
枕
酝
戴
湾
邹
飚
攘
锂
写
宵
翁
岷
无
喜
丈
挑
嗟
绛
殉
议
槽
具
醇
淞
笃
郴
阅
饼
底
壕
砚
弈
询
缕
庹
翟
零
筷
暨
舟
闺
甯
撞
麂
茌
蔼
很
珲
捕
棠
角
阉
媛
娲
诽
剿
尉
爵
睬
韩
诰
匣
危
糍
镯
立
浏
阳
少
盆
舔
擘
匪
申
尬
铣
旯
抖
赘
瓯
居
ˇ
哮
游
锭
茏
歌
坏
甚
秒
舞
沙
仗
劲
潺
阿
燧
郭
嗖
霏
忠
材
奂
耐
跺
砀
输
岖
媳
氟
极
摆
灿
今
扔
腻
枝
奎
药
熄
吨
话
q
额
慑
嘌
协
喀
壳
埭
视
著
於
愧
陲
翌
峁
颅
佛
腹
聋
侯
咎
叟
秀
颇
存
较
罪
哄
岗
扫
栏
钾
羌
己
璨
枭
霉
煌
涸
衿
键
镝
益
岢
奏
连
夯
睿
冥
均
糖
狞
蹊
稻
爸
刿
胥
煜
丽
肿
璃
掸
跚
灾
垂
樾
濑
乎
莲
窄
犹
撮
战
馄
软
络
显
鸢
胸
宾
妲
恕
埔
蝌
份
遇
巧
瞟
粒
恰
剥
桡
博
讯
凯
堇
阶
滤
卖
斌
骚
彬
兑
磺
樱
舷
两
娱
福
仃
差
找
桁
÷
净
把
阴
污
戬
雷
碓
蕲
楚
罡
焖
抽
妫
咒
仑
闱
尽
邑
菁
爱
贷
沥
鞑
牡
嗉
崴
骤
塌
嗦
订
拮
滓
捡
锻
次
坪
杩
臃
箬
融
珂
鹗
宗
枚
降
鸬
妯
阄
堰
盐
毅
必
杨
崃
俺
甬
状
莘
货
耸
菱
腼
铸
唏
痤
孚
澳
懒
溅
翘
疙
杷
淼
缙
骰
喊
悉
砻
坷
艇
赁
界
谤
纣
宴
晃
茹
归
饭
梢
铡
街
抄
肼
鬟
苯
颂
撷
戈
炒
咆
茭
瘙
负
仰
客
琉
铢
封
卑
珥
椿
镧
窨
鬲
寿
御
袤
铃
萎
砖
餮
脒
裳
肪
孕
嫣
馗
嵇
恳
氯
江
石
褶
冢
祸
阻
狈
羞
银
靳
透
咳
叼
敷
芷
啥
它
瓤
兰
痘
懊
逑
肌
往
捺
坊
甩
呻
〃
沦
忘
膻
祟
菅
剧
崆
智
坯
臧
霍
墅
攻
眯
倘
拢
骠
铐
庭
岙
瓠
′
缺
泥
迢
捶
?
?
郏
喙
掷
沌
纯
秘
种
听
绘
固
螨
团
香
盗
妒
埚
蓝
拖
旱
荞
铀
血
遏
汲
辰
叩
拽
幅
硬
惶
桀
漠
措
泼
唑
齐
肾
念
酱
虚
屁
耶
旗
砦
闵
婉
馆
拭
绅
韧
忏
窝
醋
葺
顾
辞
倜
堆
辋
逆
玟
贱
疾
董
惘
倌
锕
淘
嘀
莽
俭
笏
绑
鲷
杈
择
蟀
粥
嗯
驰
逾
案
谪
褓
胫
哩
昕
颚
鲢
绠
躺
鹄
崂
儒
俨
丝
尕
泌
啊
萸
彰
幺
吟
骄
苣
弦
脊
瑰
〈
诛
镁
析
闪
剪
侧
哟
框
螃
守
嬗
燕
狭
铈
缮
概
迳
痧
鲲
俯
售
笼
痣
扉
挖
满
咋
援
邱
扇
歪
便
玑
绦
峡
蛇
叨
〖
泽
胃
斓
喋
怂
坟
猪
该
蚬
炕
弥
赞
棣
晔
娠
挲
狡
创
疖
铕
镭
稷
挫
弭
啾
翔
粉
履
苘
哦
楼
秕
铂
土
锣
瘟
挣
栉
习
享
桢
袅
磨
桂
谦
延
坚
蔚
噗
署
谟
猬
钎
恐
嬉
雒
倦
衅
亏
璩
睹
刻
殿
王
算
雕
麻
丘
柯
骆
丸
塍
谚
添
鲈
垓
桎
蚯
芥
予
飕
镦
谌
窗
醚
菀
亮
搪
莺
蒿
羁
足
J
真
轶
悬
衷
靛
翊
掩
哒
炅
掐
冼
妮
l
谐
稚
荆
擒
犯
陵
虏
浓
崽
刍
陌
傻
孜
千
靖
演
矜
钕
煽
杰
酗
渗
伞
栋
俗
泫
戍
罕
沾
疽
灏
煦
芬
磴
叱
阱
榉
湃
蜀
叉
醒
彪
租
郡
篷
屎
良
垢
隗
弱
陨
峪
砷
掴
颁
胎
雯
绵
贬
沐
撵
隘
篙
暖
曹
陡
栓
填
臼
彦
瓶
琪
潼
哪
鸡
摩
啦
俟
锋
域
耻
蔫
疯
纹
撇
毒
绶
痛
酯
忍
爪
赳
歆
嘹
辕
烈
册
朴
钱
吮
毯
癜
娃
谀
邵
厮
炽
璞
邃
丐
追
词
瓒
忆
轧
芫
谯
喷
弟
半
冕
裙
掖
墉
绮
寝
苔
势
顷
褥
切
衮
君
佳
嫒
蚩
霞
佚
洙
逊
镖
暹
唛
&
殒
顶
碗
獗
轭
铺
蛊
废
恹
汨
崩
珍
那
杵
曲
纺
夏
薰
傀
闳
淬
姘
舀
拧
卷
楂
恍
讪
厩
寮
篪
赓
乘
灭
盅
鞣
沟
慎
挂
饺
鼾
杳
树
缨
丛
絮
娌
臻
嗳
篡
侩
述
衰
矛
圈
蚜
匕
筹
匿
濞
晨
叶
骋
郝
挚
蚴
滞
增
侍
描
瓣
吖
嫦
蟒
匾
圣
赌
毡
癞
恺
百
曳
需
篓
肮
庖
帏
卿
驿
遗
蹬
鬓
骡
歉
芎
胳
屐
禽
烦
晌
寄
媾
狄
翡
苒
船
廉
终
痞
殇
々
畦
饶
改
拆
悻
萄
£
瓿
乃
訾
桅
匮
溧
拥
纱
铍
骗
蕃
龋
缬
父
佐
疚
栎
醍
掳
蓄
x
惆
颜
鲆
榆
〔
猎
敌
暴
谥
鲫
贾
罗
玻
缄
扦
芪
癣
落
徒
臾
恿
猩
托
邴
肄
牵
春
陛
耀
刊
拓
蓓
邳
堕
寇
枉
淌
啡
湄
兽
酷
萼
碚
濠
萤
夹
旬
戮
梭
琥
椭
昔
勺
蜊
绐
晚
孺
僵
宣
摄
冽
旨
萌
忙
蚤
眉
噼
蟑
付
契
瓜
悼
颡
壁
曾
窕
颢
澎
仿
俑
浑
嵌
浣
乍
碌
褪
乱
蔟
隙
玩
剐
葫
箫
纲
围
伐
决
伙
漩
瑟
刑
肓
镳
缓
蹭
氨
皓
典
畲
坍
铑
檐
塑
洞
倬
储
胴
淳
戾
吐
灼
惺
妙
毕
珐
缈
虱
盖
羰
鸿
磅
谓
髅
娴
苴
唷
蚣
霹
抨
贤
唠
犬
誓
逍
庠
逼
麓
籼
釉
呜
碧
秧
氩
摔
霄
穸
纨
辟
妈
映
完
牛
缴
嗷
炊
恩
荔
茆
掉
紊
慌
莓
羟
阙
萁
磐
另
蕹
辱
鳐
湮
吡
吩
唐
睦
垠
舒
圜
冗
瞿
溺
芾
囱
匠
僳
汐
菩
饬
漓
黑
霰
浸
濡
窥
毂
蒡
兢
驻
鹉
芮
诙
迫
雳
厂
忐
臆
猴
鸣
蚪
栈
箕
羡
渐
莆
捍
眈
哓
趴
蹼
埕
嚣
骛
宏
淄
斑
噜
严
瑛
垃
椎
诱
压
庾
绞
焘
廿
抡
迄
棘
夫
纬
锹
眨
瞌
侠
脐
竞
瀑
孳
骧
遁
姜
颦
荪
滚
萦
伪
逸
粳
爬
锁
矣
役
趣
洒
颔
诏
逐
奸
甭
惠
攀
蹄
泛
尼
拼
阮
鹰
亚
颈
惑
勒
〉
际
肛
爷
刚
钨
丰
养
冶
鲽
辉
蔻
画
覆
皴
妊
麦
返
醉
皂
擀
〗
酶
凑
粹
悟
诀
硖
港
卜
z
杀
涕
±
舍
铠
抵
弛
段
敝
镐
奠
拂
轴
跛
袱
e
t
沉
菇
俎
薪
峦
秭
蟹
历
盟
菠
寡
液
肢
喻
染
裱
悱
抱
氙
赤
捅
猛
跑
氮
谣
仁
尺
辊
窍
烙
衍
架
擦
倏
璐
瑁
币
楞
胖
夔
趸
邛
惴
饕
虔
蝎
§
哉
贝
宽
辫
炮
扩
饲
籽
魏
菟
锰
伍
猝
末
琳
哚
蛎
邂
呀
姿
鄞
却
歧
仙
恸
椐
森
牒
寤
袒
婆
虢
雅
钉
朵
贼
欲
苞
寰
故
龚
坭
嘘
咫
礼
硷
兀
睢
汶
’
铲
烧
绕
诃
浃
钿
哺
柜
讼
颊
璁
腔
洽
咐
脲
簌
筠
镣
玮
鞠
谁
兼
姆
挥
梯
蝴
谘
漕
刷
躏
宦
弼
b
垌
劈
麟
莉
揭
笙
渎
仕
嗤
仓
配
怏
抬
错
泯
镊
孰
猿
邪
仍
秋
鼬
壹
歇
吵
炼
<
尧
射
柬
廷
胧
霾
凳
隋
肚
浮
梦
祥
株
堵
退
L
鹫
跎
凶
毽
荟
炫
栩
玳
甜
沂
鹿
顽
伯
爹
赔
蛴
徐
匡
欣
狰
缸
雹
蟆
疤
默
沤
啜
痂
衣
禅
w
i
h
辽
葳
黝
钗
停
沽
棒
馨
颌
肉
吴
硫
悯
劾
娈
马
啧
吊
悌
镑
峭
帆
瀣
涉
咸
疸
滋
泣
翦
拙
癸
钥
蜒
+
尾
庄
凝
泉
婢
渴
谊
乞
陆
锉
糊
鸦
淮
I
B
N
晦
弗
乔
庥
葡
尻
席
橡
傣
渣
拿
惩
麋
斛
缃
矮
蛏
岘
鸽
姐
膏
催
奔
镒
喱
蠡
摧
钯
胤
柠
拐
璋
鸥
卢
荡
倾
^
_
珀
逄
萧
塾
掇
贮
笆
聂
圃
冲
嵬
M
滔
笕
值
炙
偶
蜱
搐
梆
汪
蔬
腑
鸯
蹇
敞
绯
仨
祯
谆
梧
糗
鑫
啸
豺
囹
猾
巢
柄
瀛
筑
踌
沭
暗
苁
鱿
蹉
脂
蘖
牢
热
木
吸
溃
宠
序
泞
偿
拜
檩
厚
朐
毗
螳
吞
媚
朽
担
蝗
橘
畴
祈
糟
盱
隼
郜
惜
珠
裨
铵
焙
琚
唯
咚
噪
骊
丫
滢
勤
棉
呸
咣
淀
隔
蕾
窈
饨
挨
煅
短
匙
粕
镜
赣
撕
墩
酬
馁
豌
颐
抗
酣
氓
佑
搁
哭
递
耷
涡
桃
贻
碣
截
瘦
昭
镌
蔓
氚
甲
猕
蕴
蓬
散
拾
纛
狼
猷
铎
埋
旖
矾
讳
囊
糜
迈
粟
蚂
紧
鲳
瘢
栽
稼
羊
锄
斟
睁
桥
瓮
蹙
祉
醺
鼻
昱
剃
跳
篱
跷
蒜
翎
宅
晖
嗑
壑
峻
癫
屏
狠
陋
袜
途
憎
祀
莹
滟
佶
溥
臣
约
盛
峰
磁
慵
婪
拦
莅
朕
鹦
粲
裤
哎
疡
嫖
琵
窟
堪
谛
嘉
儡
鳝
斩
郾
驸
酊
妄
胜
贺
徙
傅
噌
钢
栅
庇
恋
匝
巯
邈
尸
锚
粗
佟
蛟
薹
纵
蚊
郅
绢
锐
苗
俞
篆
淆
膀
鲜
煎
诶
秽
寻
涮
刺
怀
噶
巨
褰
魅
灶
灌
桉
藕
谜
舸
薄
搀
恽
借
牯
痉
渥
愿
亓
耘
杠
柩
锔
蚶
钣
珈
喘
蹒
幽
赐
稗
晤
莱
泔
扯
肯
菪
裆
腩
豉
疆
骜
腐
倭
珏
唔
粮
亡
润
慰
伽
橄
玄
誉
醐
胆
龊
粼
塬
陇
彼
削
嗣
绾
芽
妗
垭
瘴
爽
薏
寨
龈
泠
弹
赢
漪
猫
嘧
涂
恤
圭
茧
烽
屑
痕
巾
赖
荸
凰
腮
畈
亵
蹲
偃
苇
澜
艮
换
骺
烘
苕
梓
颉
肇
哗
悄
氤
涠
葬
屠
鹭
植
竺
佯
诣
鲇
瘀
鲅
邦
移
滁
冯
耕
癔
戌
茬
沁
巩
悠
湘
洪
痹
锟
循
谋
腕
鳃
钠
捞
焉
迎
碱
伫
急
榷
奈
邝
卯
辄
皲
卟
醛
畹
忧
稳
雄
昼
缩
阈
睑
扌
耗
曦
涅
捏
瞧
邕
淖
漉
铝
耦
禹
湛
喽
莼
琅
诸
苎
纂
硅
始
嗨
傥
燃
臂
赅
嘈
呆
贵
屹
壮
肋
亍
蚀
卅
豹
腆
邬
迭
浊
}
童
螂
捐
圩
勐
触
寞
汊
壤
荫
膺
渌
芳
懿
遴
螈
泰
蓼
蛤
茜
舅
枫
朔
膝
眙
避
梅
判
鹜
璜
牍
缅
垫
藻
黔
侥
惚
懂
踩
腰
腈
札
丞
唾
慈
顿
摹
荻
琬
~
斧
沈
滂
胁
胀
幄
莜
Z
匀
鄄
掌
绰
茎
焚
赋
萱
谑
汁
铒
瞎
夺
蜗
野
娆
冀
弯
篁
懵
灞
隽
芡
脘
俐
辩
芯
掺
喏
膈
蝈
觐
悚
踹
蔗
熠
鼠
呵
抓
橼
峨
畜
缔
禾
崭
弃
熊
摒
凸
拗
穹
蒙
抒
祛
劝
闫
扳
阵
醌
踪
喵
侣
搬
仅
荧
赎
蝾
琦
买
婧
瞄
寓
皎
冻
赝
箩
莫
瞰
郊
笫
姝
筒
枪
遣
煸
袋
舆
痱
涛
母
〇
启
践
耙
绲
盘
遂
昊
搞
槿
诬
纰
泓
惨
檬
亻
越
C
o
憩
熵
祷
钒
暧
塔
阗
胰
咄
娶
魔
琶
钞
邻
扬
杉
殴
咽
弓
〆
髻
】
吭
揽
霆
拄
殖
脆
彻
岩
芝
勃
辣
剌
钝
嘎
甄
佘
皖
伦
授
徕
憔
挪
皇
庞
稔
芜
踏
溴
兖
卒
擢
饥
鳞
煲
‰
账
颗
叻
斯
捧
鳍
琮
讹
蛙
纽
谭
酸
兔
莒
睇
伟
觑
羲
嗜
宜
褐
旎
辛
卦
诘
筋
鎏
溪
挛
熔
阜
晰
鳅
丢
奚
灸
呱
献
陉
黛
鸪
甾
萨
疮
拯
洲
疹
辑
叙
恻
谒
允
柔
烂
氏
逅
漆
拎
惋
扈
湟
纭
啕
掬
擞
哥
忽
涤
鸵
靡
郗
瓷
扁
廊
怨
雏
钮
敦
E
懦
憋
汀
拚
啉
腌
岸
f
痼
瞅
尊
咀
眩
飙
忌
仝
迦
熬
毫
胯
篑
茄
腺
凄
舛
碴
锵
诧
羯
後
漏
汤
宓
仞
蚁
壶
谰
皑
铄
棰
罔
辅
晶
苦
牟
闽
\
烃
饮
聿
丙
蛳
朱
煤
涔
鳖
犁
罐
荼
砒
淦
妤
黏
戎
孑
婕
瑾
戢
钵
枣
捋
砥
衩
狙
桠
稣
阎
肃
梏
诫
孪
昶
婊
衫
嗔
侃
塞
蜃
樵
峒
貌
屿
欺
缫
阐
栖
诟
珞
荭
吝
萍
嗽
恂
啻
蜴
磬
峋
俸
豫
谎
徊
镍
韬
魇
晴
U
囟
猜
蛮
坐
囿
伴
亭
肝
佗
蝠
妃
胞
滩
榴
氖
垩
苋
砣
扪
馏
姓
轩
厉
夥
侈
禀
垒
岑
赏
钛
辐
痔
披
纸
碳
“
坞
蠓
挤
荥
沅
悔
铧
帼
蒌
蝇
a
p
y
n
g
哀
浆
瑶
凿
桶
馈
皮
奴
苜
佤
伶
晗
铱
炬
优
弊
氢
恃
甫
攥
端
锌
灰
稹
炝
曙
邋
亥
眶
碾
拉
萝
绔
捷
浍
腋
姑
菖
凌
涞
麽
锢
桨
潢
绎
镰
殆
锑
渝
铬
困
绽
觎
匈
糙
暑
裹
鸟
盔
肽
迷
綦
『
亳
佝
俘
钴
觇
骥
仆
疝
跪
婶
郯
瀹
唉
脖
踞
针
晾
忒
扼
瞩
叛
椒
疟
嗡
邗
肆
跆
玫
忡
捣
咧
唆
艄
蘑
潦
笛
阚
沸
泻
掊
菽
贫
斥
髂
孢
镂
赂
麝
鸾
屡
衬
苷
恪
叠
希
粤
爻
喝
茫
惬
郸
绻
庸
撅
碟
宄
妹
膛
叮
饵
崛
嗲
椅
冤
搅
咕
敛
尹
垦
闷
蝉
霎
勰
败
蓑
泸
肤
鹌
幌
焦
浠
鞍
刁
舰
乙
竿
裔
。
茵
函
伊
兄
丨
娜
匍
謇
莪
宥
似
蝽
翳
酪
翠
粑
薇
祢
骏
赠
叫
Q
噤
噻
竖
芗
莠
潭
俊
羿
耜
O
郫
趁
嗪
囚
蹶
芒
洁
笋
鹑
敲
硝
啶
堡
渲
揩
』
携
宿
遒
颍
扭
棱
割
萜
蔸
葵
琴
捂
饰
衙
耿
掠
募
岂
窖
涟
蔺
瘤
柞
瞪
怜
匹
距
楔
炜
哆
秦
缎
幼
茁
绪
痨
恨
楸
娅
瓦
桩
雪
嬴
伏
榔
妥
铿
拌
眠
雍
缇
‘
卓
搓
哌
觞
噩
屈
哧
髓
咦
巅
娑
侑
淫
膳
祝
勾
姊
莴
胄
疃
薛
蜷
胛
巷
芙
芋
熙
闰
勿
窃
狱
剩
钏
幢
陟
铛
慧
靴
耍
k
浙
浇
飨
惟
绗
祜
澈
啼
咪
磷
摞
诅
郦
抹
跃
壬
吕
肖
琏
颤
尴
剡
抠
凋
赚
泊
津
宕
殷
倔
氲
漫
邺
涎
怠
$
垮
荬
遵
俏
叹
噢
饽
蜘
孙
筵
疼
鞭
羧
牦
箭
潴
c
眸
祭
髯
啖
坳
愁
芩
驮
倡
巽
穰
沃
胚
怒
凤
槛
剂
趵
嫁
v
邢
灯
鄢
桐
睽
檗
锯
槟
婷
嵋
圻
诗
蕈
颠
遭
痢
芸
怯
馥
竭
锗
徜
恭
遍
籁
剑
嘱
苡
龄
僧
桑
潸
弘
澶
楹
悲
讫
愤
腥
悸
谍
椹
呢
桓
葭
攫
阀
翰
躲
敖
柑
郎
笨
橇
呃
魁
燎
脓
葩
磋
垛
玺
狮
沓
砜
蕊
锺
罹
蕉
翱
虐
闾
巫
旦
茱
嬷
枯
鹏
贡
芹
汛
矫
绁
拣
禺
佃
讣
舫
惯
乳
趋
疲
挽
岚
虾
衾
蠹
蹂
飓
氦
铖
孩
稞
瑜
壅
掀
勘
妓
畅
髋
W
庐
牲
蓿
榕
练
垣
唱
邸
菲
昆
婺
穿
绡
麒
蚱
掂
愚
泷
涪
漳
妩
娉
榄
讷
觅
旧
藤
煮
呛
柳
腓
叭
庵
烷
阡
罂
蜕
擂
猖
咿
媲
脉
【
沏
貅
黠
熏
哲
烁
坦
酵
兜
×
潇
撒
剽
珩
圹
乾
摸
樟
帽
嗒
襄
魂
轿
憬
锡
〕
喃
皆
咖
隅
脸
残
泮
袂
鹂
珊
囤
捆
咤
误
徨
闹
淙
芊
淋
怆
囗
拨
梳
渤
R
G
绨
蚓
婀
幡
狩
麾
谢
唢
裸
旌
伉
纶
裂
驳
砼
咛
澄
樨
蹈
宙
澍
倍
貔
操
勇
蟠
摈
砧
虬
够
缁
悦
藿
撸
艹
摁
淹
豇
虎
榭
ˉ
吱
d
°
喧
荀
踱
侮
奋
偕
饷
犍
惮
坑
璎
徘
宛
妆
袈
倩
窦
昂
荏
乖
K
怅
撰
鳙
牙
袁
酞
X
痿
琼
闸
雁
趾
荚
虻
涝
《
杏
韭
偈
烤
绫
鞘
卉
症
遢
蓥
诋
杭
荨
匆
竣
簪
辙
敕
虞
丹
缭
咩
黟
m
淤
瑕
咂
铉
硼
茨
嶂
痒
畸
敬
涿
粪
窘
熟
叔
嫔
盾
忱
裘
憾
梵
赡
珙
咯
娘
庙
溯
胺
葱
痪
摊
荷
卞
乒
髦
寐
铭
坩
胗
枷
爆
溟
嚼
羚
砬
轨
惊
挠
罄
竽
菏
氧
浅
楣
盼
枢
炸
阆
杯
谏
噬
淇
渺
俪
秆
墓
泪
跻
砌
痰
垡
渡
耽
釜
讶
鳎
煞
呗
韶
舶
绷
鹳
缜
旷
铊
皱
龌
檀
霖
奄
槐
艳
蝶
旋
哝
赶
骞
蚧
腊
盈
丁
`
蜚
矸
蝙
睨
嚓
僻
鬼
醴
夜
彝
磊
笔
拔
栀
糕
厦
邰
纫
逭
纤
眦
膊
馍
躇
烯
蘼
冬
诤
暄
骶
哑
瘠
」
臊
丕
愈
咱
螺
擅
跋
搏
硪
谄
笠
淡
嘿
骅
谧
鼎
皋
姚
歼
蠢
驼
耳
胬
挝
涯
狗
蒽
孓
犷
凉
芦
箴
铤
孤
嘛
坤
V
茴
朦
挞
尖
橙
诞
搴
碇
洵
浚
帚
蜍
漯
柘
嚎
讽
芭
荤
咻
祠
秉
跖
埃
吓
糯
眷
馒
惹
娼
鲑
嫩
讴
轮
瞥
靶
褚
乏
缤
宋
帧
删
驱
碎
扑
俩
俄
偏
涣
竹
噱
皙
佰
渚
唧
斡
#
镉
刀
崎
筐
佣
夭
贰
肴
峙
哔
艿
匐
牺
镛
缘
仡
嫡
劣
枸
堀
梨
簿
鸭
蒸
亦
稽
浴
{
衢
束
槲
j
阁
揍
疥
棋
潋
聪
窜
乓
睛
插
冉
阪
苍
搽
「
蟾
螟
幸
仇
樽
撂
慢
跤
幔
俚
淅
覃
觊
溶
妖
帛
侨
曰
妾
泗
·
:
瀘
風
Ë
(
)
∶
紅
紗
瑭
雲
頭
鶏
財
許
•
¥
樂
焗
麗
—
;
滙
東
榮
繪
興
…
門
業
π
楊
國
顧
é
盤
寳
Λ
龍
鳳
島
誌
緣
結
銭
萬
勝
祎
璟
優
歡
臨
時
購
=
★
藍
昇
鐵
觀
勅
農
聲
畫
兿
術
發
劉
記
專
耑
園
書
壴
種
Ο
●
褀
號
銀
匯
敟
锘
葉
橪
廣
進
蒄
鑽
阝
祙
貢
鍋
豊
夬
喆
團
閣
開
燁
賓
館
酡
沔
順
+
硚
劵
饸
陽
車
湓
復
萊
氣
軒
華
堃
迮
纟
戶
馬
學
裡
電
嶽
獨
マ
シ
サ
ジ
燘
袪
環
❤
臺
灣
専
賣
孖
聖
攝
線
▪
α
傢
俬
夢
達
莊
喬
貝
薩
劍
羅
壓
棛
饦
尃
璈
囍
醫
G
I
A
#
N
鷄
髙
嬰
啓
約
隹
潔
賴
藝
~
寶
籣
麺
嶺
√
義
網
峩
長
∧
魚
機
構
②
鳯
偉
L
B
㙟
畵
鴿
'
詩
溝
嚞
屌
藔
佧
玥
蘭
織
1
3
9
0
7
點
砭
鴨
鋪
銘
廳
弍
‧
創
湯
坶
℃
卩
骝
&
烜
荘
當
潤
扞
係
懷
碶
钅
蚨
讠
☆
叢
爲
埗
涫
塗
→
楽
現
鯨
愛
瑪
鈺
忄
悶
藥
飾
樓
視
孬
ㆍ
燚
苪
師
①
丼
锽
│
韓
標
è
兒
閏
匋
張
漢
Ü
髪
會
閑
檔
習
裝
の
峯
菘
輝
И
雞
釣
億
浐
K
O
R
8
H
E
P
T
W
D
S
C
M
F
姌
饹
»
晞
廰
ä
嵯
鷹
負
飲
絲
冚
楗
澤
綫
區
❋
←
質
靑
揚
③
滬
統
産
協
﹑
乸
畐
經
運
際
洺
岽
為
粵
諾
崋
豐
碁
ɔ
V
2
6
齋
誠
訂
´
勑
雙
陳
無
í
泩
媄
夌
刂
i
c
t
o
r
a
嘢
耄
燴
暃
壽
媽
靈
抻
體
唻
É
冮
甹
鎮
錦
ʌ
蜛
蠄
尓
駕
戀
飬
逹
倫
貴
極
Я
Й
寬
磚
嶪
郎
職
|
間
n
d
剎
伈
課
飛
橋
瘊
№
譜
骓
圗
滘
縣
粿
咅
養
濤
彳
®
%
Ⅱ
啰
㴪
見
矞
薬
糁
邨
鲮
顔
罱
З
選
話
贏
氪
俵
競
瑩
繡
枱
β
綉
á
獅
爾
™
麵
戋
淩
徳
個
劇
場
務
簡
寵
h
實
膠
轱
圖
築
嘣
樹
㸃
營
耵
孫
饃
鄺
飯
麯
遠
輸
坫
孃
乚
閃
鏢
㎡
題
廠
關
↑
爺
將
軍
連
篦
覌
參
箸
-
窠
棽
寕
夀
爰
歐
呙
閥
頡
熱
雎
垟
裟
凬
勁
帑
馕
夆
疌
枼
馮
貨
蒤
樸
彧
旸
靜
龢
暢
㐱
鳥
珺
鏡
灡
爭
堷
廚
Ó
騰
診
┅
蘇
褔
凱
頂
豕
亞
帥
嘬
⊥
仺
桖
複
饣
絡
穂
顏
棟
納
▏
濟
親
設
計
攵
埌
烺
ò
頤
燦
蓮
撻
節
講
濱
濃
娽
洳
朿
燈
鈴
護
膚
铔
過
補
Z
U
5
4
坋
闿
䖝
餘
缐
铞
貿
铪
桼
趙
鍊
[
㐂
垚
菓
揸
捲
鐘
滏
𣇉
爍
輪
燜
鴻
鮮
動
鹞
鷗
丄
慶
鉌
翥
飮
腸
⇋
漁
覺
來
熘
昴
翏
鲱
圧
鄉
萭
頔
爐
嫚
г
貭
類
聯
幛
輕
訓
鑒
夋
锨
芃
珣
䝉
扙
嵐
銷
處
ㄱ
語
誘
苝
歸
儀
燒
楿
內
粢
葒
奧
麥
礻
滿
蠔
穵
瞭
態
鱬
榞
硂
鄭
黃
煙
祐
奓
逺
*
瑄
獲
聞
薦
讀
這
樣
決
問
啟
們
執
説
轉
單
隨
唘
帶
倉
庫
還
贈
尙
皺
■
餅
產
○
∈
報
狀
楓
賠
琯
嗮
禮
`
傳
>
≤
嗞
Φ
≥
換
咭
∣
↓
曬
ε
応
寫
″
終
様
純
費
療
聨
凍
壐
郵
ü
黒
∫
製
塊
調
軽
確
撃
級
馴
Ⅲ
涇
繹
數
碼
證
狒
処
劑
<
晧
賀
衆
]
櫥
兩
陰
絶
對
鯉
憶
◎
p
e
Y
蕒
煖
頓
測
試
鼽
僑
碩
妝
帯
≈
鐡
舖
權
喫
倆
ˋ
該
悅
ā
俫
.
f
s
b
m
k
g
u
j
貼
淨
濕
針
適
備
l
/
給
謢
強
觸
衛
與
⊙
$
緯
變
⑴
⑵
⑶
㎏
殺
∩
幚
─
價
▲
離
ú
ó
飄
烏
関
閟
﹝
﹞
邏
輯
鍵
驗
訣
導
歷
屆
層
▼
儱
錄
熳
ē
艦
吋
錶
辧
飼
顯
④
禦
販
気
対
枰
閩
紀
幹
瞓
貊
淚
△
眞
墊
Ω
獻
褲
縫
緑
亜
鉅
餠
{
}
◆
蘆
薈
█
◇
溫
彈
晳
粧
犸
穩
訊
崬
凖
熥
П
舊
條
紋
圍
Ⅳ
筆
尷
難
雜
錯
綁
識
頰
鎖
艶
□
殁
殼
⑧
├
▕
鵬
ǐ
ō
ǒ
糝
綱
▎
μ
盜
饅
醬
籤
蓋
釀
鹽
據
à
ɡ
辦
◥
彐
┌
婦
獸
鲩
伱
ī
蒟
蒻
齊
袆
腦
寧
凈
妳
煥
詢
偽
謹
啫
鯽
騷
鱸
損
傷
鎻
髮
買
冏
儥
両
﹢
∞
載
喰
z
羙
悵
燙
曉
員
組
徹
艷
痠
鋼
鼙
縮
細
嚒
爯
≠
維
"
鱻
壇
厍
帰
浥
犇
薡
軎
²
應
醜
刪
緻
鶴
賜
噁
軌
尨
镔
鷺
槗
彌
葚
濛
請
溇
緹
賢
訪
獴
瑅
資
縤
陣
蕟
栢
韻
祼
恁
伢
謝
劃
涑
總
衖
踺
砋
凉
籃
駿
苼
瘋
昽
紡
驊
腎
﹗
響
杋
剛
嚴
禪
歓
槍
傘
檸
檫
炣
勢
鏜
鎢
銑
尐
減
奪
惡
θ
僮
婭
臘
ū
ì
殻
鉄
∑
蛲
焼
緖
續
紹
懮
================================================
FILE: app/src/main/assets/pdocrv2.0_det-op.param
================================================
7767517
115 131
Input input 0 1 input0
Convolution Conv_0 1 1 input0 647 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish Div_8 1 1 647 330 0=1.666667e-01
Split splitncnn_0 1 2 330 330_splitncnn_0 330_splitncnn_1
Convolution Conv_9 1 1 330_splitncnn_1 333 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise Conv_11 1 1 333 336 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Convolution Conv_13 1 1 336 656 0=8 1=1 5=1 6=64
BinaryOp Add_14 2 1 330_splitncnn_0 656 339
Convolution Conv_15 1 1 339 342 0=32 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_17 1 1 342 345 0=32 1=3 3=2 4=1 5=1 6=288 7=32 9=1
Convolution Conv_19 1 1 345 665 0=16 1=1 5=1 6=512
Split splitncnn_1 1 2 665 665_splitncnn_0 665_splitncnn_1
Convolution Conv_20 1 1 665_splitncnn_1 350 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_22 1 1 350 353 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution Conv_24 1 1 353 674 0=16 1=1 5=1 6=640
BinaryOp Add_25 2 1 665_splitncnn_0 674 356
Split splitncnn_2 1 2 356 356_splitncnn_0 356_splitncnn_1
Convolution Conv_26 1 1 356_splitncnn_1 359 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_28 1 1 359 362 0=40 1=5 3=2 4=2 5=1 6=1000 7=40 9=1
Convolution Conv_30 1 1 362 683 0=24 1=1 5=1 6=960
Split splitncnn_3 1 2 683 683_splitncnn_0 683_splitncnn_1
Convolution Conv_31 1 1 683_splitncnn_1 367 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_33 1 1 367 370 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_35 1 1 370 692 0=24 1=1 5=1 6=1536
BinaryOp Add_36 2 1 683_splitncnn_0 692 373
Split splitncnn_4 1 2 373 373_splitncnn_0 373_splitncnn_1
Convolution Conv_37 1 1 373_splitncnn_1 376 0=64 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_39 1 1 376 379 0=64 1=5 4=2 5=1 6=1600 7=64 9=1
Convolution Conv_41 1 1 379 701 0=24 1=1 5=1 6=1536
BinaryOp Add_42 2 1 373_splitncnn_0 701 382
Split splitncnn_5 1 2 382 382_splitncnn_0 382_splitncnn_1
Convolution Conv_43 1 1 382_splitncnn_1 704 0=120 1=1 5=1 6=2880
HardSwish Div_51 1 1 704 392 0=1.666667e-01
ConvolutionDepthWise Conv_52 1 1 392 707 0=120 1=3 3=2 4=1 5=1 6=1080 7=120
HardSwish Div_60 1 1 707 402 0=1.666667e-01
Convolution Conv_61 1 1 402 710 0=40 1=1 5=1 6=4800
Split splitncnn_6 1 2 710 710_splitncnn_0 710_splitncnn_1
Convolution Conv_62 1 1 710_splitncnn_1 713 0=104 1=1 5=1 6=4160
HardSwish Div_70 1 1 713 414 0=1.666667e-01
ConvolutionDepthWise Conv_71 1 1 414 716 0=104 1=3 4=1 5=1 6=936 7=104
HardSwish Div_79 1 1 716 424 0=1.666667e-01
Convolution Conv_80 1 1 424 719 0=40 1=1 5=1 6=4160
BinaryOp Add_81 2 1 710_splitncnn_0 719 427
Split splitncnn_7 1 2 427 427_splitncnn_0 427_splitncnn_1
Convolution Conv_82 1 1 427_splitncnn_1 722 0=96 1=1 5=1 6=3840
HardSwish Div_90 1 1 722 437 0=1.666667e-01
ConvolutionDepthWise Conv_91 1 1 437 725 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish Div_99 1 1 725 447 0=1.666667e-01
Convolution Conv_100 1 1 447 728 0=40 1=1 5=1 6=3840
BinaryOp Add_101 2 1 427_splitncnn_0 728 450
Split splitncnn_8 1 2 450 450_splitncnn_0 450_splitncnn_1
Convolution Conv_102 1 1 450_splitncnn_1 731 0=96 1=1 5=1 6=3840
HardSwish Div_110 1 1 731 460 0=1.666667e-01
ConvolutionDepthWise Conv_111 1 1 460 734 0=96 1=3 4=1 5=1 6=864 7=96
HardSwish Div_119 1 1 734 470 0=1.666667e-01
Convolution Conv_120 1 1 470 737 0=40 1=1 5=1 6=3840
BinaryOp Add_121 2 1 450_splitncnn_0 737 473
Convolution Conv_122 1 1 473 740 0=240 1=1 5=1 6=9600
HardSwish Div_130 1 1 740 483 0=1.666667e-01
ConvolutionDepthWise Conv_131 1 1 483 743 0=240 1=3 4=1 5=1 6=2160 7=240
HardSwish Div_139 1 1 743 493 0=1.666667e-01
Convolution Conv_140 1 1 493 746 0=56 1=1 5=1 6=13440
Split splitncnn_9 1 2 746 746_splitncnn_0 746_splitncnn_1
Convolution Conv_141 1 1 746_splitncnn_1 749 0=336 1=1 5=1 6=18816
HardSwish Div_149 1 1 749 505 0=1.666667e-01
ConvolutionDepthWise Conv_150 1 1 505 752 0=336 1=3 4=1 5=1 6=3024 7=336
HardSwish Div_158 1 1 752 515 0=1.666667e-01
Convolution Conv_159 1 1 515 755 0=56 1=1 5=1 6=18816
BinaryOp Add_160 2 1 746_splitncnn_0 755 518
Split splitncnn_10 1 2 518 518_splitncnn_0 518_splitncnn_1
Convolution Conv_161 1 1 518_splitncnn_1 758 0=336 1=1 5=1 6=18816
HardSwish Div_169 1 1 758 528 0=1.666667e-01
ConvolutionDepthWise Conv_170 1 1 528 761 0=336 1=5 3=2 4=2 5=1 6=8400 7=336
HardSwish Div_178 1 1 761 538 0=1.666667e-01
Convolution Conv_179 1 1 538 764 0=80 1=1 5=1 6=26880
Split splitncnn_11 1 2 764 764_splitncnn_0 764_splitncnn_1
Convolution Conv_180 1 1 764_splitncnn_1 767 0=480 1=1 5=1 6=38400
HardSwish Div_188 1 1 767 550 0=1.666667e-01
ConvolutionDepthWise Conv_189 1 1 550 770 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish Div_197 1 1 770 560 0=1.666667e-01
Convolution Conv_198 1 1 560 773 0=80 1=1 5=1 6=38400
BinaryOp Add_199 2 1 764_splitncnn_0 773 563
Split splitncnn_12 1 2 563 563_splitncnn_0 563_splitncnn_1
Convolution Conv_200 1 1 563_splitncnn_1 776 0=480 1=1 5=1 6=38400
HardSwish Div_208 1 1 776 573 0=1.666667e-01
ConvolutionDepthWise Conv_209 1 1 573 779 0=480 1=5 4=2 5=1 6=12000 7=480
HardSwish Div_217 1 1 779 583 0=1.666667e-01
Convolution Conv_218 1 1 583 782 0=80 1=1 5=1 6=38400
BinaryOp Add_219 2 1 563_splitncnn_0 782 586
Convolution Conv_220 1 1 586 785 0=480 1=1 5=1 6=38400
HardSwish Div_228 1 1 785 596 0=1.666667e-01
Convolution Conv_229 1 1 596 597 0=96 1=1 6=46080
Split splitncnn_13 1 2 597 597_splitncnn_0 597_splitncnn_1
Convolution Conv_230 1 1 518_splitncnn_0 598 0=96 1=1 6=5376
Convolution Conv_231 1 1 382_splitncnn_0 599 0=96 1=1 6=2304
Convolution Conv_232 1 1 356_splitncnn_0 600 0=96 1=1 6=1536
Interp Resize_234 1 1 597_splitncnn_1 605 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_235 2 1 598 605 606
Split splitncnn_14 1 2 606 606_splitncnn_0 606_splitncnn_1
Interp Resize_237 1 1 606_splitncnn_1 611 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_238 2 1 599 611 612
Split splitncnn_15 1 2 612 612_splitncnn_0 612_splitncnn_1
Interp Resize_240 1 1 612_splitncnn_1 617 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_241 2 1 600 617 618
Convolution Conv_242 1 1 597_splitncnn_0 619 0=24 1=3 4=1 6=20736
Convolution Conv_243 1 1 606_splitncnn_0 620 0=24 1=3 4=1 6=20736
Convolution Conv_244 1 1 612_splitncnn_0 621 0=24 1=3 4=1 6=20736
Convolution Conv_245 1 1 618 622 0=24 1=3 4=1 6=20736
Interp Resize_247 1 1 619 627 0=1 1=8.000000e+00 2=8.000000e+00
Interp Resize_249 1 1 620 632 0=1 1=4.000000e+00 2=4.000000e+00
Interp Resize_251 1 1 621 637 0=1 1=2.000000e+00 2=2.000000e+00
Concat Concat_252 4 1 627 632 637 622 638
Convolution Conv_253 1 1 638 641 0=24 1=3 4=1 5=1 6=20736 9=1
Deconvolution ConvTranspose_255 1 1 641 644 0=24 1=2 3=2 5=1 6=2304 9=1
Deconvolution ConvTranspose_258 1 1 644 out1 0=1 1=2 3=2 5=1 6=96 9=4
================================================
FILE: app/src/main/assets/pdocrv2.0_rec-op.param
================================================
7767517
75 77
Input input 0 1 input
Convolution Conv_0 1 1 input 779 0=16 1=3 3=2 4=1 5=1 6=432
HardSwish Div_8 1 1 779 200 0=1.666667e-01
ConvolutionDepthWise Conv_9 1 1 200 782 0=16 1=3 4=1 5=1 6=144 7=16
HardSwish Div_17 1 1 782 210 0=1.666667e-01
Convolution Conv_18 1 1 210 785 0=32 1=1 5=1 6=512
HardSwish Div_26 1 1 785 220 0=1.666667e-01
ConvolutionDepthWise Conv_27 1 1 220 788 0=32 1=3 4=1 5=1 6=288 7=32
HardSwish Div_35 1 1 788 230 0=1.666667e-01
Convolution Conv_36 1 1 230 791 0=64 1=1 5=1 6=2048
HardSwish Div_44 1 1 791 240 0=1.666667e-01
ConvolutionDepthWise Conv_45 1 1 240 794 0=64 1=3 4=1 5=1 6=576 7=64
HardSwish Div_53 1 1 794 250 0=1.666667e-01
Convolution Conv_54 1 1 250 797 0=64 1=1 5=1 6=4096
HardSwish Div_62 1 1 797 260 0=1.666667e-01
ConvolutionDepthWise Conv_63 1 1 260 800 0=64 1=3 13=2 4=1 5=1 6=576 7=64
HardSwish Div_71 1 1 800 270 0=1.666667e-01
Convolution Conv_72 1 1 270 803 0=128 1=1 5=1 6=8192
HardSwish Div_80 1 1 803 280 0=1.666667e-01
ConvolutionDepthWise Conv_81 1 1 280 806 0=128 1=3 4=1 5=1 6=1152 7=128
HardSwish Div_89 1 1 806 290 0=1.666667e-01
Convolution Conv_90 1 1 290 809 0=128 1=1 5=1 6=16384
HardSwish Div_98 1 1 809 300 0=1.666667e-01
ConvolutionDepthWise Conv_99 1 1 300 812 0=128 1=3 13=2 4=1 5=1 6=1152 7=128
HardSwish Div_107 1 1 812 310 0=1.666667e-01
Convolution Conv_108 1 1 310 815 0=256 1=1 5=1 6=32768
HardSwish Div_116 1 1 815 320 0=1.666667e-01
ConvolutionDepthWise Conv_117 1 1 320 818 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish Div_125 1 1 818 330 0=1.666667e-01
Convolution Conv_126 1 1 330 821 0=256 1=1 5=1 6=65536
HardSwish Div_134 1 1 821 340 0=1.666667e-01
ConvolutionDepthWise Conv_135 1 1 340 824 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish Div_143 1 1 824 350 0=1.666667e-01
Convolution Conv_144 1 1 350 827 0=256 1=1 5=1 6=65536
HardSwish Div_152 1 1 827 360 0=1.666667e-01
ConvolutionDepthWise Conv_153 1 1 360 830 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish Div_161 1 1 830 370 0=1.666667e-01
Convolution Conv_162 1 1 370 833 0=256 1=1 5=1 6=65536
HardSwish Div_170 1 1 833 380 0=1.666667e-01
ConvolutionDepthWise Conv_171 1 1 380 836 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish Div_179 1 1 836 390 0=1.666667e-01
Convolution Conv_180 1 1 390 839 0=256 1=1 5=1 6=65536
HardSwish Div_188 1 1 839 400 0=1.666667e-01
ConvolutionDepthWise Conv_189 1 1 400 842 0=256 1=5 4=2 5=1 6=6400 7=256
HardSwish Div_197 1 1 842 410 0=1.666667e-01
Convolution Conv_198 1 1 410 845 0=256 1=1 5=1 6=65536
HardSwish Div_206 1 1 845 420 0=1.666667e-01
ConvolutionDepthWise Conv_207 1 1 420 848 0=256 1=5 13=2 4=2 5=1 6=6400 7=256
HardSwish Div_215 1 1 848 430 0=1.666667e-01
Split splitncnn_0 1 2 430 430_splitncnn_0 430_splitncnn_1
Pooling GlobalAveragePool_216 1 1 430_splitncnn_1 431 0=1 4=1
InnerProduct Conv_217 1 1 431 433 0=64 1=1 2=16384 9=1
InnerProduct Conv_219 1 1 433 434 0=256 1=1 2=16384
HardSigmoid Div_226 1 1 434 441 0=1.666667e-01
BinaryOp Mul_227 2 1 430_splitncnn_0 441 442 0=2
Convolution Conv_228 1 1 442 851 0=512 1=1 5=1 6=131072
HardSwish Div_236 1 1 851 452 0=1.666667e-01
ConvolutionDepthWise Conv_237 1 1 452 854 0=512 1=5 4=2 5=1 6=12800 7=512
HardSwish Div_245 1 1 854 462 0=1.666667e-01
Split splitncnn_1 1 2 462 462_splitncnn_0 462_splitncnn_1
Pooling GlobalAveragePool_246 1 1 462_splitncnn_1 463 0=1 4=1
InnerProduct Conv_247 1 1 463 465 0=128 1=1 2=65536 9=1
InnerProduct Conv_249 1 1 465 466 0=512 1=1 2=65536
HardSigmoid Div_256 1 1 466 473 0=1.666667e-01
BinaryOp Mul_257 2 1 462_splitncnn_0 473 474 0=2
Convolution Conv_258 1 1 474 857 0=512 1=1 5=1 6=262144
HardSwish Div_266 1 1 857 484 0=1.666667e-01
Pooling MaxPool_267 1 1 484 485 1=2 2=2 5=1
Reshape Reshape_281 1 1 485 499 0=-1 1=512
Permute Transpose_289 1 1 499 511 0=1
LSTM LSTM_298 1 1 511 641 0=64 1=262144 2=2
LSTM LSTM_310 1 1 641 771 0=64 1=65536 2=2
InnerProduct MatMul_315 1 1 771 774 0=96 1=1 2=12288
InnerProduct MatMul_317 1 1 774 777 0=6625 1=1 2=636000
Softmax Softmax_319 1 1 777 out 0=1 1=1
================================================
FILE: app/src/main/assets/rec-sim-op.param
================================================
7767517
138 154
Input input 0 1 input
Convolution Conv_0 1 1 input 266 0=8 1=3 3=2 4=1 5=1 6=216
HardSwish Div_9 1 1 266 274 0=1.666667e-01
Convolution Conv_10 1 1 274 277 0=8 1=1 5=1 6=64 9=1
ConvolutionDepthWise Conv_13 1 1 277 280 0=8 1=3 4=1 5=1 6=72 7=8 9=1
Split splitncnn_0 1 2 280 280_splitncnn_0 280_splitncnn_1
Pooling GlobalAveragePool_16 1 1 280_splitncnn_1 281 0=1 4=1
InnerProduct Conv_17 1 1 281 283 0=2 1=1 2=16 9=1
InnerProduct Conv_19 1 1 283 284 0=8 1=1 2=16
BinaryOp Mul_21 1 1 284 286 0=2 1=1 2=1.200000e+00
HardSigmoid Div_28 1 1 286 293 0=1.666667e-01
BinaryOp Mul_29 2 1 280_splitncnn_0 293 294 0=2
Convolution Conv_30 1 1 294 296 0=8 1=1 5=1 6=64
Convolution Conv_32 1 1 296 299 0=40 1=1 5=1 6=320 9=1
ConvolutionDepthWise Conv_35 1 1 299 302 0=40 1=3 13=2 4=1 5=1 6=360 7=40 9=1
Convolution Conv_38 1 1 302 304 0=16 1=1 5=1 6=640
Split splitncnn_1 1 2 304 304_splitncnn_0 304_splitncnn_1
Convolution Conv_40 1 1 304_splitncnn_1 307 0=48 1=1 5=1 6=768 9=1
ConvolutionDepthWise Conv_43 1 1 307 310 0=48 1=3 4=1 5=1 6=432 7=48 9=1
Convolution Conv_46 1 1 310 312 0=16 1=1 5=1 6=768
BinaryOp Add_48 2 1 304_splitncnn_0 312 313
Convolution Conv_49 1 1 313 315 0=48 1=1 5=1 6=768
HardSwish Div_58 1 1 315 323 0=1.666667e-01
ConvolutionDepthWise Conv_59 1 1 323 325 0=48 1=5 13=2 4=2 5=1 6=1200 7=48
HardSwish Div_68 1 1 325 333 0=1.666667e-01
Split splitncnn_2 1 2 333 333_splitncnn_0 333_splitncnn_1
Pooling GlobalAveragePool_69 1 1 333_splitncnn_1 334 0=1 4=1
InnerProduct Conv_70 1 1 334 336 0=12 1=1 2=576 9=1
InnerProduct Conv_72 1 1 336 337 0=48 1=1 2=576
BinaryOp Mul_74 1 1 337 339 0=2 1=1 2=1.200000e+00
HardSigmoid Div_81 1 1 339 346 0=1.666667e-01
BinaryOp Mul_82 2 1 333_splitncnn_0 346 347 0=2
Convolution Conv_83 1 1 347 349 0=24 1=1 5=1 6=1152
Split splitncnn_3 1 2 349 349_splitncnn_0 349_splitncnn_1
Convolution Conv_85 1 1 349_splitncnn_1 351 0=120 1=1 5=1 6=2880
HardSwish Div_94 1 1 351 359 0=1.666667e-01
ConvolutionDepthWise Conv_95 1 1 359 361 0=120 1=5 4=2 5=1 6=3000 7=120
HardSwish Div_104 1 1 361 369 0=1.666667e-01
Split splitncnn_4 1 2 369 369_splitncnn_0 369_splitncnn_1
Pooling GlobalAveragePool_105 1 1 369_splitncnn_1 370 0=1 4=1
InnerProduct Conv_106 1 1 370 372 0=30 1=1 2=3600 9=1
InnerProduct Conv_108 1 1 372 373 0=120 1=1 2=3600
BinaryOp Mul_110 1 1 373 375 0=2 1=1 2=1.200000e+00
HardSigmoid Div_117 1 1 375 382 0=1.666667e-01
BinaryOp Mul_118 2 1 369_splitncnn_0 382 383 0=2
Convolution Conv_119 1 1 383 385 0=24 1=1 5=1 6=2880
BinaryOp Add_121 2 1 349_splitncnn_0 385 386
Split splitncnn_5 1 2 386 386_splitncnn_0 386_splitncnn_1
Convolution Conv_122 1 1 386_splitncnn_1 388 0=120 1=1 5=1 6=2880
HardSwish Div_131 1 1 388 396 0=1.666667e-01
ConvolutionDepthWise Conv_132 1 1 396 398 0=120 1=5 4=2 5=1 6=3000 7=120
HardSwish Div_141 1 1 398 406 0=1.666667e-01
Split splitncnn_6 1 2 406 406_splitncnn_0 406_splitncnn_1
Pooling GlobalAveragePool_142 1 1 406_splitncnn_1 407 0=1 4=1
InnerProduct Conv_143 1 1 407 409 0=30 1=1 2=3600 9=1
InnerProduct Conv_145 1 1 409 410 0=120 1=1 2=3600
BinaryOp Mul_147 1 1 410 412 0=2 1=1 2=1.200000e+00
HardSigmoid Div_154 1 1 412 419 0=1.666667e-01
BinaryOp Mul_155 2 1 406_splitncnn_0 419 420 0=2
Convolution Conv_156 1 1 420 422 0=24 1=1 5=1 6=2880
BinaryOp Add_158 2 1 386_splitncnn_0 422 423
Split splitncnn_7 1 2 423 423_splitncnn_0 423_splitncnn_1
Convolution Conv_159 1 1 423_splitncnn_1 425 0=64 1=1 5=1 6=1536
HardSwish Div_168 1 1 425 433 0=1.666667e-01
ConvolutionDepthWise Conv_169 1 1 433 435 0=64 1=5 4=2 5=1 6=1600 7=64
HardSwish Div_178 1 1 435 443 0=1.666667e-01
Split splitncnn_8 1 2 443 443_splitncnn_0 443_splitncnn_1
Pooling GlobalAveragePool_179 1 1 443_splitncnn_1 444 0=1 4=1
InnerProduct Conv_180 1 1 444 446 0=16 1=1 2=1024 9=1
InnerProduct Conv_182 1 1 446 447 0=64 1=1 2=1024
BinaryOp Mul_184 1 1 447 449 0=2 1=1 2=1.200000e+00
HardSigmoid Div_191 1 1 449 456 0=1.666667e-01
BinaryOp Mul_192 2 1 443_splitncnn_0 456 457 0=2
Convolution Conv_193 1 1 457 459 0=24 1=1 5=1 6=1536
BinaryOp Add_195 2 1 423_splitncnn_0 459 460
Split splitncnn_9 1 2 460 460_splitncnn_0 460_splitncnn_1
Convolution Conv_196 1 1 460_splitncnn_1 462 0=72 1=1 5=1 6=1728
HardSwish Div_205 1 1 462 470 0=1.666667e-01
ConvolutionDepthWise Conv_206 1 1 470 472 0=72 1=5 4=2 5=1 6=1800 7=72
HardSwish Div_215 1 1 472 480 0=1.666667e-01
Split splitncnn_10 1 2 480 480_splitncnn_0 480_splitncnn_1
Pooling GlobalAveragePool_216 1 1 480_splitncnn_1 481 0=1 4=1
InnerProduct Conv_217 1 1 481 483 0=18 1=1 2=1296 9=1
InnerProduct Conv_219 1 1 483 484 0=72 1=1 2=1296
BinaryOp Mul_221 1 1 484 486 0=2 1=1 2=1.200000e+00
HardSigmoid Div_228 1 1 486 493 0=1.666667e-01
BinaryOp Mul_229 2 1 480_splitncnn_0 493 494 0=2
Convolution Conv_230 1 1 494 496 0=24 1=1 5=1 6=1728
BinaryOp Add_232 2 1 460_splitncnn_0 496 497
Convolution Conv_233 1 1 497 499 0=144 1=1 5=1 6=3456
HardSwish Div_242 1 1 499 507 0=1.666667e-01
ConvolutionDepthWise Conv_243 1 1 507 509 0=144 1=5 13=2 4=2 5=1 6=3600 7=144
HardSwish Div_252 1 1 509 517 0=1.666667e-01
Split splitncnn_11 1 2 517 517_splitncnn_0 517_splitncnn_1
Pooling GlobalAveragePool_253 1 1 517_splitncnn_1 518 0=1 4=1
InnerProduct Conv_254 1 1 518 520 0=36 1=1 2=5184 9=1
InnerProduct Conv_256 1 1 520 521 0=144 1=1 2=5184
BinaryOp Mul_258 1 1 521 523 0=2 1=1 2=1.200000e+00
HardSigmoid Div_265 1 1 523 530 0=1.666667e-01
BinaryOp Mul_266 2 1 517_splitncnn_0 530 531 0=2
Convolution Conv_267 1 1 531 533 0=48 1=1 5=1 6=6912
Split splitncnn_12 1 2 533 533_splitncnn_0 533_splitncnn_1
Convolution Conv_269 1 1 533_splitncnn_1 535 0=288 1=1 5=1 6=13824
HardSwish Div_278 1 1 535 543 0=1.666667e-01
ConvolutionDepthWise Conv_279 1 1 543 545 0=288 1=5 4=2 5=1 6=7200 7=288
HardSwish Div_288 1 1 545 553 0=1.666667e-01
Split splitncnn_13 1 2 553 553_splitncnn_0 553_splitncnn_1
Pooling GlobalAveragePool_289 1 1 553_splitncnn_1 554 0=1 4=1
InnerProduct Conv_290 1 1 554 556 0=72 1=1 2=20736 9=1
InnerProduct Conv_292 1 1 556 557 0=288 1=1 2=20736
BinaryOp Mul_294 1 1 557 559 0=2 1=1 2=1.200000e+00
HardSigmoid Div_301 1 1 559 566 0=1.666667e-01
BinaryOp Mul_302 2 1 553_splitncnn_0 566 567 0=2
Convolution Conv_303 1 1 567 569 0=48 1=1 5=1 6=13824
BinaryOp Add_305 2 1 533_splitncnn_0 569 570
Split splitncnn_14 1 2 570 570_splitncnn_0 570_splitncnn_1
Convolution Conv_306 1 1 570_splitncnn_1 572 0=288 1=1 5=1 6=13824
HardSwish Div_315 1 1 572 580 0=1.666667e-01
ConvolutionDepthWise Conv_316 1 1 580 582 0=288 1=5 4=2 5=1 6=7200 7=288
HardSwish Div_325 1 1 582 590 0=1.666667e-01
Split splitncnn_15 1 2 590 590_splitncnn_0 590_splitncnn_1
Pooling GlobalAveragePool_326 1 1 590_splitncnn_1 591 0=1 4=1
InnerProduct Conv_327 1 1 591 593 0=72 1=1 2=20736 9=1
InnerProduct Conv_329 1 1 593 594 0=288 1=1 2=20736
BinaryOp Mul_331 1 1 594 596 0=2 1=1 2=1.200000e+00
HardSigmoid Div_338 1 1 596 603 0=1.666667e-01
BinaryOp Mul_339 2 1 590_splitncnn_0 603 604 0=2
Convolution Conv_340 1 1 604 606 0=48 1=1 5=1 6=13824
BinaryOp Add_342 2 1 570_splitncnn_0 606 607
Convolution Conv_343 1 1 607 609 0=288 1=1 5=1 6=13824
HardSwish Div_352 1 1 609 617 0=1.666667e-01
Pooling MaxPool_353 1 1 617 618 1=2 2=2 5=1
Reshape Squeeze_354 1 1 618 619 0=-1 1=288
Permute Transpose_362 1 1 619 631 0=1
LSTM LSTM_371 1 1 631 761 0=48 1=110592 2=2
LSTM LSTM_383 1 1 761 891 0=48 1=36864 2=2
InnerProduct MatMul_388 1 1 891 894 0=6625 1=1 2=636000
Softmax Softmax_390 1 1 894 out 0=1 1=1
================================================
FILE: app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
package com.tencent.paddleocrncnn;
import android.os.Build;
import android.Manifest;
import android.os.Environment;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.media.ExifInterface;
import android.graphics.Matrix;
import android.net.Uri;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.File;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v4.content.FileProvider;
import android.provider.MediaStore;
import android.content.pm.PackageManager;
public class MainActivity extends Activity
{
private static final int TAKE_PHOTO = 1;
private static final int SELECT_IMAGE = 2;
private ImageView imageView;
//private Bitmap bitmap = null;
private Bitmap yourSelectedImage = null;
private final String filePath = Environment.getExternalStorageDirectory() + File.separator + "output_image.jpg";
private Uri imageUri;
private PaddleOCRNcnn paddleocrncnn = new PaddleOCRNcnn();
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (grantResults != null && grantResults.length != 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
switch (requestCode) {
case 1: {
requestCamera();
}
break;
}
}
}
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
boolean ret_init = paddleocrncnn.Init(getAssets());
if (!ret_init)
{
Log.e("MainActivity", "paddleocrncnn Init failed");
}
imageView = (ImageView) findViewById(R.id.imageView);
Button buttonImage = (Button) findViewById(R.id.buttonImage);
buttonImage.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
Intent i = new Intent(Intent.ACTION_PICK);
i.setType("image/*");
startActivityForResult(i, SELECT_IMAGE);
}
});
Button buttonCamera = (Button) findViewById(R.id.buttonCamera);
buttonCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
requestPermission();
}
});
Button buttonDetect = (Button) findViewById(R.id.buttonDetect);
buttonDetect.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (yourSelectedImage == null)
return;
Bitmap bitmap = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);
PaddleOCRNcnn.Obj[] objects = paddleocrncnn.Detect(bitmap, false);
showObjects(objects);
}
});
Button buttonDetectGPU = (Button) findViewById(R.id.buttonDetectGPU);
buttonDetectGPU.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
if (yourSelectedImage == null)
return;
Bitmap bitmap = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);
PaddleOCRNcnn.Obj[] objects = paddleocrncnn.Detect(bitmap, true);
showObjects(objects);
}
});
}
private void requestPermission() {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.CAMERA}, 1);
} else {
requestCamera();
}
}
private void requestCamera() {
File outputImage = new File(filePath);
try
{
if (!outputImage.getParentFile().exists()) {
outputImage.getParentFile().mkdirs();
}
if (outputImage.exists()) {
outputImage.delete();
}
outputImage.createNewFile();
if (Build.VERSION.SDK_INT >= 24) {
imageUri = FileProvider.getUriForFile(this,
"com.tencent.paddleocrncnn.fileprovider", outputImage);
} else {
imageUri = Uri.fromFile(outputImage);
}
Intent intent = new Intent("android.media.action.IMAGE_CAPTURE");
intent.putExtra(MediaStore.EXTRA_OUTPUT, imageUri);
startActivityForResult(intent, TAKE_PHOTO);
} catch (IOException e) {
e.printStackTrace();
}
}
private void showObjects(PaddleOCRNcnn.Obj[] objects)
{
if (objects == null)
{
imageView.setImageBitmap(yourSelectedImage);
return;
}
// draw objects on bitmap
Bitmap rgba = yourSelectedImage.copy(Bitmap.Config.ARGB_8888, true);
final int[] colors = new int[] {
Color.rgb( 54, 67, 244),
Color.rgb( 99, 30, 233),
Color.rgb(176, 39, 156),
Color.rgb(183, 58, 103),
Color.rgb(181, 81, 63),
Color.rgb(243, 150, 33),
Color.rgb(244, 169, 3),
Color.rgb(212, 188, 0),
Color.rgb(136, 150, 0),
Color.rgb( 80, 175, 76),
Color.rgb( 74, 195, 139),
Color.rgb( 57, 220, 205),
Color.rgb( 59, 235, 255),
Color.rgb( 7, 193, 255),
Color.rgb( 0, 152, 255),
Color.rgb( 34, 87, 255),
Color.rgb( 72, 85, 121),
Color.rgb(158, 158, 158),
Color.rgb(139, 125, 96)
};
Canvas canvas = new Canvas(rgba);
Paint paint = new Paint();
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeWidth(4);
Paint textbgpaint = new Paint();
textbgpaint.setColor(Color.WHITE);
textbgpaint.setStyle(Paint.Style.FILL);
Paint textpaint = new Paint();
textpaint.setColor(Color.BLACK);
textpaint.setTextSize(56);
textpaint.setTextAlign(Paint.Align.LEFT);
for (int i = 0; i < objects.length; i++)
{
paint.setColor(colors[i % 19]);
//canvas.drawRect(objects[i].x, objects[i].y, objects[i].x + objects[i].w, objects[i].y + objects[i].h, paint);
canvas.drawLine(objects[i].x0,objects[i].y0,objects[i].x1,objects[i].y1,paint);
canvas.drawLine(objects[i].x1,objects[i].y1,objects[i].x2,objects[i].y2,paint);
canvas.drawLine(objects[i].x2,objects[i].y2,objects[i].x3,objects[i].y3,paint);
canvas.drawLine(objects[i].x3,objects[i].y3,objects[i].x0,objects[i].y0,paint);
// draw filled text inside image
{
String text = objects[i].label;// + " = " + String.format("%.1f", objects[i].prob * 100) + "%";
float text_width = textpaint.measureText(text);
float text_height = - textpaint.ascent() + textpaint.descent();
float x = objects[i].x0;
float y = objects[i].y0 - text_height;
if (y < 0)
y = 0;
if (x + text_width > rgba.getWidth())
x = rgba.getWidth() - text_width;
canvas.drawRect(x, y, x + text_width, y + text_height, textbgpaint);
canvas.drawText(text, x, y - textpaint.ascent(), textpaint);
}
}
imageView.setImageBitmap(rgba);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
switch (requestCode) {
case TAKE_PHOTO:
if (resultCode == RESULT_OK) {
try {
yourSelectedImage = BitmapFactory.decodeStream(getContentResolver().openInputStream(imageUri));
imageView.setImageBitmap(yourSelectedImage);
} catch (FileNotFoundException e) {
e.printStackTrace();
Log.e("MainActivity", "FileNotFoundException");
}
}
break;
case SELECT_IMAGE:
if (resultCode == RESULT_OK && null != data) {
Uri selectedImage = data.getData();
try {
if (requestCode == SELECT_IMAGE) {
yourSelectedImage = decodeUri(selectedImage);
imageView.setImageBitmap(yourSelectedImage);
}
}
catch (FileNotFoundException e) {
Log.e("MainActivity", "FileNotFoundException");
return;
}
}
default:
break;
}
}
private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException
{
// Decode image size
BitmapFactory.Options o = new BitmapFactory.Options();
o.inJustDecodeBounds = true;
BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o);
// The new size we want to scale to
final int REQUIRED_SIZE = 640;
// Find the correct scale value. It should be the power of 2.
int width_tmp = o.outWidth, height_tmp = o.outHeight;
int scale = 1;
while (true) {
if (width_tmp / 2 < REQUIRED_SIZE
|| height_tmp / 2 < REQUIRED_SIZE) {
break;
}
width_tmp /= 2;
height_tmp /= 2;
scale *= 2;
}
// Decode with inSampleSize
BitmapFactory.Options o2 = new BitmapFactory.Options();
o2.inSampleSize = scale;
Bitmap bitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2);
// Rotate according to EXIF
int rotate = 0;
try
{
ExifInterface exif = new ExifInterface(getContentResolver().openInputStream(selectedImage));
int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
switch (orientation) {
case ExifInterface.ORIENTATION_ROTATE_270:
rotate = 270;
break;
case ExifInterface.ORIENTATION_ROTATE_180:
rotate = 180;
break;
case ExifInterface.ORIENTATION_ROTATE_90:
rotate = 90;
break;
}
}
catch (IOException e)
{
Log.e("MainActivity", "ExifInterface IOException");
}
Matrix matrix = new Matrix();
matrix.postRotate(rotate);
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
}
}
================================================
FILE: app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2020 THL A29 Limited, a Tencent company. All rights reserved.
//
// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
// in compliance with the License. You may obtain a copy of the License at
//
// https://opensource.org/licenses/BSD-3-Clause
//
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
package com.tencent.paddleocrncnn;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
public class PaddleOCRNcnn
{
public native boolean Init(AssetManager mgr);
public class Obj
{
public float x0;
public float y0;
public float x1;
public float y1;
public float x2;
public float y2;
public float x3;
public float y3;
public String label;
public float prob;
}
public native Obj[] Detect(Bitmap bitmap, boolean use_gpu);
static {
System.loadLibrary("paddleocrncnn");
}
}
================================================
FILE: app/src/main/jni/CMakeLists.txt
================================================
project(paddleocrncnn)
cmake_minimum_required(VERSION 3.4.1)
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-android/sdk/native/jni)
find_package(OpenCV REQUIRED core imgproc)
set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)
add_library(paddleocrncnn SHARED paddleocr_ncnn.cpp common.cpp clipper.cpp)
target_link_libraries(paddleocrncnn ncnn ${OpenCV_LIBS} jnigraphics)
================================================
FILE: app/src/main/jni/clipper.cpp
================================================
/*******************************************************************************
* *
* Author : Angus Johnson *
* Version : 6.4.2 *
* Date : 27 February 2017 *
* Website : http://www.angusj.com *
* Copyright : Angus Johnson 2010-2017 *
* *
* License: *
* Use, modification & distribution is subject to Boost Software License Ver 1. *
* http://www.boost.org/LICENSE_1_0.txt *
* *
* Attributions: *
* The code in this library is an extension of Bala Vatti's clipping algorithm: *
* "A generic solution to polygon clipping" *
* Communications of the ACM, Vol 35, Issue 7 (July 1992) pp 56-63. *
* http://portal.acm.org/citation.cfm?id=129906 *
* *
* Computer graphics and geometric modeling: implementation and algorithms *
* By Max K. Agoston *
* Springer; 1 edition (January 4, 2005) *
* http://books.google.com/books?q=vatti+clipping+agoston *
* *
* See also: *
* "Polygon Offsetting by Computing Winding Numbers" *
* Paper no. DETC2005-85513 pp. 565-575 *
* ASME 2005 International Design Engineering Technical Conferences *
* and Computers and Information in Engineering Conference (IDETC/CIE2005) *
* September 24-28, 2005 , Long Beach, California, USA *
* http://www.me.berkeley.edu/~mcmains/pubs/DAC05OffsetPolygon.pdf *
* *
*******************************************************************************/
/*******************************************************************************
* *
* This is a translation of the Delphi Clipper library and the naming style *
* used has retained a Delphi flavour. *
* *
*******************************************************************************/
#include "clipper.hpp"
#include <cmath>
#include <vector>
#include <algorithm>
#include <stdexcept>
#include <cstring>
#include <cstdlib>
#include <ostream>
#include <functional>
namespace ClipperLib {
static double const pi = 3.141592653589793238;
static double const two_pi = pi *2;
static double const def_arc_tolerance = 0.25;
enum Direction { dRightToLeft, dLeftToRight };
static int const Unassigned = -1; //edge not currently 'owning' a solution
static int const Skip = -2; //edge that would otherwise close a path
#define HORIZONTAL (-1.0E+40)
#define TOLERANCE (1.0e-20)
#define NEAR_ZERO(val) (((val) > -TOLERANCE) && ((val) < TOLERANCE))
struct TEdge {
IntPoint Bot;
IntPoint Curr; //current (updated for every new scanbeam)
IntPoint Top;
double Dx;
PolyType PolyTyp;
EdgeSide Side; //side only refers to current side of solution poly
int WindDelta; //1 or -1 depending on winding direction
int WindCnt;
int WindCnt2; //winding count of the opposite polytype
int OutIdx;
TEdge *Next;
TEdge *Prev;
TEdge *NextInLML;
TEdge *NextInAEL;
TEdge *PrevInAEL;
TEdge *NextInSEL;
TEdge *PrevInSEL;
};
struct IntersectNode {
TEdge *Edge1;
TEdge *Edge2;
IntPoint Pt;
};
struct LocalMinimum {
cInt Y;
TEdge *LeftBound;
TEdge *RightBound;
};
struct OutPt;
//OutRec: contains a path in the clipping solution. Edges in the AEL will
//carry a pointer to an OutRec when they are part of the clipping solution.
struct OutRec {
int Idx;
bool IsHole;
bool IsOpen;
OutRec *FirstLeft; //see comments in clipper.pas
PolyNode *PolyNd;
OutPt *Pts;
OutPt *BottomPt;
};
struct OutPt {
int Idx;
IntPoint Pt;
OutPt *Next;
OutPt *Prev;
};
struct Join {
OutPt *OutPt1;
OutPt *OutPt2;
IntPoint OffPt;
};
struct LocMinSorter
{
inline bool operator()(const LocalMinimum& locMin1, const LocalMinimum& locMin2)
{
return locMin2.Y < locMin1.Y;
}
};
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
inline cInt Round(double val)
{
if ((val < 0)) return static_cast<cInt>(val - 0.5);
else return static_cast<cInt>(val + 0.5);
}
//------------------------------------------------------------------------------
inline cInt Abs(cInt val)
{
return val < 0 ? -val : val;
}
//------------------------------------------------------------------------------
// PolyTree methods ...
//------------------------------------------------------------------------------
void PolyTree::Clear()
{
for (PolyNodes::size_type i = 0; i < AllNodes.size(); ++i)
delete AllNodes[i];
AllNodes.resize(0);
Childs.resize(0);
}
//------------------------------------------------------------------------------
PolyNode* PolyTree::GetFirst() const
{
if (!Childs.empty())
return Childs[0];
else
return 0;
}
//------------------------------------------------------------------------------
int PolyTree::Total() const
{
int result = (int)AllNodes.size();
//with negative offsets, ignore the hidden outer polygon ...
if (result > 0 && Childs[0] != AllNodes[0]) result--;
return result;
}
//------------------------------------------------------------------------------
// PolyNode methods ...
//------------------------------------------------------------------------------
PolyNode::PolyNode(): Parent(0), Index(0), m_IsOpen(false)
{
}
//------------------------------------------------------------------------------
int PolyNode::ChildCount() const
{
return (int)Childs.size();
}
//------------------------------------------------------------------------------
void PolyNode::AddChild(PolyNode& child)
{
unsigned cnt = (unsigned)Childs.size();
Childs.push_back(&child);
child.Parent = this;
child.Index = cnt;
}
//------------------------------------------------------------------------------
PolyNode* PolyNode::GetNext() const
{
if (!Childs.empty())
return Childs[0];
else
return GetNextSiblingUp();
}
//------------------------------------------------------------------------------
PolyNode* PolyNode::GetNextSiblingUp() const
{
if (!Parent) //protects against PolyTree.GetNextSiblingUp()
return 0;
else if (Index == Parent->Childs.size() - 1)
return Parent->GetNextSiblingUp();
else
return Parent->Childs[Index + 1];
}
//------------------------------------------------------------------------------
bool PolyNode::IsHole() const
{
bool result = true;
PolyNode* node = Parent;
while (node)
{
result = !result;
node = node->Parent;
}
return result;
}
//------------------------------------------------------------------------------
bool PolyNode::IsOpen() const
{
return m_IsOpen;
}
//------------------------------------------------------------------------------
#ifndef use_int32
//------------------------------------------------------------------------------
// Int128 class (enables safe math on signed 64bit integers)
// eg Int128 val1((long64)9223372036854775807); //ie 2^63 -1
// Int128 val2((long64)9223372036854775807);
// Int128 val3 = val1 * val2;
// val3.AsString => "85070591730234615847396907784232501249" (8.5e+37)
//------------------------------------------------------------------------------
class Int128
{
public:
ulong64 lo;
long64 hi;
Int128(long64 _lo = 0)
{
lo = (ulong64)_lo;
if (_lo < 0) hi = -1; else hi = 0;
}
Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
Int128& operator = (const long64 &val)
{
lo = (ulong64)val;
if (val < 0) hi = -1; else hi = 0;
return *this;
}
bool operator == (const Int128 &val) const
{return (hi == val.hi && lo == val.lo);}
bool operator != (const Int128 &val) const
{ return !(*this == val);}
bool operator > (const Int128 &val) const
{
if (hi != val.hi)
return hi > val.hi;
else
return lo > val.lo;
}
bool operator < (const Int128 &val) const
{
if (hi != val.hi)
return hi < val.hi;
else
return lo < val.lo;
}
bool operator >= (const Int128 &val) const
{ return !(*this < val);}
bool operator <= (const Int128 &val) const
{ return !(*this > val);}
Int128& operator += (const Int128 &rhs)
{
hi += rhs.hi;
lo += rhs.lo;
if (lo < rhs.lo) hi++;
return *this;
}
Int128 operator + (const Int128 &rhs) const
{
Int128 result(*this);
result+= rhs;
return result;
}
Int128& operator -= (const Int128 &rhs)
{
*this += -rhs;
return *this;
}
Int128 operator - (const Int128 &rhs) const
{
Int128 result(*this);
result -= rhs;
return result;
}
Int128 operator-() const //unary negation
{
if (lo == 0)
return Int128(-hi, 0);
else
return Int128(~hi, ~lo + 1);
}
operator double() const
{
const double shift64 = 18446744073709551616.0; //2^64
if (hi < 0)
{
if (lo == 0) return (double)hi * shift64;
else return -(double)(~lo + ~hi * shift64);
}
else
return (double)(lo + hi * shift64);
}
};
//------------------------------------------------------------------------------
Int128 Int128Mul (long64 lhs, long64 rhs)
{
bool negate = (lhs < 0) != (rhs < 0);
if (lhs < 0) lhs = -lhs;
ulong64 int1Hi = ulong64(lhs) >> 32;
ulong64 int1Lo = ulong64(lhs & 0xFFFFFFFF);
if (rhs < 0) rhs = -rhs;
ulong64 int2Hi = ulong64(rhs) >> 32;
ulong64 int2Lo = ulong64(rhs & 0xFFFFFFFF);
//nb: see comments in clipper.pas
ulong64 a = int1Hi * int2Hi;
ulong64 b = int1Lo * int2Lo;
ulong64 c = int1Hi * int2Lo + int1Lo * int2Hi;
Int128 tmp;
tmp.hi = long64(a + (c >> 32));
tmp.lo = long64(c << 32);
tmp.lo += long64(b);
if (tmp.lo < b) tmp.hi++;
if (negate) tmp = -tmp;
return tmp;
};
#endif
//------------------------------------------------------------------------------
// Miscellaneous global functions
//------------------------------------------------------------------------------
bool Orientation(const Path &poly)
{
return Area(poly) >= 0;
}
//------------------------------------------------------------------------------
double Area(const Path &poly)
{
int size = (int)poly.size();
if (size < 3) return 0;
double a = 0;
for (int i = 0, j = size -1; i < size; ++i)
{
a += ((double)poly[j].X + poly[i].X) * ((double)poly[j].Y - poly[i].Y);
j = i;
}
return -a * 0.5;
}
//------------------------------------------------------------------------------
double Area(const OutPt *op)
{
const OutPt *startOp = op;
if (!op) return 0;
double a = 0;
do {
a += (double)(op->Prev->Pt.X + op->Pt.X) * (double)(op->Prev->Pt.Y - op->Pt.Y);
op = op->Next;
} while (op != startOp);
return a * 0.5;
}
//------------------------------------------------------------------------------
double Area(const OutRec &outRec)
{
return Area(outRec.Pts);
}
//------------------------------------------------------------------------------
bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
{
OutPt *pp2 = pp;
do
{
if (pp2->Pt == Pt) return true;
pp2 = pp2->Next;
}
while (pp2 != pp);
return false;
}
//------------------------------------------------------------------------------
//See "The Point in Polygon Problem for Arbitrary Polygons" by Hormann & Agathos
//http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.5498&rep=rep1&type=pdf
int PointInPolygon(const IntPoint &pt, const Path &path)
{
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary
int result = 0;
size_t cnt = path.size();
if (cnt < 3) return 0;
IntPoint ip = path[0];
for(size_t i = 1; i <= cnt; ++i)
{
IntPoint ipNext = (i == cnt ? path[0] : path[i]);
if (ipNext.Y == pt.Y)
{
if ((ipNext.X == pt.X) || (ip.Y == pt.Y &&
((ipNext.X > pt.X) == (ip.X < pt.X)))) return -1;
}
if ((ip.Y < pt.Y) != (ipNext.Y < pt.Y))
{
if (ip.X >= pt.X)
{
if (ipNext.X > pt.X) result = 1 - result;
else
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
} else
{
if (ipNext.X > pt.X)
{
double d = (double)(ip.X - pt.X) * (ipNext.Y - pt.Y) -
(double)(ipNext.X - pt.X) * (ip.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (ipNext.Y > ip.Y)) result = 1 - result;
}
}
}
ip = ipNext;
}
return result;
}
//------------------------------------------------------------------------------
int PointInPolygon (const IntPoint &pt, OutPt *op)
{
//returns 0 if false, +1 if true, -1 if pt ON polygon boundary
int result = 0;
OutPt* startOp = op;
for(;;)
{
if (op->Next->Pt.Y == pt.Y)
{
if ((op->Next->Pt.X == pt.X) || (op->Pt.Y == pt.Y &&
((op->Next->Pt.X > pt.X) == (op->Pt.X < pt.X)))) return -1;
}
if ((op->Pt.Y < pt.Y) != (op->Next->Pt.Y < pt.Y))
{
if (op->Pt.X >= pt.X)
{
if (op->Next->Pt.X > pt.X) result = 1 - result;
else
{
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
}
} else
{
if (op->Next->Pt.X > pt.X)
{
double d = (double)(op->Pt.X - pt.X) * (op->Next->Pt.Y - pt.Y) -
(double)(op->Next->Pt.X - pt.X) * (op->Pt.Y - pt.Y);
if (!d) return -1;
if ((d > 0) == (op->Next->Pt.Y > op->Pt.Y)) result = 1 - result;
}
}
}
op = op->Next;
if (startOp == op) break;
}
return result;
}
//------------------------------------------------------------------------------
bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
{
OutPt* op = OutPt1;
do
{
//nb: PointInPolygon returns 0 if false, +1 if true, -1 if pt on polygon
int res = PointInPolygon(op->Pt, OutPt2);
if (res >= 0) return res > 0;
op = op->Next;
}
while (op != OutPt1);
return true;
}
//----------------------------------------------------------------------
bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(e1.Top.Y - e1.Bot.Y, e2.Top.X - e2.Bot.X) ==
Int128Mul(e1.Top.X - e1.Bot.X, e2.Top.Y - e2.Bot.Y);
else
#endif
return (e1.Top.Y - e1.Bot.Y) * (e2.Top.X - e2.Bot.X) ==
(e1.Top.X - e1.Bot.X) * (e2.Top.Y - e2.Bot.Y);
}
//------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
const IntPoint pt3, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt2.X-pt3.X) == Int128Mul(pt1.X-pt2.X, pt2.Y-pt3.Y);
else
#endif
return (pt1.Y-pt2.Y)*(pt2.X-pt3.X) == (pt1.X-pt2.X)*(pt2.Y-pt3.Y);
}
//------------------------------------------------------------------------------
bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
const IntPoint pt3, const IntPoint pt4, bool UseFullInt64Range)
{
#ifndef use_int32
if (UseFullInt64Range)
return Int128Mul(pt1.Y-pt2.Y, pt3.X-pt4.X) == Int128Mul(pt1.X-pt2.X, pt3.Y-pt4.Y);
else
#endif
return (pt1.Y-pt2.Y)*(pt3.X-pt4.X) == (pt1.X-pt2.X)*(pt3.Y-pt4.Y);
}
//------------------------------------------------------------------------------
inline bool IsHorizontal(TEdge &e)
{
return e.Dx == HORIZONTAL;
}
//------------------------------------------------------------------------------
inline double GetDx(const IntPoint pt1, const IntPoint pt2)
{
return (pt1.Y == pt2.Y) ?
HORIZONTAL : (double)(pt2.X - pt1.X) / (pt2.Y - pt1.Y);
}
//---------------------------------------------------------------------------
inline void SetDx(TEdge &e)
{
cInt dy = (e.Top.Y - e.Bot.Y);
if (dy == 0) e.Dx = HORIZONTAL;
else e.Dx = (double)(e.Top.X - e.Bot.X) / dy;
}
//---------------------------------------------------------------------------
inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
{
EdgeSide Side = Edge1.Side;
Edge1.Side = Edge2.Side;
Edge2.Side = Side;
}
//------------------------------------------------------------------------------
inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
{
int OutIdx = Edge1.OutIdx;
Edge1.OutIdx = Edge2.OutIdx;
Edge2.OutIdx = OutIdx;
}
//------------------------------------------------------------------------------
inline cInt TopX(TEdge &edge, const cInt currentY)
{
return ( currentY == edge.Top.Y ) ?
edge.Top.X : edge.Bot.X + Round(edge.Dx *(currentY - edge.Bot.Y));
}
//------------------------------------------------------------------------------
void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
{
#ifdef use_xyz
ip.Z = 0;
#endif
double b1, b2;
if (Edge1.Dx == Edge2.Dx)
{
ip.Y = Edge1.Curr.Y;
ip.X = TopX(Edge1, ip.Y);
return;
}
else if (Edge1.Dx == 0)
{
ip.X = Edge1.Bot.X;
if (IsHorizontal(Edge2))
ip.Y = Edge2.Bot.Y;
else
{
b2 = Edge2.Bot.Y - (Edge2.Bot.X / Edge2.Dx);
ip.Y = Round(ip.X / Edge2.Dx + b2);
}
}
else if (Edge2.Dx == 0)
{
ip.X = Edge2.Bot.X;
if (IsHorizontal(Edge1))
ip.Y = Edge1.Bot.Y;
else
{
b1 = Edge1.Bot.Y - (Edge1.Bot.X / Edge1.Dx);
ip.Y = Round(ip.X / Edge1.Dx + b1);
}
}
else
{
b1 = Edge1.Bot.X - Edge1.Bot.Y * Edge1.Dx;
b2 = Edge2.Bot.X - Edge2.Bot.Y * Edge2.Dx;
double q = (b2-b1) / (Edge1.Dx - Edge2.Dx);
ip.Y = Round(q);
if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
ip.X = Round(Edge1.Dx * q + b1);
else
ip.X = Round(Edge2.Dx * q + b2);
}
if (ip.Y < Edge1.Top.Y || ip.Y < Edge2.Top.Y)
{
if (Edge1.Top.Y > Edge2.Top.Y)
ip.Y = Edge1.Top.Y;
else
ip.Y = Edge2.Top.Y;
if (std::fabs(Edge1.Dx) < std::fabs(Edge2.Dx))
ip.X = TopX(Edge1, ip.Y);
else
ip.X = TopX(Edge2, ip.Y);
}
//finally, don't allow 'ip' to be BELOW curr.Y (ie bottom of scanbeam) ...
if (ip.Y > Edge1.Curr.Y)
{
ip.Y = Edge1.Curr.Y;
//use the more vertical edge to derive X ...
if (std::fabs(Edge1.Dx) > std::fabs(Edge2.Dx))
ip.X = TopX(Edge2, ip.Y); else
ip.X = TopX(Edge1, ip.Y);
}
}
//------------------------------------------------------------------------------
void ReversePolyPtLinks(OutPt *pp)
{
if (!pp) return;
OutPt *pp1, *pp2;
pp1 = pp;
do {
pp2 = pp1->Next;
pp1->Next = pp1->Prev;
pp1->Prev = pp2;
pp1 = pp2;
} while( pp1 != pp );
}
//------------------------------------------------------------------------------
void DisposeOutPts(OutPt*& pp)
{
if (pp == 0) return;
pp->Prev->Next = 0;
while( pp )
{
OutPt *tmpPp = pp;
pp = pp->Next;
delete tmpPp;
}
}
//------------------------------------------------------------------------------
inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPoint& Pt)
{
std::memset(e, 0, sizeof(TEdge));
e->Next = eNext;
e->Prev = ePrev;
e->Curr = Pt;
e->OutIdx = Unassigned;
}
//------------------------------------------------------------------------------
void InitEdge2(TEdge& e, PolyType Pt)
{
if (e.Curr.Y >= e.Next->Curr.Y)
{
e.Bot = e.Curr;
e.Top = e.Next->Curr;
} else
{
e.Top = e.Curr;
e.Bot = e.Next->Curr;
}
SetDx(e);
e.PolyTyp = Pt;
}
//------------------------------------------------------------------------------
TEdge* RemoveEdge(TEdge* e)
{
//removes e from double_linked_list (but without removing from memory)
e->Prev->Next = e->Next;
e->Next->Prev = e->Prev;
TEdge* result = e->Next;
e->Prev = 0; //flag as removed (see ClipperBase.Clear)
return result;
}
//------------------------------------------------------------------------------
inline void ReverseHorizontal(TEdge &e)
{
//swap horizontal edges' Top and Bottom x's so they follow the natural
//progression of the bounds - ie so their xbots will align with the
//adjoining lower edge. [Helpful in the ProcessHorizontal() method.]
std::swap(e.Top.X, e.Bot.X);
#ifdef use_xyz
std::swap(e.Top.Z, e.Bot.Z);
#endif
}
//------------------------------------------------------------------------------
void SwapPoints(IntPoint &pt1, IntPoint &pt2)
{
IntPoint tmp = pt1;
pt1 = pt2;
pt2 = tmp;
}
//------------------------------------------------------------------------------
bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
IntPoint pt2b, IntPoint &pt1, IntPoint &pt2)
{
//precondition: segments are Collinear.
if (Abs(pt1a.X - pt1b.X) > Abs(pt1a.Y - pt1b.Y))
{
if (pt1a.X > pt1b.X) SwapPoints(pt1a, pt1b);
if (pt2a.X > pt2b.X) SwapPoints(pt2a, pt2b);
if (pt1a.X > pt2a.X) pt1 = pt1a; else pt1 = pt2a;
if (pt1b.X < pt2b.X) pt2 = pt1b; else pt2 = pt2b;
return pt1.X < pt2.X;
} else
{
if (pt1a.Y < pt1b.Y) SwapPoints(pt1a, pt1b);
if (pt2a.Y < pt2b.Y) SwapPoints(pt2a, pt2b);
if (pt1a.Y < pt2a.Y) pt1 = pt1a; else pt1 = pt2a;
if (pt1b.Y > pt2b.Y) pt2 = pt1b; else pt2 = pt2b;
return pt1.Y > pt2.Y;
}
}
//------------------------------------------------------------------------------
bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
{
OutPt *p = btmPt1->Prev;
while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Prev;
double dx1p = std::fabs(GetDx(btmPt1->Pt, p->Pt));
p = btmPt1->Next;
while ((p->Pt == btmPt1->Pt) && (p != btmPt1)) p = p->Next;
double dx1n = std::fabs(GetDx(btmPt1->Pt, p->Pt));
p = btmPt2->Prev;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Prev;
double dx2p = std::fabs(GetDx(btmPt2->Pt, p->Pt));
p = btmPt2->Next;
while ((p->Pt == btmPt2->Pt) && (p != btmPt2)) p = p->Next;
double dx2n = std::fabs(GetDx(btmPt2->Pt, p->Pt));
if (std::max(dx1p, dx1n) == std::max(dx2p, dx2n) &&
std::min(dx1p, dx1n) == std::min(dx2p, dx2n))
return Area(btmPt1) > 0; //if otherwise identical use orientation
else
return (dx1p >= dx2p && dx1p >= dx2n) || (dx1n >= dx2p && dx1n >= dx2n);
}
//------------------------------------------------------------------------------
OutPt* GetBottomPt(OutPt *pp)
{
OutPt* dups = 0;
OutPt* p = pp->Next;
while (p != pp)
{
if (p->Pt.Y > pp->Pt.Y)
{
pp = p;
dups = 0;
}
else if (p->Pt.Y == pp->Pt.Y && p->Pt.X <= pp->Pt.X)
{
if (p->Pt.X < pp->Pt.X)
{
dups = 0;
pp = p;
} else
{
if (p->Next != pp && p->Prev != pp) dups = p;
}
}
p = p->Next;
}
if (dups)
{
//there appears to be at least 2 vertices at BottomPt so ...
while (dups != p)
{
if (!FirstIsBottomPt(p, dups)) pp = dups;
dups = dups->Next;
while (dups->Pt != pp->Pt) dups = dups->Next;
}
}
return pp;
}
//------------------------------------------------------------------------------
bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1,
const IntPoint pt2, const IntPoint pt3)
{
if ((pt1 == pt3) || (pt1 == pt2) || (pt3 == pt2))
return false;
else if (pt1.X != pt3.X)
return (pt2.X > pt1.X) == (pt2.X < pt3.X);
else
return (pt2.Y > pt1.Y) == (pt2.Y < pt3.Y);
}
//------------------------------------------------------------------------------
bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
{
if (seg1a > seg1b) std::swap(seg1a, seg1b);
if (seg2a > seg2b) std::swap(seg2a, seg2b);
return (seg1a < seg2b) && (seg2a < seg1b);
}
//------------------------------------------------------------------------------
// ClipperBase class methods ...
//------------------------------------------------------------------------------
ClipperBase::ClipperBase() //constructor
{
m_CurrentLM = m_MinimaList.begin(); //begin() == end() here
m_UseFullRange = false;
}
//------------------------------------------------------------------------------
ClipperBase::~ClipperBase() //destructor
{
Clear();
}
//------------------------------------------------------------------------------
void RangeTest(const IntPoint& Pt, bool& useFullRange)
{
if (useFullRange)
{
if (Pt.X > hiRange || Pt.Y > hiRange || -Pt.X > hiRange || -Pt.Y > hiRange)
return;//throw clipperException("Coordinate outside allowed range");
}
else if (Pt.X > loRange|| Pt.Y > loRange || -Pt.X > loRange || -Pt.Y > loRange)
{
useFullRange = true;
RangeTest(Pt, useFullRange);
}
}
//------------------------------------------------------------------------------
TEdge* FindNextLocMin(TEdge* E)
{
for (;;)
{
while (E->Bot != E->Prev->Bot || E->Curr == E->Top) E = E->Next;
if (!IsHorizontal(*E) && !IsHorizontal(*E->Prev)) break;
while (IsHorizontal(*E->Prev)) E = E->Prev;
TEdge* E2 = E;
while (IsHorizontal(*E)) E = E->Next;
if (E->Top.Y == E->Prev->Bot.Y) continue; //ie just an intermediate horz.
if (E2->Prev->Bot.X < E->Bot.X) E = E2;
break;
}
return E;
}
//------------------------------------------------------------------------------
TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
{
TEdge *Result = E;
TEdge *Horz = 0;
if (E->OutIdx == Skip)
{
//if edges still remain in the current bound beyond the skip edge then
//create another LocMin and call ProcessBound once more
if (NextIsForward)
{
while (E->Top.Y == E->Next->Bot.Y) E = E->Next;
//don't include top horizontals when parsing a bound a second time,
//they will be contained in the opposite bound ...
while (E != Result && IsHorizontal(*E)) E = E->Prev;
}
else
{
while (E->Top.Y == E->Prev->Bot.Y) E = E->Prev;
while (E != Result && IsHorizontal(*E)) E = E->Next;
}
if (E == Result)
{
if (NextIsForward) Result = E->Next;
else Result = E->Prev;
}
else
{
//there are more edges in the bound beyond result starting with E
if (NextIsForward)
E = Result->Next;
else
E = Result->Prev;
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
locMin.LeftBound = 0;
locMin.RightBound = E;
E->WindDelta = 0;
Result = ProcessBound(E, NextIsForward);
m_MinimaList.push_back(locMin);
}
return Result;
}
TEdge *EStart;
if (IsHorizontal(*E))
{
//We need to be careful with open paths because this may not be a
//true local minima (ie E may be following a skip edge).
//Also, consecutive horz. edges may start heading left before going right.
if (NextIsForward)
EStart = E->Prev;
else
EStart = E->Next;
if (IsHorizontal(*EStart)) //ie an adjoining horizontal skip edge
{
if (EStart->Bot.X != E->Bot.X && EStart->Top.X != E->Bot.X)
ReverseHorizontal(*E);
}
else if (EStart->Bot.X != E->Bot.X)
ReverseHorizontal(*E);
}
EStart = E;
if (NextIsForward)
{
while (Result->Top.Y == Result->Next->Bot.Y && Result->Next->OutIdx != Skip)
Result = Result->Next;
if (IsHorizontal(*Result) && Result->Next->OutIdx != Skip)
{
//nb: at the top of a bound, horizontals are added to the bound
//only when the preceding edge attaches to the horizontal's left vertex
//unless a Skip edge is encountered when that becomes the top divide
Horz = Result;
while (IsHorizontal(*Horz->Prev)) Horz = Horz->Prev;
if (Horz->Prev->Top.X > Result->Next->Top.X) Result = Horz->Prev;
}
while (E != Result)
{
E->NextInLML = E->Next;
if (IsHorizontal(*E) && E != EStart &&
E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
E = E->Next;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Prev->Top.X)
ReverseHorizontal(*E);
Result = Result->Next; //move to the edge just beyond current bound
} else
{
while (Result->Top.Y == Result->Prev->Bot.Y && Result->Prev->OutIdx != Skip)
Result = Result->Prev;
if (IsHorizontal(*Result) && Result->Prev->OutIdx != Skip)
{
Horz = Result;
while (IsHorizontal(*Horz->Next)) Horz = Horz->Next;
if (Horz->Next->Top.X == Result->Prev->Top.X ||
Horz->Next->Top.X > Result->Prev->Top.X) Result = Horz->Next;
}
while (E != Result)
{
E->NextInLML = E->Prev;
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
E = E->Prev;
}
if (IsHorizontal(*E) && E != EStart && E->Bot.X != E->Next->Top.X)
ReverseHorizontal(*E);
Result = Result->Prev; //move to the edge just beyond current bound
}
return Result;
}
//------------------------------------------------------------------------------
bool ClipperBase::AddPath(const Path &pg, PolyType PolyTyp, bool Closed)
{
#ifdef use_lines
if (!Closed && PolyTyp == ptClip)
return false;//throw clipperException("AddPath: Open paths must be subject.");
#else
if (!Closed)
throw clipperException("AddPath: Open paths have been disabled.");
#endif
int highI = (int)pg.size() -1;
if (Closed) while (highI > 0 && (pg[highI] == pg[0])) --highI;
while (highI > 0 && (pg[highI] == pg[highI -1])) --highI;
if ((Closed && highI < 2) || (!Closed && highI < 1)) return false;
//create a new edge array ...
TEdge *edges = new TEdge [highI +1];
bool IsFlat = true;
//1. Basic (first) edge initialization ...
//try
{
edges[1].Curr = pg[1];
RangeTest(pg[0], m_UseFullRange);
RangeTest(pg[highI], m_UseFullRange);
InitEdge(&edges[0], &edges[1], &edges[highI], pg[0]);
InitEdge(&edges[highI], &edges[0], &edges[highI-1], pg[highI]);
for (int i = highI - 1; i >= 1; --i)
{
RangeTest(pg[i], m_UseFullRange);
InitEdge(&edges[i], &edges[i+1], &edges[i-1], pg[i]);
}
}
//catch(...)
//{
// delete [] edges;
// return false;//throw; //range test fails
//}
TEdge *eStart = &edges[0];
//2. Remove duplicate vertices, and (when closed) collinear edges ...
TEdge *E = eStart, *eLoopStop = eStart;
for (;;)
{
//nb: allows matching start and end points when not Closed ...
if (E->Curr == E->Next->Curr && (Closed || E->Next != eStart))
{
if (E == E->Next) break;
if (E == eStart) eStart = E->Next;
E = RemoveEdge(E);
eLoopStop = E;
continue;
}
if (E->Prev == E->Next)
break; //only two vertices
else if (Closed &&
SlopesEqual(E->Prev->Curr, E->Curr, E->Next->Curr, m_UseFullRange) &&
(!m_PreserveCollinear ||
!Pt2IsBetweenPt1AndPt3(E->Prev->Curr, E->Curr, E->Next->Curr)))
{
//Collinear edges are allowed for open paths but in closed paths
//the default is to merge adjacent collinear edges into a single edge.
//However, if the PreserveCollinear property is enabled, only overlapping
//collinear edges (ie spikes) will be removed from closed paths.
if (E == eStart) eStart = E->Next;
E = RemoveEdge(E);
E = E->Prev;
eLoopStop = E;
continue;
}
E = E->Next;
if ((E == eLoopStop) || (!Closed && E->Next == eStart)) break;
}
if ((!Closed && (E == E->Next)) || (Closed && (E->Prev == E->Next)))
{
delete [] edges;
return false;
}
if (!Closed)
{
m_HasOpenPaths = true;
eStart->Prev->OutIdx = Skip;
}
//3. Do second stage of edge initialization ...
E = eStart;
do
{
InitEdge2(*E, PolyTyp);
E = E->Next;
if (IsFlat && E->Curr.Y != eStart->Curr.Y) IsFlat = false;
}
while (E != eStart);
//4. Finally, add edge bounds to LocalMinima list ...
//Totally flat paths must be handled differently when adding them
//to LocalMinima list to avoid endless loops etc ...
if (IsFlat)
{
if (Closed)
{
delete [] edges;
return false;
}
E->Prev->OutIdx = Skip;
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
locMin.LeftBound = 0;
locMin.RightBound = E;
locMin.RightBound->Side = esRight;
locMin.RightBound->WindDelta = 0;
for (;;)
{
if (E->Bot.X != E->Prev->Top.X) ReverseHorizontal(*E);
if (E->Next->OutIdx == Skip) break;
E->NextInLML = E->Next;
E = E->Next;
}
m_MinimaList.push_back(locMin);
m_edges.push_back(edges);
return true;
}
m_edges.push_back(edges);
bool leftBoundIsForward;
TEdge* EMin = 0;
//workaround to avoid an endless loop in the while loop below when
//open paths have matching start and end points ...
if (E->Prev->Bot == E->Prev->Top) E = E->Next;
for (;;)
{
E = FindNextLocMin(E);
if (E == EMin) break;
else if (!EMin) EMin = E;
//E and E.Prev now share a local minima (left aligned if horizontal).
//Compare their slopes to find which starts which bound ...
MinimaList::value_type locMin;
locMin.Y = E->Bot.Y;
if (E->Dx < E->Prev->Dx)
{
locMin.LeftBound = E->Prev;
locMin.RightBound = E;
leftBoundIsForward = false; //Q.nextInLML = Q.prev
} else
{
locMin.LeftBound = E;
locMin.RightBound = E->Prev;
leftBoundIsForward = true; //Q.nextInLML = Q.next
}
if (!Closed) locMin.LeftBound->WindDelta = 0;
else if (locMin.LeftBound->Next == locMin.RightBound)
locMin.LeftBound->WindDelta = -1;
else locMin.LeftBound->WindDelta = 1;
locMin.RightBound->WindDelta = -locMin.LeftBound->WindDelta;
E = ProcessBound(locMin.LeftBound, leftBoundIsForward);
if (E->OutIdx == Skip) E = ProcessBound(E, leftBoundIsForward);
TEdge* E2 = ProcessBound(locMin.RightBound, !leftBoundIsForward);
if (E2->OutIdx == Skip) E2 = ProcessBound(E2, !leftBoundIsForward);
if (locMin.LeftBound->OutIdx == Skip)
locMin.LeftBound = 0;
else if (locMin.RightBound->OutIdx == Skip)
locMin.RightBound = 0;
m_MinimaList.push_back(locMin);
if (!leftBoundIsForward) E = E2;
}
return true;
}
//------------------------------------------------------------------------------
bool ClipperBase::AddPaths(const Paths &ppg, PolyType PolyTyp, bool Closed)
{
bool result = false;
for (Paths::size_type i = 0; i < ppg.size(); ++i)
if (AddPath(ppg[i], PolyTyp, Closed)) result = true;
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::Clear()
{
DisposeLocalMinimaList();
for (EdgeList::size_type i = 0; i < m_edges.size(); ++i)
{
TEdge* edges = m_edges[i];
delete [] edges;
}
m_edges.clear();
m_UseFullRange = false;
m_HasOpenPaths = false;
}
//------------------------------------------------------------------------------
void ClipperBase::Reset()
{
m_CurrentLM = m_MinimaList.begin();
if (m_CurrentLM == m_MinimaList.end()) return; //ie nothing to process
std::sort(m_MinimaList.begin(), m_MinimaList.end(), LocMinSorter());
m_Scanbeam = ScanbeamList(); //clears/resets priority_queue
//reset all edges ...
for (MinimaList::iterator lm = m_MinimaList.begin(); lm != m_MinimaList.end(); ++lm)
{
InsertScanbeam(lm->Y);
TEdge* e = lm->LeftBound;
if (e)
{
e->Curr = e->Bot;
e->Side = esLeft;
e->OutIdx = Unassigned;
}
e = lm->RightBound;
if (e)
{
e->Curr = e->Bot;
e->Side = esRight;
e->OutIdx = Unassigned;
}
}
m_ActiveEdges = 0;
m_CurrentLM = m_MinimaList.begin();
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeLocalMinimaList()
{
m_MinimaList.clear();
m_CurrentLM = m_MinimaList.begin();
}
//------------------------------------------------------------------------------
bool ClipperBase::PopLocalMinima(cInt Y, const LocalMinimum *&locMin)
{
if (m_CurrentLM == m_MinimaList.end() || (*m_CurrentLM).Y != Y) return false;
locMin = &(*m_CurrentLM);
++m_CurrentLM;
return true;
}
//------------------------------------------------------------------------------
IntRect ClipperBase::GetBounds()
{
IntRect result;
MinimaList::iterator lm = m_MinimaList.begin();
if (lm == m_MinimaList.end())
{
result.left = result.top = result.right = result.bottom = 0;
return result;
}
result.left = lm->LeftBound->Bot.X;
result.top = lm->LeftBound->Bot.Y;
result.right = lm->LeftBound->Bot.X;
result.bottom = lm->LeftBound->Bot.Y;
while (lm != m_MinimaList.end())
{
//todo - needs fixing for open paths
result.bottom = std::max(result.bottom, lm->LeftBound->Bot.Y);
TEdge* e = lm->LeftBound;
for (;;) {
TEdge* bottomE = e;
while (e->NextInLML)
{
if (e->Bot.X < result.left) result.left = e->Bot.X;
if (e->Bot.X > result.right) result.right = e->Bot.X;
e = e->NextInLML;
}
result.left = std::min(result.left, e->Bot.X);
result.right = std::max(result.right, e->Bot.X);
result.left = std::min(result.left, e->Top.X);
result.right = std::max(result.right, e->Top.X);
result.top = std::min(result.top, e->Top.Y);
if (bottomE == lm->LeftBound) e = lm->RightBound;
else break;
}
++lm;
}
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::InsertScanbeam(const cInt Y)
{
m_Scanbeam.push(Y);
}
//------------------------------------------------------------------------------
bool ClipperBase::PopScanbeam(cInt &Y)
{
if (m_Scanbeam.empty()) return false;
Y = m_Scanbeam.top();
m_Scanbeam.pop();
while (!m_Scanbeam.empty() && Y == m_Scanbeam.top()) { m_Scanbeam.pop(); } // Pop duplicates.
return true;
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeAllOutRecs(){
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
DisposeOutRec(i);
m_PolyOuts.clear();
}
//------------------------------------------------------------------------------
void ClipperBase::DisposeOutRec(PolyOutList::size_type index)
{
OutRec *outRec = m_PolyOuts[index];
if (outRec->Pts) DisposeOutPts(outRec->Pts);
delete outRec;
m_PolyOuts[index] = 0;
}
//------------------------------------------------------------------------------
void ClipperBase::DeleteFromAEL(TEdge *e)
{
TEdge* AelPrev = e->PrevInAEL;
TEdge* AelNext = e->NextInAEL;
if (!AelPrev && !AelNext && (e != m_ActiveEdges)) return; //already deleted
if (AelPrev) AelPrev->NextInAEL = AelNext;
else m_ActiveEdges = AelNext;
if (AelNext) AelNext->PrevInAEL = AelPrev;
e->NextInAEL = 0;
e->PrevInAEL = 0;
}
//------------------------------------------------------------------------------
OutRec* ClipperBase::CreateOutRec()
{
OutRec* result = new OutRec;
result->IsHole = false;
result->IsOpen = false;
result->FirstLeft = 0;
result->Pts = 0;
result->BottomPt = 0;
result->PolyNd = 0;
m_PolyOuts.push_back(result);
result->Idx = (int)m_PolyOuts.size() - 1;
return result;
}
//------------------------------------------------------------------------------
void ClipperBase::SwapPositionsInAEL(TEdge *Edge1, TEdge *Edge2)
{
//check that one or other edge hasn't already been removed from AEL ...
if (Edge1->NextInAEL == Edge1->PrevInAEL ||
Edge2->NextInAEL == Edge2->PrevInAEL) return;
if (Edge1->NextInAEL == Edge2)
{
TEdge* Next = Edge2->NextInAEL;
if (Next) Next->PrevInAEL = Edge1;
TEdge* Prev = Edge1->PrevInAEL;
if (Prev) Prev->NextInAEL = Edge2;
Edge2->PrevInAEL = Prev;
Edge2->NextInAEL = Edge1;
Edge1->PrevInAEL = Edge2;
Edge1->NextInAEL = Next;
}
else if (Edge2->NextInAEL == Edge1)
{
TEdge* Next = Edge1->NextInAEL;
if (Next) Next->PrevInAEL = Edge2;
TEdge* Prev = Edge2->PrevInAEL;
if (Prev) Prev->NextInAEL = Edge1;
Edge1->PrevInAEL = Prev;
Edge1->NextInAEL = Edge2;
Edge2->PrevInAEL = Edge1;
Edge2->NextInAEL = Next;
}
else
{
TEdge* Next = Edge1->NextInAEL;
TEdge* Prev = Edge1->PrevInAEL;
Edge1->NextInAEL = Edge2->NextInAEL;
if (Edge1->NextInAEL) Edge1->NextInAEL->PrevInAEL = Edge1;
Edge1->PrevInAEL = Edge2->PrevInAEL;
if (Edge1->PrevInAEL) Edge1->PrevInAEL->NextInAEL = Edge1;
Edge2->NextInAEL = Next;
if (Edge2->NextInAEL) Edge2->NextInAEL->PrevInAEL = Edge2;
Edge2->PrevInAEL = Prev;
if (Edge2->PrevInAEL) Edge2->PrevInAEL->NextInAEL = Edge2;
}
if (!Edge1->PrevInAEL) m_ActiveEdges = Edge1;
else if (!Edge2->PrevInAEL) m_ActiveEdges = Edge2;
}
//------------------------------------------------------------------------------
void ClipperBase::UpdateEdgeIntoAEL(TEdge *&e)
{
if (!e->NextInLML)
return;//throw clipperException("UpdateEdgeIntoAEL: invalid call");
e->NextInLML->OutIdx = e->OutIdx;
TEdge* AelPrev = e->PrevInAEL;
TEdge* AelNext = e->NextInAEL;
if (AelPrev) AelPrev->NextInAEL = e->NextInLML;
else m_ActiveEdges = e->NextInLML;
if (AelNext) AelNext->PrevInAEL = e->NextInLML;
e->NextInLML->Side = e->Side;
e->NextInLML->WindDelta = e->WindDelta;
e->NextInLML->WindCnt = e->WindCnt;
e->NextInLML->WindCnt2 = e->WindCnt2;
e = e->NextInLML;
e->Curr = e->Bot;
e->PrevInAEL = AelPrev;
e->NextInAEL = AelNext;
if (!IsHorizontal(*e)) InsertScanbeam(e->Top.Y);
}
//------------------------------------------------------------------------------
bool ClipperBase::LocalMinimaPending()
{
return (m_CurrentLM != m_MinimaList.end());
}
//------------------------------------------------------------------------------
// TClipper methods ...
//------------------------------------------------------------------------------
Clipper::Clipper(int initOptions) : ClipperBase() //constructor
{
m_ExecuteLocked = false;
m_UseFullRange = false;
m_ReverseOutput = ((initOptions & ioReverseSolution) != 0);
m_StrictSimple = ((initOptions & ioStrictlySimple) != 0);
m_PreserveCollinear = ((initOptions & ioPreserveCollinear) != 0);
m_HasOpenPaths = false;
#ifdef use_xyz
m_ZFill = 0;
#endif
}
//------------------------------------------------------------------------------
#ifdef use_xyz
void Clipper::ZFillFunction(ZFillCallback zFillFunc)
{
m_ZFill = zFillFunc;
}
//------------------------------------------------------------------------------
#endif
bool Clipper::Execute(ClipType clipType, Paths &solution, PolyFillType fillType)
{
return Execute(clipType, solution, fillType, fillType);
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, PolyTree &polytree, PolyFillType fillType)
{
return Execute(clipType, polytree, fillType, fillType);
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, Paths &solution,
PolyFillType subjFillType, PolyFillType clipFillType)
{
if( m_ExecuteLocked ) return false;
if (m_HasOpenPaths)
return false;//throw clipperException("Error: PolyTree struct is needed for open path clipping.");
m_ExecuteLocked = true;
solution.resize(0);
m_SubjFillType = subjFillType;
m_ClipFillType = clipFillType;
m_ClipType = clipType;
m_UsingPolyTree = false;
bool succeeded = ExecuteInternal();
if (succeeded) BuildResult(solution);
DisposeAllOutRecs();
m_ExecuteLocked = false;
return succeeded;
}
//------------------------------------------------------------------------------
bool Clipper::Execute(ClipType clipType, PolyTree& polytree,
PolyFillType subjFillType, PolyFillType clipFillType)
{
if( m_ExecuteLocked ) return false;
m_ExecuteLocked = true;
m_SubjFillType = subjFillType;
m_ClipFillType = clipFillType;
m_ClipType = clipType;
m_UsingPolyTree = true;
bool succeeded = ExecuteInternal();
if (succeeded) BuildResult2(polytree);
DisposeAllOutRecs();
m_ExecuteLocked = false;
return succeeded;
}
//------------------------------------------------------------------------------
void Clipper::FixHoleLinkage(OutRec &outrec)
{
//skip OutRecs that (a) contain outermost polygons or
//(b) already have the correct owner/child linkage ...
if (!outrec.FirstLeft ||
(outrec.IsHole != outrec.FirstLeft->IsHole &&
outrec.FirstLeft->Pts)) return;
OutRec* orfl = outrec.FirstLeft;
while (orfl && ((orfl->IsHole == outrec.IsHole) || !orfl->Pts))
orfl = orfl->FirstLeft;
outrec.FirstLeft = orfl;
}
//------------------------------------------------------------------------------
bool Clipper::ExecuteInternal()
{
bool succeeded = true;
//try
{
Reset();
m_Maxima = MaximaList();
m_SortedEdges = 0;
succeeded = true;
cInt botY, topY;
if (!PopScanbeam(botY)) return false;
InsertLocalMinimaIntoAEL(botY);
while (PopScanbeam(topY) || LocalMinimaPending())
{
ProcessHorizontals();
ClearGhostJoins();
if (!ProcessIntersections(topY))
{
succeeded = false;
break;
}
ProcessEdgesAtTopOfScanbeam(topY);
botY = topY;
InsertLocalMinimaIntoAEL(botY);
}
}
//catch(...)
//{
// succeeded = false;
//}
if (succeeded)
{
//fix orientations ...
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec *outRec = m_PolyOuts[i];
if (!outRec->Pts || outRec->IsOpen) continue;
if ((outRec->IsHole ^ m_ReverseOutput) == (Area(*outRec) > 0))
ReversePolyPtLinks(outRec->Pts);
}
if (!m_Joins.empty()) JoinCommonEdges();
//unfortunately FixupOutPolygon() must be done after JoinCommonEdges()
for (PolyOutList::size_type i = 0; i < m_PolyOuts.size(); ++i)
{
OutRec *outRec = m_PolyOuts[i];
if (!outRec->Pts) continue;
if (outRec->IsOpen)
FixupOutPolyline(*outRec);
else
FixupOutPolygon(*outRec);
}
if (m_StrictSimple) DoSimplePolygons();
}
ClearJoins();
ClearGhostJoins();
return succeeded;
}
//------------------------------------------------------------------------------
void Clipper::SetWindingCount(TEdge &edge)
{
TEdge *e = edge.PrevInAEL;
//find the edge of the same polytype that immediately preceeds 'edge' in AEL
while (e && ((e->PolyTyp != edge.PolyTyp) || (e->WindDelta == 0))) e = e->PrevInAEL;
if (!e)
{
if (edge.WindDelta == 0)
{
PolyFillType pft = (edge.PolyTyp == ptSubject ? m_SubjFillType : m_ClipFillType);
edge.WindCnt = (pft == pftNegative ? -1 : 1);
}
else
edge.WindCnt = edge.WindDelta;
edge.WindCnt2 = 0;
e = m_ActiveEdges; //ie get ready to calc WindCnt2
}
else if (edge.WindDelta == 0 && m_ClipType != ctUnion)
{
edge.WindCnt = 1;
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
else if (IsEvenOddFillType(edge))
{
//EvenOdd filling ...
if (edge.WindDelta == 0)
{
//are we inside a subj polygon ...
bool Inside = true;
TEdge *e2 = e->PrevInAEL;
while (e2)
{
if (e2->PolyTyp == e->PolyTyp && e2->WindDelta != 0)
Inside = !Inside;
e2 = e2->PrevInAEL;
}
edge.WindCnt = (Inside ? 0 : 1);
}
else
{
edge.WindCnt = edge.WindDelta;
}
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
else
{
//nonZero, Positive or Negative filling ...
if (e->WindCnt * e->WindDelta < 0)
{
//prev edge is 'decreasing' WindCount (WC) toward zero
//so we're outside the previous polygon ...
if (Abs(e->WindCnt) > 1)
{
//outside prev poly but still inside another.
//when reversing direction of prev poly use the same WC
if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
//otherwise continue to 'decrease' WC ...
else edge.WindCnt = e->WindCnt + edge.WindDelta;
}
else
//now outside all polys of same polytype so set own WC ...
edge.WindCnt = (edge.WindDelta == 0 ? 1 : edge.WindDelta);
} else
{
//prev edge is 'increasing' WindCount (WC) away from zero
//so we're inside the previous polygon ...
if (edge.WindDelta == 0)
edge.WindCnt = (e->WindCnt < 0 ? e->WindCnt - 1 : e->WindCnt + 1);
//if wind direction is reversing prev then use same WC
else if (e->WindDelta * edge.WindDelta < 0) edge.WindCnt = e->WindCnt;
//otherwise add to WC ...
else edge.WindCnt = e->WindCnt + edge.WindDelta;
}
edge.WindCnt2 = e->WindCnt2;
e = e->NextInAEL; //ie get ready to calc WindCnt2
}
//update WindCnt2 ...
if (IsEvenOddAltFillType(edge))
{
//EvenOdd filling ...
while (e != &edge)
{
if (e->WindDelta != 0)
edge.WindCnt2 = (edge.WindCnt2 == 0 ? 1 : 0);
e = e->NextInAEL;
}
} else
{
//nonZero, Positive or Negative filling ...
while ( e != &edge )
{
edge.WindCnt2 += e->WindDelta;
e = e->NextInAEL;
}
}
}
//------------------------------------------------------------------------------
bool Clipper::IsEvenOddFillType(const TEdge& edge) const
{
if (edge.PolyTyp == ptSubject)
return m_SubjFillType == pftEvenOdd; else
return m_ClipFillType == pftEvenOdd;
}
//------------------------------------------------------------------------------
bool Clipper::IsEvenOddAltFillType(const TEdge& edge) const
{
if (edge.PolyTyp == ptSubject)
return m_ClipFillType == pftEvenOdd; else
return m_SubjFillType == pftEvenOdd;
}
//------------------------------------------------------------------------------
bool Clipper::IsContributing(const TEdge& edge) const
{
PolyFillType pft, pft2;
if (edge.PolyTyp == ptSubject)
{
pft = m_SubjFillType;
pft2 = m_ClipFillType;
} else
{
pft = m_ClipFillType;
pft2 = m_SubjFillType;
}
switch(pft)
{
case pftEvenOdd:
//return false if a subj line has been flagged as inside a subj polygon
if (edge.WindDelta == 0 && edge.WindCnt != 1) return false;
break;
case pftNonZero:
if (Abs(edge.WindCnt) != 1) return false;
break;
case pftPositive:
if (edge.WindCnt != 1) return false;
break;
default: //pftNegative
if (edge.WindCnt != -1) return false;
}
switch(m_ClipType)
{
case ctIntersection:
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 != 0);
case pftPositive:
return (edge.WindCnt2 > 0);
default:
return (edge.WindCnt2 < 0);
}
break;
case ctUnion:
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
break;
case ctDifference:
if (edge.PolyTyp == ptSubject)
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
else
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 != 0);
case pftPositive:
return (edge.WindCnt2 > 0);
default:
return (edge.WindCnt2 < 0);
}
break;
case ctXor:
if (edge.WindDelta == 0) //XOr always contributing unless open
switch(pft2)
{
case pftEvenOdd:
case pftNonZero:
return (edge.WindCnt2 == 0);
case pftPositive:
return (edge.WindCnt2 <= 0);
default:
return (edge.WindCnt2 >= 0);
}
else
return true;
break;
default:
return true;
}
}
//------------------------------------------------------------------------------
OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
{
OutPt* result;
TEdge *e, *prevE;
if (IsHorizontal(*e2) || ( e1->Dx > e2->Dx ))
{
result = AddOutPt(e1, Pt);
e2->OutIdx = e1->OutIdx;
e1->Side = esLeft;
e2->Side = esRight;
e = e1;
if (e->PrevInAEL == e2)
prevE = e2->PrevInAEL;
else
prevE = e->PrevInAEL;
} else
{
result = AddOutPt(e2, Pt);
e1->OutIdx = e2->OutIdx;
e1->Side = esRight;
e2->Side = esLeft;
e = e2;
if (e->PrevInAEL == e1)
prevE = e1->PrevInAEL;
else
prevE = e->PrevInAEL;
}
if (prevE && prevE->OutIdx >= 0 && prevE->Top.Y < Pt.Y && e->Top.Y < Pt.Y)
{
cInt xPrev = TopX(*prevE, Pt.Y);
cInt xE = TopX(*e, Pt.Y);
if (xPrev == xE && (e->WindDelta != 0) && (prevE->WindDelta != 0) &&
SlopesEqual(IntPoint(xPrev, Pt.Y), prevE->Top, IntPoint(xE, Pt.Y), e->Top, m_UseFullRange))
{
OutPt* outPt = AddOutPt(prevE, Pt);
AddJoin(result, outPt, e->Top);
}
}
return result;
}
//------------------------------------------------------------------------------
void Clipper::AddLocalMaxPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
{
AddOutPt( e1, Pt );
if (e2->WindDelta == 0) AddOutPt(e2, Pt);
if( e1->OutIdx == e2->OutIdx )
{
e1->OutIdx = Unassigned;
e2->OutIdx = Unassigned;
}
else if (e1->OutIdx < e2->OutIdx)
AppendPolygon(e1, e2);
else
AppendPolygon(e2, e1);
}
//------------------------------------------------------------------------------
void Clipper::AddEdgeToSEL(TEdge *edge)
{
//SEL pointers in PEdge are reused to build a list of horizontal edges.
//However, we don't need to worry about order with horizontal edge processing.
if( !m_SortedEdges )
{
m_SortedEdges = edge;
edge->PrevInSEL = 0;
edge->NextInSEL = 0;
}
else
{
edge->NextInSEL = m_SortedEdges;
edge->PrevInSEL = 0;
m_SortedEdges->PrevInSEL = edge;
m_SortedEdges = edge;
}
}
//------------------------------------------------------------------------------
bool Clipper::PopEdgeFromSEL(TEdge *&edge)
{
if (!m_SortedEdges) return false;
edge = m_SortedEdges;
DeleteFromSEL(m_SortedEdges);
return true;
}
//------------------------------------------------------------------------------
void Clipper::CopyAELToSEL()
{
TEdge* e = m_ActiveEdges;
m_SortedEdges = e;
while ( e )
{
e->PrevInSEL = e->PrevInAEL;
e->NextInSEL = e->NextInAEL;
e = e->NextInAEL;
}
}
//------------------------------------------------------------------------------
void Clipper::AddJoin(OutPt *op1, OutPt *op2, const IntPoint OffPt)
{
Join* j = new Join;
j->OutPt1 = op1;
j->OutPt2 = op2;
j->OffPt = OffPt;
m_Joins.push_back(j);
}
//------------------------------------------------------------------------------
void Clipper::ClearJoins()
{
for (JoinList::size_type i = 0; i < m_Joins.size(); i++)
delete m_Joins[i];
m_Joins.resize(0);
}
//------------------------------------------------------------------------------
void Clipper::ClearGhostJoins()
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); i++)
delete m_GhostJoins[i];
m_GhostJoins.resize(0);
}
//------------------------------------------------------------------------------
void Clipper::AddGhostJoin(OutPt *op, const IntPoint OffPt)
{
Join* j = new Join;
j->OutPt1 = op;
j->OutPt2 = 0;
j->OffPt = OffPt;
m_GhostJoins.push_back(j);
}
//------------------------------------------------------------------------------
void Clipper::InsertLocalMinimaIntoAEL(const cInt botY)
{
const LocalMinimum *lm;
while (PopLocalMinima(botY, lm))
{
TEdge* lb = lm->LeftBound;
TEdge* rb = lm->RightBound;
OutPt *Op1 = 0;
if (!lb)
{
//nb: don't insert LB into either AEL or SEL
InsertEdgeIntoAEL(rb, 0);
SetWindingCount(*rb);
if (IsContributing(*rb))
Op1 = AddOutPt(rb, rb->Bot);
}
else if (!rb)
{
InsertEdgeIntoAEL(lb, 0);
SetWindingCount(*lb);
if (IsContributing(*lb))
Op1 = AddOutPt(lb, lb->Bot);
InsertScanbeam(lb->Top.Y);
}
else
{
InsertEdgeIntoAEL(lb, 0);
InsertEdgeIntoAEL(rb, lb);
SetWindingCount( *lb );
rb->WindCnt = lb->WindCnt;
rb->WindCnt2 = lb->WindCnt2;
if (IsContributing(*lb))
Op1 = AddLocalMinPoly(lb, rb, lb->Bot);
InsertScanbeam(lb->Top.Y);
}
if (rb)
{
if (IsHorizontal(*rb))
{
AddEdgeToSEL(rb);
if (rb->NextInLML)
InsertScanbeam(rb->NextInLML->Top.Y);
}
else InsertScanbeam( rb->Top.Y );
}
if (!lb || !rb) continue;
//if any output polygons share an edge, they'll need joining later ...
if (Op1 && IsHorizontal(*rb) &&
m_GhostJoins.size() > 0 && (rb->WindDelta != 0))
{
for (JoinList::size_type i = 0; i < m_GhostJoins.size(); ++i)
{
Join* jr = m_GhostJoins[i];
//if the horizontal Rb and a 'ghost' horizontal overlap, then convert
//the 'ghost' join to a real join ready for later ...
if (HorzSegmentsOverlap(jr->OutPt1->Pt.X, jr->OffPt.X, rb->Bot.X, rb->Top.X))
AddJoin(jr->OutPt1, Op1, jr->OffPt);
}
}
if (lb->OutIdx >= 0 && lb->PrevInAEL &&
lb->PrevInAEL->Curr.X == lb->Bot.X &&
lb->PrevInAEL->OutIdx >= 0 &&
SlopesEqual(lb->PrevInAEL->Bot, lb->PrevInAEL->Top, lb->Curr, lb->Top, m_UseFullRange) &&
(lb->WindDelta != 0) && (lb->PrevInAEL->WindDelta != 0))
{
OutPt *Op2 = AddOutPt(lb->PrevInAEL, lb->Bot);
AddJoin(Op1, Op2, lb->Top);
}
if(lb->NextInAEL != rb)
{
if (rb->OutIdx >= 0 && rb->PrevInAEL->OutIdx >= 0 &&
SlopesEqual(rb->PrevInAEL->Curr, rb->PrevInAEL->Top, rb->Curr, rb->Top, m_UseFullRange) &&
(rb->WindDelta != 0) && (rb->PrevInAEL->WindDelta != 0))
{
OutPt *Op2 = AddOutPt(rb->PrevInAEL, rb->Bot);
AddJoin(Op1, Op2, rb->Top);
}
TEdge* e = lb->NextInAEL;
if (e)
{
while( e != rb )
{
//nb: For calculating winding counts etc, IntersectEdges() assumes
//that param1 will be to the Right of param2 ABOVE the intersection ...
IntersectEdges(rb , e , lb->Curr); //order important here
e = e->NextInAEL;
}
}
}
}
}
//------------------------------------------------------------------------------
void Clipper::DeleteFromSEL(TEdge *e)
{
TEdge* SelPrev = e->PrevInSEL;
TEdge* SelNext = e->NextInSEL;
if( !SelPrev && !SelNext && (e != m_SortedEdges) ) return; //already deleted
if( SelPrev ) SelPrev->NextInSEL = SelNext;
else m_SortedEdges = SelNext;
if( SelNext ) SelNext->PrevInSEL = SelPrev;
e->NextInSEL = 0;
e->PrevInSEL = 0;
}
//------------------------------------------------------------------------------
#ifdef use_xyz
void Clipper::SetZ(IntPoint& pt, TEdge& e1, TEdge& e2)
{
if (pt.Z != 0 || !m_ZFill) return;
else if (pt == e1.Bot) pt.Z = e1.Bot.Z;
else if (pt == e1.Top) pt.Z = e1.Top.Z;
else if (pt == e2.Bot) pt.Z = e2.Bot.Z;
else if (pt == e2.Top) pt.Z = e2.Top.Z;
else (*m_ZFill)(e1.Bot, e1.Top, e2.Bot, e2.Top, pt);
}
//------------------------------------------------------------------------------
#endif
void Clipper::IntersectEdges(TEdge *e1, TEdge *e2, IntPoint &Pt)
{
bool e1Contributing = ( e1->OutIdx >= 0 );
bool e2Contributing = ( e2->OutIdx >= 0 );
#ifdef use_xyz
SetZ(Pt, *e1, *e2);
#endif
#ifdef use_lines
//if either edge is on an OPEN path ...
if (e1->WindDelta == 0 || e2->WindDelta == 0)
{
//ignore subject-subject open path intersections UNLESS they
//are both open paths, AND they are both 'contributing maximas' ...
if (e1->WindDelta == 0 && e2->WindDelta == 0) return;
//if intersecting a subj line with a subj poly ...
else if (e1->PolyTyp == e2->PolyTyp &&
e1->WindDelta != e2->WindDelta && m_ClipType == ctUnion)
{
if (e1->WindDelta == 0)
{
if (e2Contributing)
{
AddOutPt(e1, Pt);
if (e1Contributing) e1->OutIdx = Unassigned;
}
}
else
{
if (e1Contributing)
{
AddOutPt(e2, Pt);
if (e2Contributing) e2->OutIdx = Unassigned;
}
}
}
else if (e1->PolyTyp != e2->PolyTyp)
{
//toggle subj open path OutIdx on/off when Abs(clip.WndCnt) == 1 ...
if ((e1->WindDelta == 0) && abs(e2->WindCnt) == 1 &&
(m_ClipType != ctUnion || e2->WindCnt2 == 0))
{
AddOutPt(e1, Pt);
if (e1Contributing) e1->OutIdx = Unassigned;
}
else if ((e2->WindDelta == 0) && (abs(e1->WindCnt) == 1) &&
(m_ClipType != ctUnion || e1->WindCnt2 == 0))
{
AddOutPt(e2, Pt);
if (e2Contributing) e2->OutIdx = Unassigned;
}
}
return;
}
#endif
//update winding counts...
//assumes that e1 will be to the Right of e2 ABOVE the intersection
if ( e1->PolyTyp == e2->PolyTyp )
{
if ( IsEvenOddFillType( *e1) )
{
int oldE1WindCnt = e1->WindCnt;
e1->WindCnt = e2->WindCnt;
e2->WindCnt = oldE1WindCnt;
} else
{
if (e1->WindCnt + e2->WindDelta == 0 ) e1->WindCnt = -e1->WindCnt;
else e1->WindCnt += e2->WindDelta;
if ( e2->WindCnt - e1->WindDelta == 0 ) e2->WindCnt = -e2->WindCnt;
else e2->WindCnt -= e1->WindDelta;
}
} else
{
if (!IsEvenOddFillType(*e2)) e1->WindCnt2 += e2->WindDelta;
else e1->WindCnt2 = ( e1->WindCnt2 == 0 ) ? 1 : 0;
if (!IsEvenOddFillType(*e1)) e2->WindCnt2 -= e1->WindDelta;
else e2->WindCnt2 = ( e2->WindCnt2 == 0 ) ? 1 : 0;
}
PolyFillType e1FillType, e2FillType, e1FillType2, e2FillType2;
if (e1->PolyTyp == ptSubject)
{
e1FillType = m_SubjFillType;
e1FillType2 = m_ClipFillType;
} else
{
e1FillType = m_ClipFillType;
e1FillType2 = m_SubjFillType;
}
if (e2->PolyTyp == ptSubject)
{
e2FillType = m_SubjFillType;
e2FillType2 = m_ClipFillType;
} else
{
e2FillType = m_ClipFillType;
e2FillType2 = m_SubjFillType;
}
cInt e1Wc, e2Wc;
switch (e1FillType)
{
case pftPositive: e1Wc = e1->WindCnt; break;
case pftNegative: e1Wc = -e1->WindCnt; break;
default: e1Wc = Abs(e1->WindCnt);
}
switch(e2FillType)
{
case pftPositive: e2Wc = e2->WindCnt; break;
case pftNegative: e2Wc = -e2->WindCnt; break;
default: e2Wc = Abs(e2->WindCnt);
}
if ( e1Contributing && e2Contributing )
{
if ((e1Wc != 0 && e1Wc != 1) || (e2Wc != 0 && e2Wc != 1) ||
(e1->PolyTyp != e2->PolyTyp && m_ClipType != ctXor) )
{
AddLocalMaxPoly(e1, e2, Pt);
}
else
{
AddOutPt(e1, Pt);
AddOutPt(e2, Pt);
SwapSides( *e1 , *e2 );
SwapPolyIndexes( *e1 , *e2 );
}
}
else if ( e1Contributing )
{
if (e2Wc == 0 || e2Wc == 1)
{
AddOutPt(e1, Pt);
SwapSides(*e1, *e2);
SwapPolyIndexes(*e1, *e2);
}
}
else if ( e2Contributing )
{
if (e1Wc == 0 || e1Wc == 1)
{
AddOutPt(e2, Pt);
SwapSides(*e1, *e2);
SwapPolyIndexes(*e1, *e2);
}
}
else if ( (e1Wc == 0 || e1Wc == 1) && (e2Wc == 0 || e2Wc == 1))
{
//neither edge is currently contributing ...
cInt e1Wc2, e2Wc2;
switch (e1FillType2)
{
case pftPositive: e1Wc2 = e1->WindCnt2; break;
case pftNegative : e1Wc2 = -e1->WindCnt2; break;
default: e1Wc2 = Abs(e1->WindCnt2);
}
switch (e2FillType2)
{
case pftPositive: e2Wc2 = e2->WindCnt2; break;
case pftNegative: e2Wc2 = -e2->WindCnt2; break;
default: e2Wc2 = Abs(e2->WindCnt2);
}
if (e1->PolyTyp != e2->PolyTyp)
{
AddLocalMinPoly(e1, e2, Pt);
}
else if (e1Wc == 1 && e2Wc == 1)
switch( m_ClipType ) {
case ctIntersection:
if (e1Wc2 > 0 && e2Wc2 > 0)
AddLocalMinPoly(e1, e2, Pt);
break;
case ctUnion:
if ( e1Wc2 <= 0 && e2Wc2 <= 0 )
AddLocalMinPoly(e1, e2, Pt);
break;
case ctDifference:
if (((e1->PolyTyp == ptClip) && (e1Wc2 > 0) && (e2Wc2 > 0)) ||
((e1->PolyTyp == ptSubject) && (e1Wc2 <= 0) && (e2Wc2 <= 0)))
AddLocalMinPoly(e1, e2, Pt);
break;
case ctXor:
AddLocalMinPoly(e1, e2, Pt);
}
else
SwapSides( *e1, *e2 );
}
}
//------------------------------------------------------------------------------
void Clipper::SetHoleState(TEdge *e, OutRec *outrec)
{
TEdge *e2 = e->PrevInAEL;
TEdge *eTmp = 0;
while (e2)
{
if (e2->OutIdx >= 0 && e2->WindDelta != 0)
{
if (!eTmp) eTmp = e2;
else if (eTmp->OutIdx == e2->OutIdx) eTmp = 0;
}
e2 = e2->PrevInAEL;
}
if (!eTmp)
{
outrec->FirstLeft = 0;
outrec->IsHole = false;
}
else
{
outrec->FirstLeft = m_PolyOuts[eTmp->OutIdx];
outrec->IsHole = !outrec->FirstLeft->IsHole;
}
}
//------------------------------------------------------------------------------
OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
{
//work out which polygon fragment has the correct hole state ...
if (!outRec1->BottomPt)
outRec1->BottomPt = GetBottomPt(outRec1->Pts);
if (!outRec2->BottomPt)
outRec2->BottomPt = GetBottomPt(outRec2->Pts);
OutPt *OutPt1 = outRec1->BottomPt;
OutPt *OutPt2 = outRec2->BottomPt;
if (OutPt1->Pt.Y > OutPt2->Pt.Y) return outRec1;
else if (OutPt1->Pt.Y < OutPt2->Pt.Y) return outRec2;
else if (OutPt1->Pt.X < OutPt2->Pt.X) return outRec1;
else if (OutPt1->Pt.X > OutPt2->Pt.X) return outRec2;
else if (OutPt1->Next == OutPt1) return outRec2;
else if (OutPt2->Next == OutPt2) return outRec1;
else if (FirstIsBottomPt(OutPt1, OutPt2)) return outRec1;
else return outRec2;
}
//------------------------------------------------------------------------------
bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
{
do
{
outRec1 = outRec1->FirstLeft;
if (outRec1 == outRec2) return true;
} while (outRec1);
return false;
}
//------------------------------------------------------------------------------
OutRec* Clipper::GetOutRec(int Idx)
{
OutRec* outrec = m_PolyOuts[Idx];
while (outrec != m_PolyOuts[outrec->Idx])
outrec = m_PolyOuts[outrec->Idx];
return outrec;
}
//------------------------------------------------------------------------------
void Clipper::AppendPolygon(TEdge *e1, TEdge *e2)
{
//get the start and ends of both output polygons ...
OutRec *outRec1 = m_PolyOuts[e1->OutIdx];
OutRec *outRec2 = m_PolyOuts[e2->OutIdx];
OutRec *holeStateRec;
if (OutRec1RightOfOutRec2(outRec1, outRec2))
holeStateRec = outRec2;
else if (OutRec1RightOfOutRec2(outRec2, outRec1))
holeStateRec = outRec1;
else
holeStateRec = GetLowermostRec(outRec1, outRec2);
//get the start and ends of both output polygons and
//join e2 poly onto e1 poly and delete pointers to e2 ...
OutPt* p1_lft = outRec1->Pts;
OutPt* p1_rt = p1_lft->Prev;
OutPt* p2_lft = outRec2->Pts;
OutPt* p2_rt = p2_lft->Prev;
//join e2 poly onto e1 poly and delete pointers to e2 ...
if( e1->Side == esLeft )
{
if( e2->Side == esLeft )
{
//z y x a b c
ReversePolyPtLinks(p2_lft);
p2_lft->Next = p1_lft;
p1_lft->Prev = p2_lft;
p1_rt->Next = p2_rt;
p2_rt->Prev = p1_rt;
outRec1->Pts = p2_rt;
} else
{
//x y z a b c
p2_rt->Next = p1_lft;
p1_lft->Prev = p2_rt;
p2_lft->Prev = p1_rt;
p1_rt->Next = p2_lft;
outRec1->Pts = p2_lft;
}
} else
{
if( e2->Side == esRight )
{
//a b c z y x
ReversePolyPtLinks(p2_lft);
p1_rt->Next = p2_rt;
p2_rt->Prev = p1_rt;
p2_lft->Next = p1_lft;
p1_lft->Prev = p2_lft;
} else
{
//a b c x y z
p1_rt->Next = p2_lft;
p2_lft->Prev = p1_rt;
p1_lft->Prev = p2_rt;
p2_rt->Next = p1_lft;
}
}
outRec1->BottomPt = 0;
if (holeStateRec == outRec2)
{
if (outRec2->FirstLeft != outRec1)
outRec1->FirstLeft = outRec2->FirstLeft;
outRec1->IsHole = outRec2->IsHole;
}
outRec2->Pts = 0;
outRec2->BottomPt = 0;
outRec2->FirstLeft = outRec1;
int OKIdx = e1->OutIdx;
int ObsoleteIdx = e2->OutIdx;
e1->OutIdx = Unassigned; //nb: safe because we only get here via AddLocalMaxPoly
e2->OutIdx = Unassigned;
TEdge* e = m_ActiveEdges;
while( e )
{
if( e->OutIdx == ObsoleteIdx )
{
e->OutIdx = OKIdx;
e->Side = e1->Side;
break;
}
e = e->NextInAEL;
}
outRec2->Idx = outRec1->Idx;
}
//------------------------------------------------------------------------------
OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
{
if( e->OutIdx < 0 )
{
OutRec *outRec = CreateOutRec();
outRec->IsOpen = (e->WindDelta == 0);
OutPt* newOp = new OutPt;
outRec->Pts = newOp;
newOp->Idx = outRec->Idx;
newOp->Pt = pt;
newOp->Next = newOp;
newOp->Prev = newOp;
if (!outRec->IsOpen)
SetHoleState(e, outRec);
e->OutIdx = outRec->Idx;
return newOp;
} else
{
OutRec *outRec = m_PolyOuts[e->OutIdx];
//OutRec.Pts is the 'Left-most' point & OutRec.Pts.Prev is the 'Right-most'
OutPt* op = outRec->Pts;
bool ToFront = (e->Side == esLeft);
if (ToFront && (pt == op->Pt)) return op;
gitextract_zxhxyjoe/ ├── README.md ├── app/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ ├── ch_PP-OCRv3_det.param │ │ ├── ch_PP-OCRv3_rec.param │ │ ├── cls-sim-op.param │ │ ├── det-sim-op.param │ │ ├── paddleocr_keys.txt │ │ ├── pdocrv2.0_det-op.param │ │ ├── pdocrv2.0_rec-op.param │ │ └── rec-sim-op.param │ ├── java/ │ │ └── com/ │ │ └── tencent/ │ │ └── paddleocrncnn/ │ │ ├── MainActivity.java │ │ └── PaddleOCRNcnn.java │ ├── jni/ │ │ ├── CMakeLists.txt │ │ ├── clipper.cpp │ │ ├── clipper.hpp │ │ ├── common.cpp │ │ ├── common.h │ │ └── paddleocr_ncnn.cpp │ └── res/ │ ├── layout/ │ │ └── main.xml │ ├── values/ │ │ └── strings.xml │ └── xml/ │ └── file_paths.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat ├── local.properties └── settings.gradle
SYMBOL INDEX (180 symbols across 7 files)
FILE: app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java
class MainActivity (line 43) | public class MainActivity extends Activity
method onRequestPermissionsResult (line 54) | @Override
method onCreate (line 67) | @Override
method requestPermission (line 123) | private void requestPermission() {
method requestCamera (line 130) | private void requestCamera() {
method showObjects (line 157) | private void showObjects(PaddleOCRNcnn.Obj[] objects)
method onActivityResult (line 236) | @Override
method decodeUri (line 271) | private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException
FILE: app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java
class PaddleOCRNcnn (line 20) | public class PaddleOCRNcnn
method Init (line 22) | public native boolean Init(AssetManager mgr);
class Obj (line 24) | public class Obj
method Detect (line 38) | public native Obj[] Detect(Bitmap bitmap, boolean use_gpu);
FILE: app/src/main/jni/clipper.cpp
type ClipperLib (line 51) | namespace ClipperLib {
type Direction (line 57) | enum Direction { dRightToLeft, dLeftToRight }
type TEdge (line 66) | struct TEdge {
type IntersectNode (line 86) | struct IntersectNode {
type LocalMinimum (line 92) | struct LocalMinimum {
type OutPt (line 98) | struct OutPt
type OutRec (line 102) | struct OutRec {
type OutPt (line 112) | struct OutPt {
type Join (line 119) | struct Join {
type LocMinSorter (line 125) | struct LocMinSorter
function cInt (line 136) | inline cInt Round(double val)
function cInt (line 143) | inline cInt Abs(cInt val)
function PolyNode (line 161) | PolyNode* PolyTree::GetFirst() const
function PolyNode (line 202) | PolyNode* PolyNode::GetNext() const
function PolyNode (line 211) | PolyNode* PolyNode::GetNextSiblingUp() const
class Int128 (line 251) | class Int128
method Int128 (line 257) | Int128(long64 _lo = 0)
method Int128 (line 264) | Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
method Int128 (line 266) | Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
method Int128 (line 268) | Int128& operator = (const long64 &val)
method Int128 (line 303) | Int128& operator += (const Int128 &rhs)
method Int128 (line 311) | Int128 operator + (const Int128 &rhs) const
method Int128 (line 318) | Int128& operator -= (const Int128 &rhs)
method Int128 (line 324) | Int128 operator - (const Int128 &rhs) const
method Int128 (line 331) | Int128 operator-() const //unary negation
function Int128 (line 354) | Int128 Int128Mul (long64 lhs, long64 rhs)
method Int128 (line 257) | Int128(long64 _lo = 0)
method Int128 (line 264) | Int128(const Int128 &val): lo(val.lo), hi(val.hi){}
method Int128 (line 266) | Int128(const long64& _hi, const ulong64& _lo): lo(_lo), hi(_hi){}
method Int128 (line 268) | Int128& operator = (const long64 &val)
method Int128 (line 303) | Int128& operator += (const Int128 &rhs)
method Int128 (line 311) | Int128 operator + (const Int128 &rhs) const
method Int128 (line 318) | Int128& operator -= (const Int128 &rhs)
method Int128 (line 324) | Int128 operator - (const Int128 &rhs) const
method Int128 (line 331) | Int128 operator-() const //unary negation
function Orientation (line 385) | bool Orientation(const Path &poly)
function Area (line 391) | double Area(const Path &poly)
function Area (line 406) | double Area(const OutPt *op)
function Area (line 419) | double Area(const OutRec &outRec)
function PointIsVertex (line 425) | bool PointIsVertex(const IntPoint &Pt, OutPt *pp)
function PointInPolygon (line 440) | int PointInPolygon(const IntPoint &pt, const Path &path)
function PointInPolygon (line 484) | int PointInPolygon (const IntPoint &pt, OutPt *op)
function Poly2ContainsPoly1 (line 526) | bool Poly2ContainsPoly1(OutPt *OutPt1, OutPt *OutPt2)
function SlopesEqual (line 541) | bool SlopesEqual(const TEdge &e1, const TEdge &e2, bool UseFullInt64Ra...
function SlopesEqual (line 554) | bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
function SlopesEqual (line 566) | bool SlopesEqual(const IntPoint pt1, const IntPoint pt2,
function IsHorizontal (line 578) | inline bool IsHorizontal(TEdge &e)
function GetDx (line 584) | inline double GetDx(const IntPoint pt1, const IntPoint pt2)
function SetDx (line 591) | inline void SetDx(TEdge &e)
function SwapSides (line 599) | inline void SwapSides(TEdge &Edge1, TEdge &Edge2)
function SwapPolyIndexes (line 607) | inline void SwapPolyIndexes(TEdge &Edge1, TEdge &Edge2)
function cInt (line 615) | inline cInt TopX(TEdge &edge, const cInt currentY)
function IntersectPoint (line 622) | void IntersectPoint(TEdge &Edge1, TEdge &Edge2, IntPoint &ip)
function ReversePolyPtLinks (line 692) | void ReversePolyPtLinks(OutPt *pp)
function DisposeOutPts (line 706) | void DisposeOutPts(OutPt*& pp)
function InitEdge (line 719) | inline void InitEdge(TEdge* e, TEdge* eNext, TEdge* ePrev, const IntPo...
function InitEdge2 (line 729) | void InitEdge2(TEdge& e, PolyType Pt)
function TEdge (line 745) | TEdge* RemoveEdge(TEdge* e)
function ReverseHorizontal (line 756) | inline void ReverseHorizontal(TEdge &e)
function SwapPoints (line 768) | void SwapPoints(IntPoint &pt1, IntPoint &pt2)
function GetOverlapSegment (line 776) | bool GetOverlapSegment(IntPoint pt1a, IntPoint pt1b, IntPoint pt2a,
function FirstIsBottomPt (line 798) | bool FirstIsBottomPt(const OutPt* btmPt1, const OutPt* btmPt2)
function OutPt (line 822) | OutPt* GetBottomPt(OutPt *pp)
function Pt2IsBetweenPt1AndPt3 (line 860) | bool Pt2IsBetweenPt1AndPt3(const IntPoint pt1,
function HorzSegmentsOverlap (line 872) | bool HorzSegmentsOverlap(cInt seg1a, cInt seg1b, cInt seg2a, cInt seg2b)
function RangeTest (line 896) | void RangeTest(const IntPoint& Pt, bool& useFullRange)
function TEdge (line 911) | TEdge* FindNextLocMin(TEdge* E)
function TEdge (line 928) | TEdge* ClipperBase::ProcessBound(TEdge* E, bool NextIsForward)
function IntRect (line 1295) | IntRect ClipperBase::GetBounds()
function OutRec (line 1380) | OutRec* ClipperBase::CreateOutRec()
function OutPt (line 1842) | OutPt* Clipper::AddLocalMinPoly(TEdge *e1, TEdge *e2, const IntPoint &Pt)
function OutRec (line 2328) | OutRec* GetLowermostRec(OutRec *outRec1, OutRec *outRec2)
function OutRec1RightOfOutRec2 (line 2348) | bool OutRec1RightOfOutRec2(OutRec* outRec1, OutRec* outRec2)
function OutRec (line 2359) | OutRec* Clipper::GetOutRec(int Idx)
function OutPt (line 2464) | OutPt* Clipper::AddOutPt(TEdge *e, const IntPoint &pt)
function OutPt (line 2503) | OutPt* Clipper::GetLastOutPt(TEdge *e)
function IsMinima (line 2521) | inline bool IsMinima(TEdge *e)
function IsMaxima (line 2527) | inline bool IsMaxima(TEdge *e, const cInt Y)
function IsIntermediate (line 2533) | inline bool IsIntermediate(TEdge *e, const cInt Y)
function TEdge (line 2539) | TEdge *GetMaximaPair(TEdge *e)
function TEdge (line 2549) | TEdge *GetMaximaPairEx(TEdge *e)
function TEdge (line 2605) | TEdge* GetNextInAEL(TEdge *e, Direction dir)
function GetHorzDirection (line 2611) | void GetHorzDirection(TEdge& HorzEdge, Direction& Dir, cInt& Left, cIn...
function IntersectListSort (line 2923) | bool IntersectListSort(IntersectNode* node1, IntersectNode* node2)
function EdgesAdjacent (line 2929) | inline bool EdgesAdjacent(const IntersectNode &inode)
function PointCount (line 3186) | int PointCount(OutPt *Pts)
function SwapIntersectNodes (line 3267) | void SwapIntersectNodes(IntersectNode &int1, IntersectNode &int2)
function E2InsertsBeforeE1 (line 3280) | inline bool E2InsertsBeforeE1(TEdge &e1, TEdge &e2)
function GetOverlap (line 3292) | bool GetOverlap(const cInt a1, const cInt a2, const cInt b1, const cIn...
function UpdateOutPtIdxs (line 3309) | inline void UpdateOutPtIdxs(OutRec& outrec)
function OutPt (line 3350) | OutPt* DupOutPt(OutPt* outPt, bool InsertAfter)
function JoinHorz (line 3373) | bool JoinHorz(OutPt* op1, OutPt* op1b, OutPt* op2, OutPt* op2b,
function OutRec (line 3619) | static OutRec* ParseFirstLeft(OutRec* FirstLeft)
function DoublePoint (line 3771) | DoublePoint GetUnitNormal(const IntPoint &pt1, const IntPoint &pt2)
function ReversePath (line 4285) | void ReversePath(Path& p)
function ReversePaths (line 4291) | void ReversePaths(Paths& p)
function SimplifyPolygon (line 4298) | void SimplifyPolygon(const Path &in_poly, Paths &out_polys, PolyFillTy...
function SimplifyPolygons (line 4307) | void SimplifyPolygons(const Paths &in_polys, Paths &out_polys, PolyFil...
function SimplifyPolygons (line 4316) | void SimplifyPolygons(Paths &polys, PolyFillType fillType)
function DistanceSqrd (line 4322) | inline double DistanceSqrd(const IntPoint& pt1, const IntPoint& pt2)
function DistanceFromLineSqrd (line 4330) | double DistanceFromLineSqrd(
function SlopesNearCollinear (line 4347) | bool SlopesNearCollinear(const IntPoint& pt1,
function PointsAreClose (line 4374) | bool PointsAreClose(IntPoint pt1, IntPoint pt2, double distSqrd)
function OutPt (line 4382) | OutPt* ExcludeOp(OutPt* op)
function CleanPolygon (line 4392) | void CleanPolygon(const Path& in_poly, Path& out_poly, double distance)
function CleanPolygon (line 4452) | void CleanPolygon(Path& poly, double distance)
function CleanPolygons (line 4458) | void CleanPolygons(const Paths& in_polys, Paths& out_polys, double dis...
function CleanPolygons (line 4466) | void CleanPolygons(Paths& polys, double distance)
function Minkowski (line 4472) | void Minkowski(const Path& poly, const Path& path,
function MinkowskiSum (line 4516) | void MinkowskiSum(const Path& pattern, const Path& path, Paths& soluti...
function TranslatePath (line 4525) | void TranslatePath(const Path& input, Path& output, const IntPoint delta)
function MinkowskiSum (line 4534) | void MinkowskiSum(const Path& pattern, const Paths& paths, Paths& solu...
function MinkowskiDiff (line 4553) | void MinkowskiDiff(const Path& poly1, const Path& poly2, Paths& solution)
type NodeType (line 4562) | enum NodeType {ntAny, ntOpen, ntClosed}
function AddPolyNodeToPaths (line 4564) | void AddPolyNodeToPaths(const PolyNode& polynode, NodeType nodetype, P...
function PolyTreeToPaths (line 4577) | void PolyTreeToPaths(const PolyTree& polytree, Paths& paths)
function ClosedPathsFromPolyTree (line 4585) | void ClosedPathsFromPolyTree(const PolyTree& polytree, Paths& paths)
function OpenPathsFromPolyTree (line 4593) | void OpenPathsFromPolyTree(PolyTree& polytree, Paths& paths)
FILE: app/src/main/jni/clipper.hpp
type ClipperLib (line 62) | namespace ClipperLib {
type ClipType (line 64) | enum ClipType { ctIntersection, ctUnion, ctDifference, ctXor }
type PolyType (line 65) | enum PolyType { ptSubject, ptClip }
type PolyFillType (line 70) | enum PolyFillType { pftEvenOdd, pftNonZero, pftPositive, pftNegative }
type IntPoint (line 85) | struct IntPoint {
method IntPoint (line 90) | IntPoint(cInt x = 0, cInt y = 0, cInt z = 0): X(x), Y(y), Z(z) {}
method IntPoint (line 92) | IntPoint(cInt x = 0, cInt y = 0): X(x), Y(y) {}
function Path (line 109) | inline Path& operator <<(Path& poly, const IntPoint& p) {poly.push_bac...
function Paths (line 110) | inline Paths& operator <<(Paths& polys, const Path& p) {polys.push_bac...
type DoublePoint (line 116) | struct DoublePoint
method DoublePoint (line 120) | DoublePoint(double x = 0, double y = 0) : X(x), Y(y) {}
method DoublePoint (line 121) | DoublePoint(IntPoint ip) : X((double)ip.X), Y((double)ip.Y) {}
type InitOptions (line 129) | enum InitOptions {ioReverseSolution = 1, ioStrictlySimple = 2, ioPrese...
type JoinType (line 130) | enum JoinType {jtSquare, jtRound, jtMiter}
type EndType (line 131) | enum EndType {etClosedPolygon, etClosedLine, etOpenButt, etOpenSquare,...
class PolyNode (line 133) | class PolyNode
class PolyNode (line 136) | class PolyNode
class PolyTree (line 160) | class PolyTree: public PolyNode
type IntRect (line 197) | struct IntRect { cInt left; cInt top; cInt right; cInt bottom; }
type EdgeSide (line 200) | enum EdgeSide { esLeft = 1, esRight = 2}
type TEdge (line 203) | struct TEdge
type IntersectNode (line 204) | struct IntersectNode
type LocalMinimum (line 205) | struct LocalMinimum
type OutPt (line 206) | struct OutPt
type OutRec (line 207) | struct OutRec
type Join (line 208) | struct Join
class ClipperBase (line 220) | class ClipperBase
method PreserveCollinear (line 229) | bool PreserveCollinear() {return m_PreserveCollinear;}
method PreserveCollinear (line 230) | void PreserveCollinear(bool value) {m_PreserveCollinear = value;}
class Clipper (line 263) | class Clipper : public virtual ClipperBase
method ReverseSolution (line 281) | bool ReverseSolution() { return m_ReverseOutput; }
method ReverseSolution (line 282) | void ReverseSolution(bool value) {m_ReverseOutput = value;}
method StrictlySimple (line 283) | bool StrictlySimple() {return m_StrictSimple;}
method StrictlySimple (line 284) | void StrictlySimple(bool value) {m_StrictSimple = value;}
class ClipperOffset (line 360) | class ClipperOffset
class clipperException (line 391) | class clipperException : public std::exception
method clipperException (line 394) | clipperException(const char* description): m_descr(description) {}
FILE: app/src/main/jni/common.cpp
function cvPointCompare (line 4) | bool cvPointCompare(const cv::Point& a, const cv::Point& b) {
function compareBoxWidth (line 7) | bool compareBoxWidth(const TextBox &a, const TextBox& b)
function getMinBoxes (line 12) | std::vector<cv::Point> getMinBoxes(const std::vector<cv::Point>& inVec, ...
function boxScoreFast (line 60) | float boxScoreFast(const cv::Mat & inMat, const std::vector<cv::Point> &...
function unClip (line 93) | std::vector<cv::Point> unClip(const std::vector<cv::Point> & inBox, floa...
function getRotateCropImage (line 120) | cv::Mat getRotateCropImage(const cv::Mat& src, std::vector<cv::Point> bo...
function getPartImages (line 175) | std::vector<cv::Mat> getPartImages(const cv::Mat& src, std::vector<TextB...
function matRotateClockWise180 (line 190) | cv::Mat matRotateClockWise180(cv::Mat src) {
function makePadding (line 196) | cv::Mat makePadding(cv::Mat& src, const int padding) {
FILE: app/src/main/jni/common.h
type TextBox (line 7) | struct TextBox {
type TextLine (line 12) | struct TextLine {
type Angle (line 17) | struct Angle {
FILE: app/src/main/jni/paddleocr_ncnn.cpp
function findRsBoxes (line 58) | std::vector<TextBox> findRsBoxes(const cv::Mat& fMapMat, const cv::Mat& ...
function getTextBoxes (line 99) | std::vector<TextBox> getTextBoxes(const cv::Mat & src, float boxScoreThr...
function argmax (line 163) | inline static size_t argmax(ForwardIterator first, ForwardIterator last) {
function TextLine (line 167) | TextLine scoreToTextLine(const std::vector<float>& outputData, int h, in...
function TextLine (line 192) | TextLine getTextLine(const cv::Mat & src)
function getTextLines (line 217) | std::vector<TextLine> getTextLines(std::vector<cv::Mat> & partImg) {
function JNIEXPORT (line 244) | JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
function JNIEXPORT (line 253) | JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
function JNIEXPORT (line 261) | JNIEXPORT jboolean JNICALL Java_com_tencent_paddleocrncnn_PaddleOCRNcnn_...
function JNIEXPORT (line 352) | JNIEXPORT jobjectArray JNICALL Java_com_tencent_paddleocrncnn_PaddleOCRN...
Condensed preview — 29 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (356K chars).
[
{
"path": "README.md",
"chars": 1809,
"preview": "# ncnn_paddleocr\nThis is a sample paddleocr ncnn android project, it depends on ncnn library and opencv \nhttps://github"
},
{
"path": "app/build.gradle",
"chars": 589,
"preview": "apply plugin: 'com.android.application'\n\nandroid {\n compileSdkVersion 24\n buildToolsVersion \"29.0.2\"\n\n defaultC"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 1184,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n packag"
},
{
"path": "app/src/main/assets/ch_PP-OCRv3_det.param",
"chars": 18203,
"preview": "7767517\n153 185\nInput x 0 1 input\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/ch_PP-OCRv3_rec.param",
"chars": 13790,
"preview": "7767517\n116 127\nInput input 0 1 input\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/cls-sim-op.param",
"chars": 11188,
"preview": "7767517\n135 151\nInput input 0 1 input\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/det-sim-op.param",
"chars": 9938,
"preview": "7767517\n115 131\nInput input 0 1 input0\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/paddleocr_keys.txt",
"chars": 13245,
"preview": "'\n疗\n绚\n诚\n娇\n溜\n题\n贿\n者\n廖\n更\n纳\n加\n奉\n公\n一\n就\n汴\n计\n与\n路\n房\n原\n妇\n2\n0\n8\n-\n7\n其\n>\n:\n]\n,\n,\n骑\n刈\n全\n消\n昏\n傈\n安\n久\n钟\n嗅\n不\n影\n处\n驽\n蜿\n资\n关\n椤\n地\n瘸\n专\n问\n忖\n票\n嫉\n"
},
{
"path": "app/src/main/assets/pdocrv2.0_det-op.param",
"chars": 9938,
"preview": "7767517\n115 131\nInput input 0 1 input0\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/pdocrv2.0_rec-op.param",
"chars": 6135,
"preview": "7767517\n75 77\nInput input 0 1 input\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/rec-sim-op.param",
"chars": 11451,
"preview": "7767517\n138 154\nInput input 0 1 input\nConvolution Conv_0 "
},
{
"path": "app/src/main/java/com/tencent/paddleocrncnn/MainActivity.java",
"chars": 12406,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
},
{
"path": "app/src/main/java/com/tencent/paddleocrncnn/PaddleOCRNcnn.java",
"chars": 1322,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
},
{
"path": "app/src/main/jni/CMakeLists.txt",
"chars": 454,
"preview": "project(paddleocrncnn)\n\ncmake_minimum_required(VERSION 3.4.1)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.1-an"
},
{
"path": "app/src/main/jni/clipper.cpp",
"chars": 167441,
"preview": "/*******************************************************************************\n* "
},
{
"path": "app/src/main/jni/clipper.hpp",
"chars": 16486,
"preview": "/*******************************************************************************\n* "
},
{
"path": "app/src/main/jni/common.cpp",
"chars": 6462,
"preview": "#include \"common.h\"\n#include <jni.h>\n#include <android/log.h>\nbool cvPointCompare(const cv::Point& a, const cv::Point& b"
},
{
"path": "app/src/main/jni/common.h",
"chars": 918,
"preview": "#ifndef __COMMON_H_\n#define __COMMON_H_\n#include <opencv2/opencv.hpp>\n#include <vector>\n#include \"clipper.hpp\"\n#include "
},
{
"path": "app/src/main/jni/paddleocr_ncnn.cpp",
"chars": 13358,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2020 THL A29 Li"
},
{
"path": "app/src/main/res/layout/main.xml",
"chars": 1276,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n andr"
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 116,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"app_name\">paddleocr_ncnn</string>\n</resources>\n"
},
{
"path": "app/src/main/res/xml/file_paths.xml",
"chars": 177,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<paths xmlns:android=\"http://schemas.android.com/apk/res/android\">\n <external-"
},
{
"path": "build.gradle",
"chars": 335,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nbuildscript {\n re"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 232,
"preview": "#Sun Aug 25 10:34:48 CST 2019\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\nzipStoreBase=GRADLE_USER_"
},
{
"path": "gradlew",
"chars": 5296,
"preview": "#!/usr/bin/env sh\n\n##############################################################################\n##\n## Gradle start up"
},
{
"path": "gradlew.bat",
"chars": 2176,
"preview": "@if \"%DEBUG%\" == \"\" @echo off\n@rem ##########################################################################\n@rem\n@rem "
},
{
"path": "local.properties",
"chars": 325,
"preview": "## This file must *NOT* be checked into Version Control Systems,\n# as it contains information specific to your local con"
},
{
"path": "settings.gradle",
"chars": 15,
"preview": "include ':app'\n"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the FeiGeChuanShu/ncnn_paddleocr GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 29 files (318.6 KB), approximately 107.4k tokens, and a symbol index with 180 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.