├── .DS_Store
├── .gitignore
├── README.md
├── app
├── build.gradle
└── src
│ └── main
│ ├── AndroidManifest.xml
│ ├── assets
│ ├── nanodet-m-416.bin
│ ├── nanodet-m-416.param
│ ├── out.mp4
│ ├── picodet-l-640.bin
│ ├── picodet-l-640.param
│ ├── picodet-s-416.bin
│ ├── picodet-s-416.param
│ ├── yolov5s.bin
│ ├── yolov5s.param
│ ├── yolox-nano.bin
│ └── yolox-nano.param
│ ├── java
│ └── com
│ │ └── baidu
│ │ ├── common
│ │ ├── AppCompatPreferenceActivity.java
│ │ ├── CameraSurfaceView.java
│ │ └── Utils.java
│ │ └── picodetncnn
│ │ ├── CameraFragment.java
│ │ ├── ContentFragment.java
│ │ ├── MainActivity.java
│ │ ├── NanoDetNcnn.java
│ │ └── PhotoFragment.java
│ ├── jni
│ ├── CMakeLists.txt
│ ├── nanodet.cpp
│ ├── nanodet.h
│ ├── nanodetncnn.cpp
│ ├── ndk-stl-config.cmake
│ ├── ndkcamera.cpp
│ └── ndkcamera.h
│ └── res
│ ├── drawable-v24
│ ├── camera.png
│ ├── ic_launcher_foreground.xml
│ └── photo.png
│ ├── drawable-xxhdpi
│ ├── btn_switch_default.png
│ ├── btn_switch_pressed.png
│ ├── camera.png
│ ├── paddle.png
│ └── photo.png
│ ├── drawable
│ ├── btn_settings.xml
│ ├── btn_settings_default.xml
│ ├── btn_settings_pressed.xml
│ ├── btn_shutter.xml
│ ├── btn_shutter_default.xml
│ ├── btn_shutter_pressed.xml
│ ├── btn_switch.xml
│ ├── camera.png
│ ├── ic_launcher_background.xml
│ ├── photo.png
│ └── photo1.png
│ ├── layout
│ ├── activity_main.xml
│ ├── content_main.xml
│ ├── fragment_camera.xml
│ ├── fragment_content.xml
│ └── fragment_photo.xml
│ ├── menu
│ └── menu_main.xml
│ ├── navigation
│ └── nav_graph.xml
│ └── values
│ ├── colors.xml
│ ├── dimens.xml
│ ├── strings.xml
│ └── styles.xml
├── build.gradle
├── downloadQrcode.png
├── gradle.properties
├── gradle
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── local.properties
├── ncnn
├── README.md
├── nanodet-small.gif
└── picodet-small.gif
├── old_assset
├── nanodet-m-320.bin
├── nanodet-m-320.param
├── nanodet-m-416.bin
├── nanodet-m-416.param
├── nanodet-m.param
├── out.avi
├── out.mp4
├── picodet-m-processed-320.bin
├── picodet-m-processed-320.param
├── picodet-m-processed-416.bin
├── picodet-m-processed-416.param
├── picodet-s-four-head.bin
├── picodet-s-four-head.param
├── picodet-s-three-head.bin
├── picodet-s-three-head.param
├── yolov5s.bin
├── yolov5s.param
├── yolox-nano.bin
└── yolox-nano.param
├── paddlelite
└── README.md
├── screenshot_car.jpg
└── settings.gradle
/.DS_Store:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/.DS_Store
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | .gradle
3 | app/.cxx
4 | app/build
5 | app/release
6 | app/src/main/assets/old_assset
7 | app/src/main/jni/aaa
8 | app/src/main/jni/ncnn-20210720-android-vulkan
9 | app/src/main/jni/opencv
10 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PP-PicoDet-Android-Demo
2 | The PicoDet object detection mobile demo
3 |
4 | # Support Library
5 | [NCNN](ncnn/README.md)
6 | [Paddle-LIte](paddlelite/README.md)
7 |
8 | # Apk Download
9 | ### [download link](https://paddledet.bj.bcebos.com/deploy/third_engine/PP-PicoDet.apk)
10 |
11 | ### scan to download
12 |
13 |
--------------------------------------------------------------------------------
/app/build.gradle:
--------------------------------------------------------------------------------
1 | apply plugin: 'com.android.application'
2 |
3 | android {
4 | compileSdkVersion 28
5 | // buildToolsVersion "29.0.3"
6 |
7 | defaultConfig {
8 | applicationId "com.baidu.picodetncnn"
9 | archivesBaseName = "$applicationId"
10 | minSdkVersion 24
11 | }
12 |
13 | externalNativeBuild {
14 | cmake {
15 | version "3.10.2"
16 | path file('src/main/jni/CMakeLists.txt')
17 | // abiFilters "armeabi"
18 | }
19 |
20 | }
21 | sourceSets {
22 | main {
23 | jniLibs.srcDirs = ['libs']
24 | }
25 |
26 | }
27 | // ndk{
28 | // abiFilters "armeabi-v7a"
29 | // }
30 | }
31 |
32 | dependencies {
33 | implementation fileTree(dir: "libs", include: ["*.jar"])
34 | implementation 'androidx.appcompat:appcompat:1.1.0'
35 | implementation 'com.google.android.material:material:1.0.0'
36 | implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
37 | implementation 'androidx.navigation:navigation-fragment:2.1.0'
38 | implementation 'androidx.navigation:navigation-ui:2.1.0'
39 | testImplementation 'junit:junit:4.12'
40 | androidTestImplementation 'androidx.test.ext:junit:1.1.1'
41 | androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
42 | }
43 |
44 |
--------------------------------------------------------------------------------
/app/src/main/AndroidManifest.xml:
--------------------------------------------------------------------------------
1 |
2 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
21 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/app/src/main/assets/nanodet-m-416.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/nanodet-m-416.bin
--------------------------------------------------------------------------------
/app/src/main/assets/nanodet-m-416.param:
--------------------------------------------------------------------------------
1 | 7767517
2 | 201 226
3 | Input input.1 0 1 input.1
4 | Convolution Conv_0 1 1 input.1 784 0=24 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=648
5 | ReLU LeakyRelu_1 1 1 784 424 0=1.000000e-01
6 | Pooling MaxPool_2 1 1 424 425 0=0 1=3 11=3 2=2 12=2 3=1 13=1 14=1 15=1 5=1
7 | Split splitncnn_0 1 2 425 425_splitncnn_0 425_splitncnn_1
8 | ConvolutionDepthWise Conv_3 1 1 425_splitncnn_1 787 0=24 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=216 7=24
9 | Convolution Conv_4 1 1 787 790 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=2112
10 | ReLU LeakyRelu_5 1 1 790 430 0=1.000000e-01
11 | Convolution Conv_6 1 1 425_splitncnn_0 793 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=2112
12 | ReLU LeakyRelu_7 1 1 793 433 0=1.000000e-01
13 | ConvolutionDepthWise Conv_8 1 1 433 796 0=88 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=792 7=88
14 | Convolution Conv_9 1 1 796 799 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
15 | ReLU LeakyRelu_10 1 1 799 438 0=1.000000e-01
16 | Concat Concat_11 2 1 430 438 439 0=0
17 | ShuffleChannel Reshape_16 1 1 439 444 0=2 1=0
18 | Slice Split_17 1 2 444 445 446 -23300=2,88,-233 1=0
19 | Convolution Conv_18 1 1 446 802 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
20 | ReLU LeakyRelu_19 1 1 802 449 0=1.000000e-01
21 | ConvolutionDepthWise Conv_20 1 1 449 805 0=88 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=792 7=88
22 | Convolution Conv_21 1 1 805 808 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
23 | ReLU LeakyRelu_22 1 1 808 454 0=1.000000e-01
24 | Concat Concat_23 2 1 445 454 455 0=0
25 | ShuffleChannel Reshape_28 1 1 455 460 0=2 1=0
26 | Slice Split_29 1 2 460 461 462 -23300=2,88,-233 1=0
27 | Convolution Conv_30 1 1 462 811 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
28 | ReLU LeakyRelu_31 1 1 811 465 0=1.000000e-01
29 | ConvolutionDepthWise Conv_32 1 1 465 814 0=88 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=792 7=88
30 | Convolution Conv_33 1 1 814 817 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
31 | ReLU LeakyRelu_34 1 1 817 470 0=1.000000e-01
32 | Concat Concat_35 2 1 461 470 471 0=0
33 | ShuffleChannel Reshape_40 1 1 471 476 0=2 1=0
34 | Slice Split_41 1 2 476 477 478 -23300=2,88,-233 1=0
35 | Convolution Conv_42 1 1 478 820 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
36 | ReLU LeakyRelu_43 1 1 820 481 0=1.000000e-01
37 | ConvolutionDepthWise Conv_44 1 1 481 823 0=88 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=792 7=88
38 | Convolution Conv_45 1 1 823 826 0=88 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=7744
39 | ReLU LeakyRelu_46 1 1 826 486 0=1.000000e-01
40 | Concat Concat_47 2 1 477 486 487 0=0
41 | ShuffleChannel Reshape_52 1 1 487 492 0=2 1=0
42 | Split splitncnn_1 1 3 492 492_splitncnn_0 492_splitncnn_1 492_splitncnn_2
43 | ConvolutionDepthWise Conv_53 1 1 492_splitncnn_2 829 0=176 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
44 | Convolution Conv_54 1 1 829 832 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
45 | ReLU LeakyRelu_55 1 1 832 497 0=1.000000e-01
46 | Convolution Conv_56 1 1 492_splitncnn_1 835 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
47 | ReLU LeakyRelu_57 1 1 835 500 0=1.000000e-01
48 | ConvolutionDepthWise Conv_58 1 1 500 838 0=176 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
49 | Convolution Conv_59 1 1 838 841 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
50 | ReLU LeakyRelu_60 1 1 841 505 0=1.000000e-01
51 | Concat Concat_61 2 1 497 505 506 0=0
52 | ShuffleChannel Reshape_66 1 1 506 511 0=2 1=0
53 | Slice Split_67 1 2 511 512 513 -23300=2,176,-233 1=0
54 | Convolution Conv_68 1 1 513 844 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
55 | ReLU LeakyRelu_69 1 1 844 516 0=1.000000e-01
56 | ConvolutionDepthWise Conv_70 1 1 516 847 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
57 | Convolution Conv_71 1 1 847 850 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
58 | ReLU LeakyRelu_72 1 1 850 521 0=1.000000e-01
59 | Concat Concat_73 2 1 512 521 522 0=0
60 | ShuffleChannel Reshape_78 1 1 522 527 0=2 1=0
61 | Slice Split_79 1 2 527 528 529 -23300=2,176,-233 1=0
62 | Convolution Conv_80 1 1 529 853 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
63 | ReLU LeakyRelu_81 1 1 853 532 0=1.000000e-01
64 | ConvolutionDepthWise Conv_82 1 1 532 856 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
65 | Convolution Conv_83 1 1 856 859 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
66 | ReLU LeakyRelu_84 1 1 859 537 0=1.000000e-01
67 | Concat Concat_85 2 1 528 537 538 0=0
68 | ShuffleChannel Reshape_90 1 1 538 543 0=2 1=0
69 | Slice Split_91 1 2 543 544 545 -23300=2,176,-233 1=0
70 | Convolution Conv_92 1 1 545 862 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
71 | ReLU LeakyRelu_93 1 1 862 548 0=1.000000e-01
72 | ConvolutionDepthWise Conv_94 1 1 548 865 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
73 | Convolution Conv_95 1 1 865 868 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
74 | ReLU LeakyRelu_96 1 1 868 553 0=1.000000e-01
75 | Concat Concat_97 2 1 544 553 554 0=0
76 | ShuffleChannel Reshape_102 1 1 554 559 0=2 1=0
77 | Slice Split_103 1 2 559 560 561 -23300=2,176,-233 1=0
78 | Convolution Conv_104 1 1 561 871 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
79 | ReLU LeakyRelu_105 1 1 871 564 0=1.000000e-01
80 | ConvolutionDepthWise Conv_106 1 1 564 874 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
81 | Convolution Conv_107 1 1 874 877 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
82 | ReLU LeakyRelu_108 1 1 877 569 0=1.000000e-01
83 | Concat Concat_109 2 1 560 569 570 0=0
84 | ShuffleChannel Reshape_114 1 1 570 575 0=2 1=0
85 | Slice Split_115 1 2 575 576 577 -23300=2,176,-233 1=0
86 | Convolution Conv_116 1 1 577 880 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
87 | ReLU LeakyRelu_117 1 1 880 580 0=1.000000e-01
88 | ConvolutionDepthWise Conv_118 1 1 580 883 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
89 | Convolution Conv_119 1 1 883 886 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
90 | ReLU LeakyRelu_120 1 1 886 585 0=1.000000e-01
91 | Concat Concat_121 2 1 576 585 586 0=0
92 | ShuffleChannel Reshape_126 1 1 586 591 0=2 1=0
93 | Slice Split_127 1 2 591 592 593 -23300=2,176,-233 1=0
94 | Convolution Conv_128 1 1 593 889 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
95 | ReLU LeakyRelu_129 1 1 889 596 0=1.000000e-01
96 | ConvolutionDepthWise Conv_130 1 1 596 892 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
97 | Convolution Conv_131 1 1 892 895 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
98 | ReLU LeakyRelu_132 1 1 895 601 0=1.000000e-01
99 | Concat Concat_133 2 1 592 601 602 0=0
100 | ShuffleChannel Reshape_138 1 1 602 607 0=2 1=0
101 | Slice Split_139 1 2 607 608 609 -23300=2,176,-233 1=0
102 | Convolution Conv_140 1 1 609 898 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
103 | ReLU LeakyRelu_141 1 1 898 612 0=1.000000e-01
104 | ConvolutionDepthWise Conv_142 1 1 612 901 0=176 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1584 7=176
105 | Convolution Conv_143 1 1 901 904 0=176 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=30976
106 | ReLU LeakyRelu_144 1 1 904 617 0=1.000000e-01
107 | Concat Concat_145 2 1 608 617 618 0=0
108 | ShuffleChannel Reshape_150 1 1 618 623 0=2 1=0
109 | Split splitncnn_2 1 3 623 623_splitncnn_0 623_splitncnn_1 623_splitncnn_2
110 | ConvolutionDepthWise Conv_151 1 1 623_splitncnn_2 907 0=352 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=3168 7=352
111 | Convolution Conv_152 1 1 907 910 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
112 | ReLU LeakyRelu_153 1 1 910 628 0=1.000000e-01
113 | Convolution Conv_154 1 1 623_splitncnn_1 913 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
114 | ReLU LeakyRelu_155 1 1 913 631 0=1.000000e-01
115 | ConvolutionDepthWise Conv_156 1 1 631 916 0=352 1=3 11=3 2=1 12=1 3=2 13=2 4=1 14=1 15=1 16=1 5=1 6=3168 7=352
116 | Convolution Conv_157 1 1 916 919 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
117 | ReLU LeakyRelu_158 1 1 919 636 0=1.000000e-01
118 | Concat Concat_159 2 1 628 636 637 0=0
119 | ShuffleChannel Reshape_164 1 1 637 642 0=2 1=0
120 | Slice Split_165 1 2 642 643 644 -23300=2,352,-233 1=0
121 | Convolution Conv_166 1 1 644 922 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
122 | ReLU LeakyRelu_167 1 1 922 647 0=1.000000e-01
123 | ConvolutionDepthWise Conv_168 1 1 647 925 0=352 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=3168 7=352
124 | Convolution Conv_169 1 1 925 928 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
125 | ReLU LeakyRelu_170 1 1 928 652 0=1.000000e-01
126 | Concat Concat_171 2 1 643 652 653 0=0
127 | ShuffleChannel Reshape_176 1 1 653 658 0=2 1=0
128 | Slice Split_177 1 2 658 659 660 -23300=2,352,-233 1=0
129 | Convolution Conv_178 1 1 660 931 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
130 | ReLU LeakyRelu_179 1 1 931 663 0=1.000000e-01
131 | ConvolutionDepthWise Conv_180 1 1 663 934 0=352 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=3168 7=352
132 | Convolution Conv_181 1 1 934 937 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
133 | ReLU LeakyRelu_182 1 1 937 668 0=1.000000e-01
134 | Concat Concat_183 2 1 659 668 669 0=0
135 | ShuffleChannel Reshape_188 1 1 669 674 0=2 1=0
136 | Slice Split_189 1 2 674 675 676 -23300=2,352,-233 1=0
137 | Convolution Conv_190 1 1 676 940 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
138 | ReLU LeakyRelu_191 1 1 940 679 0=1.000000e-01
139 | ConvolutionDepthWise Conv_192 1 1 679 943 0=352 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=3168 7=352
140 | Convolution Conv_193 1 1 943 946 0=352 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=123904
141 | ReLU LeakyRelu_194 1 1 946 684 0=1.000000e-01
142 | Concat Concat_195 2 1 675 684 685 0=0
143 | ShuffleChannel Reshape_200 1 1 685 690 0=2 1=0
144 | Convolution Conv_201 1 1 492_splitncnn_0 691 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=22528
145 | Convolution Conv_202 1 1 623_splitncnn_0 692 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=45056
146 | Convolution Conv_203 1 1 690 693 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=90112
147 | Split splitncnn_3 1 2 693 693_splitncnn_0 693_splitncnn_1
148 | Interp Resize_205 1 1 693_splitncnn_1 698 0=2 1=2.000000e+00 2=2.000000e+00 3=0 4=0 6=0
149 | BinaryOp Add_206 2 1 692 698 699 0=0
150 | Split splitncnn_4 1 2 699 699_splitncnn_0 699_splitncnn_1
151 | Interp Resize_208 1 1 699_splitncnn_1 704 0=2 1=2.000000e+00 2=2.000000e+00 3=0 4=0 6=0
152 | BinaryOp Add_209 2 1 691 704 705 0=0
153 | Split splitncnn_5 1 2 705 705_splitncnn_0 705_splitncnn_1
154 | Interp Resize_211 1 1 705_splitncnn_1 710 0=2 1=5.000000e-01 2=5.000000e-01 3=0 4=0 6=0
155 | BinaryOp Add_212 2 1 699_splitncnn_0 710 711 0=0
156 | Split splitncnn_6 1 2 711 711_splitncnn_0 711_splitncnn_1
157 | Interp Resize_214 1 1 711_splitncnn_1 716 0=2 1=5.000000e-01 2=5.000000e-01 3=0 4=0 6=0
158 | BinaryOp Add_215 2 1 693_splitncnn_0 716 717 0=0
159 | ConvolutionDepthWise Conv_216 1 1 705_splitncnn_0 949 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
160 | ReLU LeakyRelu_217 1 1 949 720 0=1.000000e-01
161 | Convolution Conv_218 1 1 720 952 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
162 | ReLU LeakyRelu_219 1 1 952 723 0=1.000000e-01
163 | ConvolutionDepthWise Conv_220 1 1 723 955 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
164 | ReLU LeakyRelu_221 1 1 955 726 0=1.000000e-01
165 | Convolution Conv_222 1 1 726 958 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
166 | ReLU LeakyRelu_223 1 1 958 729 0=1.000000e-01
167 | Convolution Conv_224 1 1 729 730 0=112 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=14336
168 | Slice Split_225 1 2 730 731 732 -23300=2,80,-233 1=0
169 | Sigmoid Sigmoid_226 1 1 731 733
170 | Reshape Reshape_228 1 1 733 735 0=-1 1=80
171 | Permute Transpose_229 1 1 735 cls_pred_stride_8 0=1
172 | Reshape Reshape_231 1 1 732 738 0=-1 1=32
173 | Permute Transpose_232 1 1 738 dis_pred_stride_8 0=1
174 | ConvolutionDepthWise Conv_233 1 1 711_splitncnn_0 961 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
175 | ReLU LeakyRelu_234 1 1 961 742 0=1.000000e-01
176 | Convolution Conv_235 1 1 742 964 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
177 | ReLU LeakyRelu_236 1 1 964 745 0=1.000000e-01
178 | ConvolutionDepthWise Conv_237 1 1 745 967 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
179 | ReLU LeakyRelu_238 1 1 967 748 0=1.000000e-01
180 | Convolution Conv_239 1 1 748 970 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
181 | ReLU LeakyRelu_240 1 1 970 751 0=1.000000e-01
182 | Convolution Conv_241 1 1 751 752 0=112 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=14336
183 | Slice Split_242 1 2 752 753 754 -23300=2,80,-233 1=0
184 | Sigmoid Sigmoid_243 1 1 753 755
185 | Reshape Reshape_245 1 1 755 757 0=-1 1=80
186 | Permute Transpose_246 1 1 757 cls_pred_stride_16 0=1
187 | Reshape Reshape_248 1 1 754 760 0=-1 1=32
188 | Permute Transpose_249 1 1 760 dis_pred_stride_16 0=1
189 | ConvolutionDepthWise Conv_250 1 1 717 973 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
190 | ReLU LeakyRelu_251 1 1 973 764 0=1.000000e-01
191 | Convolution Conv_252 1 1 764 976 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
192 | ReLU LeakyRelu_253 1 1 976 767 0=1.000000e-01
193 | ConvolutionDepthWise Conv_254 1 1 767 979 0=128 1=3 11=3 2=1 12=1 3=1 13=1 4=1 14=1 15=1 16=1 5=1 6=1152 7=128
194 | ReLU LeakyRelu_255 1 1 979 770 0=1.000000e-01
195 | Convolution Conv_256 1 1 770 982 0=128 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=16384
196 | ReLU LeakyRelu_257 1 1 982 773 0=1.000000e-01
197 | Convolution Conv_258 1 1 773 774 0=112 1=1 11=1 2=1 12=1 3=1 13=1 4=0 14=0 15=0 16=0 5=1 6=14336
198 | Slice Split_259 1 2 774 775 776 -23300=2,80,-233 1=0
199 | Sigmoid Sigmoid_260 1 1 775 777
200 | Reshape Reshape_262 1 1 777 779 0=-1 1=80
201 | Permute Transpose_263 1 1 779 cls_pred_stride_32 0=1
202 | Reshape Reshape_265 1 1 776 782 0=-1 1=32
203 | Permute Transpose_266 1 1 782 dis_pred_stride_32 0=1
204 |
--------------------------------------------------------------------------------
/app/src/main/assets/out.mp4:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/out.mp4
--------------------------------------------------------------------------------
/app/src/main/assets/picodet-l-640.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/picodet-l-640.bin
--------------------------------------------------------------------------------
/app/src/main/assets/picodet-s-416.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/picodet-s-416.bin
--------------------------------------------------------------------------------
/app/src/main/assets/yolov5s.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/yolov5s.bin
--------------------------------------------------------------------------------
/app/src/main/assets/yolov5s.param:
--------------------------------------------------------------------------------
1 | 7767517
2 | 192 216
3 | Input images 0 1 images
4 | YoloV5Focus focus 1 1 images 207
5 | Convolution Conv_41 1 1 207 208 0=32 1=3 4=1 5=1 6=3456
6 | HardSwish Div_49 1 1 208 216 0=1.666667e-01
7 | Convolution Conv_50 1 1 216 217 0=64 1=3 3=2 4=1 5=1 6=18432
8 | HardSwish Div_58 1 1 217 225 0=1.666667e-01
9 | Split splitncnn_0 1 2 225 225_splitncnn_0 225_splitncnn_1
10 | Convolution Conv_59 1 1 225_splitncnn_1 226 0=32 1=1 5=1 6=2048
11 | HardSwish Div_67 1 1 226 234 0=1.666667e-01
12 | Split splitncnn_1 1 2 234 234_splitncnn_0 234_splitncnn_1
13 | Convolution Conv_68 1 1 234_splitncnn_1 235 0=32 1=1 5=1 6=1024
14 | HardSwish Div_76 1 1 235 243 0=1.666667e-01
15 | Convolution Conv_77 1 1 243 244 0=32 1=3 4=1 5=1 6=9216
16 | HardSwish Div_85 1 1 244 252 0=1.666667e-01
17 | BinaryOp Add_86 2 1 234_splitncnn_0 252 253
18 | Convolution Conv_87 1 1 253 254 0=32 1=1 6=1024
19 | Convolution Conv_88 1 1 225_splitncnn_0 255 0=32 1=1 6=2048
20 | Concat Concat_89 2 1 254 255 256
21 | BatchNorm BatchNormalization_90 1 1 256 257 0=64
22 | ReLU LeakyRelu_91 1 1 257 258 0=1.000000e-01
23 | Convolution Conv_92 1 1 258 259 0=64 1=1 5=1 6=4096
24 | HardSwish Div_100 1 1 259 267 0=1.666667e-01
25 | Convolution Conv_101 1 1 267 268 0=128 1=3 3=2 4=1 5=1 6=73728
26 | HardSwish Div_109 1 1 268 276 0=1.666667e-01
27 | Split splitncnn_2 1 2 276 276_splitncnn_0 276_splitncnn_1
28 | Convolution Conv_110 1 1 276_splitncnn_1 277 0=64 1=1 5=1 6=8192
29 | HardSwish Div_118 1 1 277 285 0=1.666667e-01
30 | Split splitncnn_3 1 2 285 285_splitncnn_0 285_splitncnn_1
31 | Convolution Conv_119 1 1 285_splitncnn_1 286 0=64 1=1 5=1 6=4096
32 | HardSwish Div_127 1 1 286 294 0=1.666667e-01
33 | Convolution Conv_128 1 1 294 295 0=64 1=3 4=1 5=1 6=36864
34 | HardSwish Div_136 1 1 295 303 0=1.666667e-01
35 | BinaryOp Add_137 2 1 285_splitncnn_0 303 304
36 | Split splitncnn_4 1 2 304 304_splitncnn_0 304_splitncnn_1
37 | Convolution Conv_138 1 1 304_splitncnn_1 305 0=64 1=1 5=1 6=4096
38 | HardSwish Div_146 1 1 305 313 0=1.666667e-01
39 | Convolution Conv_147 1 1 313 314 0=64 1=3 4=1 5=1 6=36864
40 | HardSwish Div_155 1 1 314 322 0=1.666667e-01
41 | BinaryOp Add_156 2 1 304_splitncnn_0 322 323
42 | Split splitncnn_5 1 2 323 323_splitncnn_0 323_splitncnn_1
43 | Convolution Conv_157 1 1 323_splitncnn_1 324 0=64 1=1 5=1 6=4096
44 | HardSwish Div_165 1 1 324 332 0=1.666667e-01
45 | Convolution Conv_166 1 1 332 333 0=64 1=3 4=1 5=1 6=36864
46 | HardSwish Div_174 1 1 333 341 0=1.666667e-01
47 | BinaryOp Add_175 2 1 323_splitncnn_0 341 342
48 | Convolution Conv_176 1 1 342 343 0=64 1=1 6=4096
49 | Convolution Conv_177 1 1 276_splitncnn_0 344 0=64 1=1 6=8192
50 | Concat Concat_178 2 1 343 344 345
51 | BatchNorm BatchNormalization_179 1 1 345 346 0=128
52 | ReLU LeakyRelu_180 1 1 346 347 0=1.000000e-01
53 | Convolution Conv_181 1 1 347 348 0=128 1=1 5=1 6=16384
54 | HardSwish Div_189 1 1 348 356 0=1.666667e-01
55 | Split splitncnn_6 1 2 356 356_splitncnn_0 356_splitncnn_1
56 | Convolution Conv_190 1 1 356_splitncnn_1 357 0=256 1=3 3=2 4=1 5=1 6=294912
57 | HardSwish Div_198 1 1 357 365 0=1.666667e-01
58 | Split splitncnn_7 1 2 365 365_splitncnn_0 365_splitncnn_1
59 | Convolution Conv_199 1 1 365_splitncnn_1 366 0=128 1=1 5=1 6=32768
60 | HardSwish Div_207 1 1 366 374 0=1.666667e-01
61 | Split splitncnn_8 1 2 374 374_splitncnn_0 374_splitncnn_1
62 | Convolution Conv_208 1 1 374_splitncnn_1 375 0=128 1=1 5=1 6=16384
63 | HardSwish Div_216 1 1 375 383 0=1.666667e-01
64 | Convolution Conv_217 1 1 383 384 0=128 1=3 4=1 5=1 6=147456
65 | HardSwish Div_225 1 1 384 392 0=1.666667e-01
66 | BinaryOp Add_226 2 1 374_splitncnn_0 392 393
67 | Split splitncnn_9 1 2 393 393_splitncnn_0 393_splitncnn_1
68 | Convolution Conv_227 1 1 393_splitncnn_1 394 0=128 1=1 5=1 6=16384
69 | HardSwish Div_235 1 1 394 402 0=1.666667e-01
70 | Convolution Conv_236 1 1 402 403 0=128 1=3 4=1 5=1 6=147456
71 | HardSwish Div_244 1 1 403 411 0=1.666667e-01
72 | BinaryOp Add_245 2 1 393_splitncnn_0 411 412
73 | Split splitncnn_10 1 2 412 412_splitncnn_0 412_splitncnn_1
74 | Convolution Conv_246 1 1 412_splitncnn_1 413 0=128 1=1 5=1 6=16384
75 | HardSwish Div_254 1 1 413 421 0=1.666667e-01
76 | Convolution Conv_255 1 1 421 422 0=128 1=3 4=1 5=1 6=147456
77 | HardSwish Div_263 1 1 422 430 0=1.666667e-01
78 | BinaryOp Add_264 2 1 412_splitncnn_0 430 431
79 | Convolution Conv_265 1 1 431 432 0=128 1=1 6=16384
80 | Convolution Conv_266 1 1 365_splitncnn_0 433 0=128 1=1 6=32768
81 | Concat Concat_267 2 1 432 433 434
82 | BatchNorm BatchNormalization_268 1 1 434 435 0=256
83 | ReLU LeakyRelu_269 1 1 435 436 0=1.000000e-01
84 | Convolution Conv_270 1 1 436 437 0=256 1=1 5=1 6=65536
85 | HardSwish Div_278 1 1 437 445 0=1.666667e-01
86 | Split splitncnn_11 1 2 445 445_splitncnn_0 445_splitncnn_1
87 | Convolution Conv_279 1 1 445_splitncnn_1 446 0=512 1=3 3=2 4=1 5=1 6=1179648
88 | HardSwish Div_287 1 1 446 454 0=1.666667e-01
89 | Convolution Conv_288 1 1 454 455 0=256 1=1 5=1 6=131072
90 | HardSwish Div_296 1 1 455 463 0=1.666667e-01
91 | Split splitncnn_12 1 4 463 463_splitncnn_0 463_splitncnn_1 463_splitncnn_2 463_splitncnn_3
92 | Pooling MaxPool_297 1 1 463_splitncnn_3 464 1=5 3=2 5=1
93 | Pooling MaxPool_298 1 1 463_splitncnn_2 465 1=9 3=4 5=1
94 | Pooling MaxPool_299 1 1 463_splitncnn_1 466 1=13 3=6 5=1
95 | Concat Concat_300 4 1 463_splitncnn_0 464 465 466 467
96 | Convolution Conv_301 1 1 467 468 0=512 1=1 5=1 6=524288
97 | HardSwish Div_309 1 1 468 476 0=1.666667e-01
98 | Split splitncnn_13 1 2 476 476_splitncnn_0 476_splitncnn_1
99 | Convolution Conv_310 1 1 476_splitncnn_1 477 0=256 1=1 5=1 6=131072
100 | HardSwish Div_318 1 1 477 485 0=1.666667e-01
101 | Convolution Conv_319 1 1 485 486 0=256 1=1 5=1 6=65536
102 | HardSwish Div_327 1 1 486 494 0=1.666667e-01
103 | Convolution Conv_328 1 1 494 495 0=256 1=3 4=1 5=1 6=589824
104 | HardSwish Div_336 1 1 495 503 0=1.666667e-01
105 | Convolution Conv_337 1 1 503 504 0=256 1=1 6=65536
106 | Convolution Conv_338 1 1 476_splitncnn_0 505 0=256 1=1 6=131072
107 | Concat Concat_339 2 1 504 505 506
108 | BatchNorm BatchNormalization_340 1 1 506 507 0=512
109 | ReLU LeakyRelu_341 1 1 507 508 0=1.000000e-01
110 | Convolution Conv_342 1 1 508 509 0=512 1=1 5=1 6=262144
111 | HardSwish Div_350 1 1 509 517 0=1.666667e-01
112 | Convolution Conv_351 1 1 517 518 0=256 1=1 5=1 6=131072
113 | HardSwish Div_359 1 1 518 526 0=1.666667e-01
114 | Split splitncnn_14 1 2 526 526_splitncnn_0 526_splitncnn_1
115 | Interp Resize_361 1 1 526_splitncnn_1 536 0=1 1=2.000000e+00 2=2.000000e+00
116 | Concat Concat_362 2 1 536 445_splitncnn_0 537
117 | Split splitncnn_15 1 2 537 537_splitncnn_0 537_splitncnn_1
118 | Convolution Conv_363 1 1 537_splitncnn_1 538 0=128 1=1 5=1 6=65536
119 | HardSwish Div_371 1 1 538 546 0=1.666667e-01
120 | Convolution Conv_372 1 1 546 547 0=128 1=1 5=1 6=16384
121 | HardSwish Div_380 1 1 547 555 0=1.666667e-01
122 | Convolution Conv_381 1 1 555 556 0=128 1=3 4=1 5=1 6=147456
123 | HardSwish Div_389 1 1 556 564 0=1.666667e-01
124 | Convolution Conv_390 1 1 564 565 0=128 1=1 6=16384
125 | Convolution Conv_391 1 1 537_splitncnn_0 566 0=128 1=1 6=65536
126 | Concat Concat_392 2 1 565 566 567
127 | BatchNorm BatchNormalization_393 1 1 567 568 0=256
128 | ReLU LeakyRelu_394 1 1 568 569 0=1.000000e-01
129 | Convolution Conv_395 1 1 569 570 0=256 1=1 5=1 6=65536
130 | HardSwish Div_403 1 1 570 578 0=1.666667e-01
131 | Convolution Conv_404 1 1 578 579 0=128 1=1 5=1 6=32768
132 | HardSwish Div_412 1 1 579 587 0=1.666667e-01
133 | Split splitncnn_16 1 2 587 587_splitncnn_0 587_splitncnn_1
134 | Interp Resize_414 1 1 587_splitncnn_1 597 0=1 1=2.000000e+00 2=2.000000e+00
135 | Concat Concat_415 2 1 597 356_splitncnn_0 598
136 | Split splitncnn_17 1 2 598 598_splitncnn_0 598_splitncnn_1
137 | Convolution Conv_416 1 1 598_splitncnn_1 599 0=64 1=1 5=1 6=16384
138 | HardSwish Div_424 1 1 599 607 0=1.666667e-01
139 | Convolution Conv_425 1 1 607 608 0=64 1=1 5=1 6=4096
140 | HardSwish Div_433 1 1 608 616 0=1.666667e-01
141 | Convolution Conv_434 1 1 616 617 0=64 1=3 4=1 5=1 6=36864
142 | HardSwish Div_442 1 1 617 625 0=1.666667e-01
143 | Convolution Conv_443 1 1 625 626 0=64 1=1 6=4096
144 | Convolution Conv_444 1 1 598_splitncnn_0 627 0=64 1=1 6=16384
145 | Concat Concat_445 2 1 626 627 628
146 | BatchNorm BatchNormalization_446 1 1 628 629 0=128
147 | ReLU LeakyRelu_447 1 1 629 630 0=1.000000e-01
148 | Convolution Conv_448 1 1 630 631 0=128 1=1 5=1 6=16384
149 | HardSwish Div_456 1 1 631 639 0=1.666667e-01
150 | Split splitncnn_18 1 2 639 639_splitncnn_0 639_splitncnn_1
151 | Convolution Conv_457 1 1 639_splitncnn_1 640 0=128 1=3 3=2 4=1 5=1 6=147456
152 | HardSwish Div_465 1 1 640 648 0=1.666667e-01
153 | Concat Concat_466 2 1 648 587_splitncnn_0 649
154 | Split splitncnn_19 1 2 649 649_splitncnn_0 649_splitncnn_1
155 | Convolution Conv_467 1 1 649_splitncnn_1 650 0=128 1=1 5=1 6=32768
156 | HardSwish Div_475 1 1 650 658 0=1.666667e-01
157 | Convolution Conv_476 1 1 658 659 0=128 1=1 5=1 6=16384
158 | HardSwish Div_484 1 1 659 667 0=1.666667e-01
159 | Convolution Conv_485 1 1 667 668 0=128 1=3 4=1 5=1 6=147456
160 | HardSwish Div_493 1 1 668 676 0=1.666667e-01
161 | Convolution Conv_494 1 1 676 677 0=128 1=1 6=16384
162 | Convolution Conv_495 1 1 649_splitncnn_0 678 0=128 1=1 6=32768
163 | Concat Concat_496 2 1 677 678 679
164 | BatchNorm BatchNormalization_497 1 1 679 680 0=256
165 | ReLU LeakyRelu_498 1 1 680 681 0=1.000000e-01
166 | Convolution Conv_499 1 1 681 682 0=256 1=1 5=1 6=65536
167 | HardSwish Div_507 1 1 682 690 0=1.666667e-01
168 | Split splitncnn_20 1 2 690 690_splitncnn_0 690_splitncnn_1
169 | Convolution Conv_508 1 1 690_splitncnn_1 691 0=256 1=3 3=2 4=1 5=1 6=589824
170 | HardSwish Div_516 1 1 691 699 0=1.666667e-01
171 | Concat Concat_517 2 1 699 526_splitncnn_0 700
172 | Split splitncnn_21 1 2 700 700_splitncnn_0 700_splitncnn_1
173 | Convolution Conv_518 1 1 700_splitncnn_1 701 0=256 1=1 5=1 6=131072
174 | HardSwish Div_526 1 1 701 709 0=1.666667e-01
175 | Convolution Conv_527 1 1 709 710 0=256 1=1 5=1 6=65536
176 | HardSwish Div_535 1 1 710 718 0=1.666667e-01
177 | Convolution Conv_536 1 1 718 719 0=256 1=3 4=1 5=1 6=589824
178 | HardSwish Div_544 1 1 719 727 0=1.666667e-01
179 | Convolution Conv_545 1 1 727 728 0=256 1=1 6=65536
180 | Convolution Conv_546 1 1 700_splitncnn_0 729 0=256 1=1 6=131072
181 | Concat Concat_547 2 1 728 729 730
182 | BatchNorm BatchNormalization_548 1 1 730 731 0=512
183 | ReLU LeakyRelu_549 1 1 731 732 0=1.000000e-01
184 | Convolution Conv_550 1 1 732 733 0=512 1=1 5=1 6=262144
185 | HardSwish Div_558 1 1 733 741 0=1.666667e-01
186 | Convolution Conv_559 1 1 639_splitncnn_0 742 0=255 1=1 5=1 6=32640
187 | Reshape Reshape_573 1 1 742 760 0=-1 1=85 2=3
188 | Permute Transpose_574 1 1 760 output 0=1
189 | Convolution Conv_575 1 1 690_splitncnn_0 762 0=255 1=1 5=1 6=65280
190 | Reshape Reshape_589 1 1 762 780 0=-1 1=85 2=3
191 | Permute Transpose_590 1 1 780 781 0=1
192 | Convolution Conv_591 1 1 741 782 0=255 1=1 5=1 6=130560
193 | Reshape Reshape_605 1 1 782 800 0=-1 1=85 2=3
194 | Permute Transpose_606 1 1 800 801 0=1
--------------------------------------------------------------------------------
/app/src/main/assets/yolox-nano.bin:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/JiweiMaster/PP-PicoDet-Android-Demo/c2d3f41c6cbc03ad46118bc091e46f1b5097edce/app/src/main/assets/yolox-nano.bin
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/common/AppCompatPreferenceActivity.java:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (C) 2014 The Android Open Source Project
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * http://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | package com.baidu.common;
18 |
19 | import android.content.res.Configuration;
20 | import android.os.Bundle;
21 | import android.preference.PreferenceActivity;
22 | import android.view.MenuInflater;
23 | import android.view.View;
24 | import android.view.ViewGroup;
25 |
26 | import androidx.annotation.LayoutRes;
27 | import androidx.annotation.Nullable;
28 | import androidx.appcompat.app.ActionBar;
29 | import androidx.appcompat.app.AppCompatDelegate;
30 | import androidx.appcompat.widget.Toolbar;
31 |
32 | /**
33 | * A {@link PreferenceActivity} which implements and proxies the necessary calls
34 | * to be used with AppCompat.
35 | *
36 | * This technique can be used with an {@link android.app.Activity} class, not just
37 | * {@link PreferenceActivity}.
38 | */
39 | public abstract class AppCompatPreferenceActivity extends PreferenceActivity {
40 | private AppCompatDelegate mDelegate;
41 |
42 | @Override
43 | protected void onCreate(Bundle savedInstanceState) {
44 | getDelegate().installViewFactory();
45 | getDelegate().onCreate(savedInstanceState);
46 | super.onCreate(savedInstanceState);
47 | }
48 |
49 | @Override
50 | protected void onPostCreate(Bundle savedInstanceState) {
51 | super.onPostCreate(savedInstanceState);
52 | getDelegate().onPostCreate(savedInstanceState);
53 | }
54 |
55 | public ActionBar getSupportActionBar() {
56 | return getDelegate().getSupportActionBar();
57 | }
58 |
59 | public void setSupportActionBar(@Nullable Toolbar toolbar) {
60 | getDelegate().setSupportActionBar(toolbar);
61 | }
62 |
63 | @Override
64 | public MenuInflater getMenuInflater() {
65 | return getDelegate().getMenuInflater();
66 | }
67 |
68 | @Override
69 | public void setContentView(@LayoutRes int layoutResID) {
70 | getDelegate().setContentView(layoutResID);
71 | }
72 |
73 | @Override
74 | public void setContentView(View view) {
75 | getDelegate().setContentView(view);
76 | }
77 |
78 | @Override
79 | public void setContentView(View view, ViewGroup.LayoutParams params) {
80 | getDelegate().setContentView(view, params);
81 | }
82 |
83 | @Override
84 | public void addContentView(View view, ViewGroup.LayoutParams params) {
85 | getDelegate().addContentView(view, params);
86 | }
87 |
88 | @Override
89 | protected void onPostResume() {
90 | super.onPostResume();
91 | getDelegate().onPostResume();
92 | }
93 |
94 | @Override
95 | protected void onTitleChanged(CharSequence title, int color) {
96 | super.onTitleChanged(title, color);
97 | getDelegate().setTitle(title);
98 | }
99 |
100 | @Override
101 | public void onConfigurationChanged(Configuration newConfig) {
102 | super.onConfigurationChanged(newConfig);
103 | getDelegate().onConfigurationChanged(newConfig);
104 | }
105 |
106 | @Override
107 | protected void onStop() {
108 | super.onStop();
109 | getDelegate().onStop();
110 | }
111 |
112 | @Override
113 | protected void onDestroy() {
114 | super.onDestroy();
115 | getDelegate().onDestroy();
116 | }
117 |
118 | public void invalidateOptionsMenu() {
119 | getDelegate().invalidateOptionsMenu();
120 | }
121 |
122 | private AppCompatDelegate getDelegate() {
123 | if (mDelegate == null) {
124 | mDelegate = AppCompatDelegate.create(this, null);
125 | }
126 | return mDelegate;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/common/CameraSurfaceView.java:
--------------------------------------------------------------------------------
1 | package com.baidu.common;
2 |
3 | import android.content.Context;
4 | import android.graphics.SurfaceTexture;
5 | import android.hardware.Camera;
6 | import android.hardware.Camera.CameraInfo;
7 | import android.hardware.Camera.Size;
8 | import android.opengl.GLES11Ext;
9 | import android.opengl.GLES20;
10 | import android.opengl.GLSurfaceView;
11 | import android.opengl.GLSurfaceView.Renderer;
12 | import android.opengl.Matrix;
13 | import android.util.AttributeSet;
14 | import android.util.Log;
15 |
16 | import java.io.IOException;
17 | import java.nio.ByteBuffer;
18 | import java.nio.ByteOrder;
19 | import java.nio.FloatBuffer;
20 | import java.util.List;
21 |
22 | import javax.microedition.khronos.egl.EGLConfig;
23 | import javax.microedition.khronos.opengles.GL10;
24 |
25 | public class CameraSurfaceView extends GLSurfaceView implements Renderer,
26 | SurfaceTexture.OnFrameAvailableListener {
27 | private static final String TAG = CameraSurfaceView.class.getSimpleName();
28 |
29 | public static final int EXPECTED_PREVIEW_WIDTH = 1280;
30 | public static final int EXPECTED_PREVIEW_HEIGHT = 720;
31 |
32 |
33 | protected int numberOfCameras;
34 | protected int selectedCameraId;
35 | protected boolean disableCamera = false;
36 | protected Camera camera;
37 |
38 | protected Context context;
39 | protected SurfaceTexture surfaceTexture;
40 | protected int surfaceWidth = 0;
41 | protected int surfaceHeight = 0;
42 | protected int textureWidth = 0;
43 | protected int textureHeight = 0;
44 |
45 | // In order to manipulate the camera preview data and render the modified one
46 | // to the screen, three textures are created and the data flow is shown as following:
47 | // previewdata->camTextureId->fboTexureId->drawTexureId->framebuffer
48 | protected int[] fbo = {0};
49 | protected int[] camTextureId = {0};
50 | protected int[] fboTexureId = {0};
51 | protected int[] drawTexureId = {0};
52 |
53 | private final String vss = ""
54 | + "attribute vec2 vPosition;\n"
55 | + "attribute vec2 vTexCoord;\n" + "varying vec2 texCoord;\n"
56 | + "void main() {\n" + " texCoord = vTexCoord;\n"
57 | + " gl_Position = vec4 (vPosition.x, vPosition.y, 0.0, 1.0);\n"
58 | + "}";
59 |
60 | private final String fssCam2FBO = ""
61 | + "#extension GL_OES_EGL_image_external : require\n"
62 | + "precision mediump float;\n"
63 | + "uniform samplerExternalOES sTexture;\n"
64 | + "varying vec2 texCoord;\n"
65 | + "void main() {\n"
66 | + " gl_FragColor = texture2D(sTexture,texCoord);\n" + "}";
67 |
68 | private final String fssTex2Screen = ""
69 | + "precision mediump float;\n"
70 | + "uniform sampler2D sTexture;\n"
71 | + "varying vec2 texCoord;\n"
72 | + "void main() {\n"
73 | + " gl_FragColor = texture2D(sTexture,texCoord);\n" + "}";
74 |
75 | private final float vertexCoords[] = {
76 | -1, -1,
77 | -1, 1,
78 | 1, -1,
79 | 1, 1};
80 | private float textureCoords[] = {
81 | 0, 1,
82 | 0, 0,
83 | 1, 1,
84 | 1, 0};
85 |
86 | private FloatBuffer vertexCoordsBuffer;
87 | private FloatBuffer textureCoordsBuffer;
88 |
89 | private int progCam2FBO = -1;
90 | private int progTex2Screen = -1;
91 | private int vcCam2FBO;
92 | private int tcCam2FBO;
93 | private int vcTex2Screen;
94 | private int tcTex2Screen;
95 |
96 | public interface OnTextureChangedListener {
97 | public boolean onTextureChanged(int inTextureId, int outTextureId, int textureWidth, int textureHeight);
98 | }
99 |
100 | private OnTextureChangedListener onTextureChangedListener = null;
101 |
102 | public void setOnTextureChangedListener(OnTextureChangedListener listener) {
103 | onTextureChangedListener = listener;
104 | }
105 |
106 | public CameraSurfaceView(Context ctx, AttributeSet attrs) {
107 | super(ctx, attrs);
108 | context = ctx;
109 | setEGLContextClientVersion(2);
110 | setRenderer(this);
111 | setRenderMode(RENDERMODE_WHEN_DIRTY);
112 |
113 | // Find the total number of available cameras and the ID of the default camera
114 | numberOfCameras = Camera.getNumberOfCameras();
115 | CameraInfo cameraInfo = new CameraInfo();
116 | for (int i = 0; i < numberOfCameras; i++) {
117 | Camera.getCameraInfo(i, cameraInfo);
118 | if (cameraInfo.facing == CameraInfo.CAMERA_FACING_BACK) {
119 | selectedCameraId = i;
120 | }
121 | }
122 | }
123 |
124 | @Override
125 | public void onSurfaceCreated(GL10 gl, EGLConfig config) {
126 | // Create OES texture for storing camera preview data(YUV format)
127 | GLES20.glGenTextures(1, camTextureId, 0);
128 | GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
129 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
130 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
131 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
132 | GLES20.glTexParameteri(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
133 | surfaceTexture = new SurfaceTexture(camTextureId[0]);
134 | surfaceTexture.setOnFrameAvailableListener(this);
135 |
136 | // Prepare vertex and texture coordinates
137 | int bytes = vertexCoords.length * Float.SIZE / Byte.SIZE;
138 | vertexCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
139 | textureCoordsBuffer = ByteBuffer.allocateDirect(bytes).order(ByteOrder.nativeOrder()).asFloatBuffer();
140 | vertexCoordsBuffer.put(vertexCoords).position(0);
141 | textureCoordsBuffer.put(textureCoords).position(0);
142 |
143 | // Create vertex and fragment shaders
144 | // camTextureId->fboTexureId
145 | progCam2FBO = Utils.createShaderProgram(vss, fssCam2FBO);
146 | vcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vPosition");
147 | tcCam2FBO = GLES20.glGetAttribLocation(progCam2FBO, "vTexCoord");
148 | GLES20.glEnableVertexAttribArray(vcCam2FBO);
149 | GLES20.glEnableVertexAttribArray(tcCam2FBO);
150 | // fboTexureId/drawTexureId -> screen
151 | progTex2Screen = Utils.createShaderProgram(vss, fssTex2Screen);
152 | vcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vPosition");
153 | tcTex2Screen = GLES20.glGetAttribLocation(progTex2Screen, "vTexCoord");
154 | GLES20.glEnableVertexAttribArray(vcTex2Screen);
155 | GLES20.glEnableVertexAttribArray(tcTex2Screen);
156 | }
157 |
158 | @Override
159 | public void onSurfaceChanged(GL10 gl, int width, int height) {
160 | surfaceWidth = width;
161 | surfaceHeight = height;
162 | openCamera();
163 | }
164 |
165 | @Override
166 | public void onDrawFrame(GL10 gl) {
167 | if (surfaceTexture == null) return;
168 |
169 | GLES20.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
170 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT);
171 | surfaceTexture.updateTexImage();
172 | float matrix[] = new float[16];
173 | surfaceTexture.getTransformMatrix(matrix);
174 |
175 | // camTextureId->fboTexureId
176 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
177 | GLES20.glViewport(0, 0, textureWidth, textureHeight);
178 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
179 | GLES20.glUseProgram(progCam2FBO);
180 | GLES20.glVertexAttribPointer(vcCam2FBO, 2, GLES20.GL_FLOAT, false, 4 * 2, vertexCoordsBuffer);
181 | textureCoordsBuffer.clear();
182 | textureCoordsBuffer.put(transformTextureCoordinates(textureCoords, matrix));
183 | textureCoordsBuffer.position(0);
184 | GLES20.glVertexAttribPointer(tcCam2FBO, 2, GLES20.GL_FLOAT, false, 4 * 2, textureCoordsBuffer);
185 | GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
186 | GLES20.glBindTexture(GLES11Ext.GL_TEXTURE_EXTERNAL_OES, camTextureId[0]);
187 | GLES20.glUniform1i(GLES20.glGetUniformLocation(progCam2FBO, "sTexture"), 0);
188 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
189 | GLES20.glFlush();
190 |
191 | // Check if the draw texture is set
192 | int targetTexureId = fboTexureId[0];
193 | if (onTextureChangedListener != null) {
194 | boolean modified = onTextureChangedListener.onTextureChanged(fboTexureId[0], drawTexureId[0],
195 | textureWidth, textureHeight);
196 | if (modified) {
197 | targetTexureId = drawTexureId[0];
198 | }
199 | }
200 |
201 | // fboTexureId/drawTexureId->Screen
202 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
203 | GLES20.glViewport(0, 0, surfaceWidth, surfaceHeight);
204 | GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
205 | GLES20.glUseProgram(progTex2Screen);
206 | GLES20.glVertexAttribPointer(vcTex2Screen, 2, GLES20.GL_FLOAT, false, 4 * 2, vertexCoordsBuffer);
207 | textureCoordsBuffer.clear();
208 | textureCoordsBuffer.put(textureCoords);
209 | textureCoordsBuffer.position(0);
210 | GLES20.glVertexAttribPointer(tcTex2Screen, 2, GLES20.GL_FLOAT, false, 4 * 2, textureCoordsBuffer);
211 | GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
212 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, targetTexureId);
213 | GLES20.glUniform1i(GLES20.glGetUniformLocation(progTex2Screen, "sTexture"), 0);
214 | GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4);
215 | GLES20.glFlush();
216 | }
217 |
218 | private float[] transformTextureCoordinates(float[] coords, float[] matrix) {
219 | float[] result = new float[coords.length];
220 | float[] vt = new float[4];
221 | for (int i = 0; i < coords.length; i += 2) {
222 | float[] v = {coords[i], coords[i + 1], 0, 1};
223 | Matrix.multiplyMV(vt, 0, matrix, 0, v, 0);
224 | result[i] = vt[0];
225 | result[i + 1] = vt[1];
226 | }
227 | return result;
228 | }
229 |
230 | @Override
231 | public void onResume() {
232 | super.onResume();
233 | }
234 |
235 | @Override
236 | public void onPause() {
237 | super.onPause();
238 | releaseCamera();
239 | }
240 |
241 | @Override
242 | public void onFrameAvailable(SurfaceTexture surfaceTexture) {
243 | requestRender();
244 | }
245 |
246 | public void disableCamera() {
247 | disableCamera = true;
248 | }
249 |
250 | public void switchCamera() {
251 | releaseCamera();
252 | selectedCameraId = (selectedCameraId + 1) % numberOfCameras;
253 | openCamera();
254 | }
255 |
256 | public void openCamera() {
257 | if (disableCamera) return;
258 | camera = Camera.open(selectedCameraId);
259 | List supportedPreviewSizes = camera.getParameters().getSupportedPreviewSizes();
260 | Size previewSize = Utils.getOptimalPreviewSize(supportedPreviewSizes, EXPECTED_PREVIEW_WIDTH,
261 | EXPECTED_PREVIEW_HEIGHT);
262 | Camera.Parameters parameters = camera.getParameters();
263 | parameters.setPreviewSize(previewSize.width, previewSize.height);
264 | if (parameters.getSupportedFocusModes().contains(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO)) {
265 | parameters.setFocusMode(Camera.Parameters.FOCUS_MODE_CONTINUOUS_VIDEO);
266 | }
267 | camera.setParameters(parameters);
268 | int degree = Utils.getCameraDisplayOrientation(context, selectedCameraId);
269 | camera.setDisplayOrientation(degree);
270 | boolean rotate = degree == 90 || degree == 270;
271 | textureWidth = rotate ? previewSize.height : previewSize.width;
272 | textureHeight = rotate ? previewSize.width : previewSize.height;
273 | // Destroy FBO and draw textures
274 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0);
275 | GLES20.glDeleteFramebuffers(1, fbo, 0);
276 | GLES20.glDeleteTextures(1, drawTexureId, 0);
277 | GLES20.glDeleteTextures(1, fboTexureId, 0);
278 | // Normal texture for storing modified camera preview data(RGBA format)
279 | GLES20.glGenTextures(1, drawTexureId, 0);
280 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, drawTexureId[0]);
281 | GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, textureWidth, textureHeight, 0,
282 | GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
283 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
284 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
285 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
286 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
287 | // FBO texture for storing camera preview data(RGBA format)
288 | GLES20.glGenTextures(1, fboTexureId, 0);
289 | GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, fboTexureId[0]);
290 | GLES20.glTexImage2D(GLES20.GL_TEXTURE_2D, 0, GLES20.GL_RGBA, textureWidth, textureHeight, 0,
291 | GLES20.GL_RGBA, GLES20.GL_UNSIGNED_BYTE, null);
292 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE);
293 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE);
294 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST);
295 | GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST);
296 | // Generate FBO and bind to FBO texture
297 | GLES20.glGenFramebuffers(1, fbo, 0);
298 | GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo[0]);
299 | GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_TEXTURE_2D,
300 | fboTexureId[0], 0);
301 | try {
302 | camera.setPreviewTexture(surfaceTexture);
303 | } catch (IOException exception) {
304 | Log.e(TAG, "IOException caused by setPreviewDisplay()", exception);
305 | }
306 | camera.startPreview();
307 | }
308 |
309 | public void releaseCamera() {
310 | if (camera != null) {
311 | camera.setPreviewCallback(null);
312 | camera.stopPreview();
313 | camera.release();
314 | camera = null;
315 | }
316 | }
317 | }
318 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/common/Utils.java:
--------------------------------------------------------------------------------
1 | package com.baidu.common;
2 |
3 | import android.content.Context;
4 | import android.content.res.Resources;
5 | import android.hardware.Camera;
6 | import android.opengl.GLES20;
7 | import android.os.Environment;
8 | import android.util.Log;
9 | import android.view.Surface;
10 | import android.view.WindowManager;
11 |
12 | import java.io.BufferedInputStream;
13 | import java.io.BufferedOutputStream;
14 | import java.io.File;
15 | import java.io.FileNotFoundException;
16 | import java.io.FileOutputStream;
17 | import java.io.IOException;
18 | import java.io.InputStream;
19 | import java.io.OutputStream;
20 | import java.util.List;
21 |
22 | public class Utils {
23 | private static final String TAG = Utils.class.getSimpleName();
24 |
25 | public static void RecursiveCreateDirectories(String fileDir) {
26 | String[] fileDirs = fileDir.split("\\/");
27 | String topPath = "";
28 | for (int i = 0; i < fileDirs.length; i++) {
29 | topPath += "/" + fileDirs[i];
30 | File file = new File(topPath);
31 | if (file.exists()) {
32 | continue;
33 | } else {
34 | file.mkdir();
35 | }
36 | }
37 | }
38 |
39 | public static void copyFileFromAssets(Context appCtx, String srcPath, String dstPath) {
40 | if (srcPath.isEmpty() || dstPath.isEmpty()) {
41 | return;
42 | }
43 | String dstDir = dstPath.substring(0, dstPath.lastIndexOf('/'));
44 | if (dstDir.length() > 0) {
45 | RecursiveCreateDirectories(dstDir);
46 | }
47 | InputStream is = null;
48 | OutputStream os = null;
49 | try {
50 | is = new BufferedInputStream(appCtx.getAssets().open(srcPath));
51 | os = new BufferedOutputStream(new FileOutputStream(new File(dstPath)));
52 | byte[] buffer = new byte[1024];
53 | int length = 0;
54 | while ((length = is.read(buffer)) != -1) {
55 | os.write(buffer, 0, length);
56 | }
57 | } catch (FileNotFoundException e) {
58 | e.printStackTrace();
59 | } catch (IOException e) {
60 | e.printStackTrace();
61 | } finally {
62 | try {
63 | os.close();
64 | is.close();
65 | } catch (IOException e) {
66 | e.printStackTrace();
67 | }
68 | }
69 | }
70 |
71 | public static void copyDirectoryFromAssets(Context appCtx, String srcDir, String dstDir) {
72 | if (srcDir.isEmpty() || dstDir.isEmpty()) {
73 | return;
74 | }
75 | try {
76 | if (!new File(dstDir).exists()) {
77 | new File(dstDir).mkdirs();
78 | }
79 | for (String fileName : appCtx.getAssets().list(srcDir)) {
80 | String srcSubPath = srcDir + File.separator + fileName;
81 | String dstSubPath = dstDir + File.separator + fileName;
82 | if (new File(srcSubPath).isDirectory()) {
83 | copyDirectoryFromAssets(appCtx, srcSubPath, dstSubPath);
84 | } else {
85 | copyFileFromAssets(appCtx, srcSubPath, dstSubPath);
86 | }
87 | }
88 | } catch (Exception e) {
89 | e.printStackTrace();
90 | }
91 | }
92 |
93 | public static float[] parseFloatsFromString(String string, String delimiter) {
94 | String[] pieces = string.trim().toLowerCase().split(delimiter);
95 | float[] floats = new float[pieces.length];
96 | for (int i = 0; i < pieces.length; i++) {
97 | floats[i] = Float.parseFloat(pieces[i].trim());
98 | }
99 | return floats;
100 | }
101 |
102 | public static long[] parseLongsFromString(String string, String delimiter) {
103 | String[] pieces = string.trim().toLowerCase().split(delimiter);
104 | long[] longs = new long[pieces.length];
105 | for (int i = 0; i < pieces.length; i++) {
106 | longs[i] = Long.parseLong(pieces[i].trim());
107 | }
108 | return longs;
109 | }
110 |
111 | public static String getSDCardDirectory() {
112 | return Environment.getExternalStorageDirectory().getAbsolutePath();
113 | }
114 |
115 | public static String getDCIMDirectory() {
116 | return Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getAbsolutePath();
117 | }
118 |
119 | public static Camera.Size getOptimalPreviewSize(List sizes, int w, int h) {
120 | final double ASPECT_TOLERANCE = 0.1;
121 | double targetRatio = (double) w / h;
122 | if (sizes == null) return null;
123 |
124 | Camera.Size optimalSize = null;
125 | double minDiff = Double.MAX_VALUE;
126 |
127 | int targetHeight = h;
128 |
129 | // Try to find an size match aspect ratio and size
130 | for (Camera.Size size : sizes) {
131 | double ratio = (double) size.width / size.height;
132 | if (Math.abs(ratio - targetRatio) > ASPECT_TOLERANCE) continue;
133 | if (Math.abs(size.height - targetHeight) < minDiff) {
134 | optimalSize = size;
135 | minDiff = Math.abs(size.height - targetHeight);
136 | }
137 | }
138 |
139 | // Cannot find the one match the aspect ratio, ignore the requirement
140 | if (optimalSize == null) {
141 | minDiff = Double.MAX_VALUE;
142 | for (Camera.Size size : sizes) {
143 | if (Math.abs(size.height - targetHeight) < minDiff) {
144 | optimalSize = size;
145 | minDiff = Math.abs(size.height - targetHeight);
146 | }
147 | }
148 | }
149 | return optimalSize;
150 | }
151 |
152 | public static int getScreenWidth() {
153 | return Resources.getSystem().getDisplayMetrics().widthPixels;
154 | }
155 |
156 | public static int getScreenHeight() {
157 | return Resources.getSystem().getDisplayMetrics().heightPixels;
158 | }
159 |
160 | public static int getCameraDisplayOrientation(Context context, int cameraId) {
161 | Camera.CameraInfo info = new Camera.CameraInfo();
162 | Camera.getCameraInfo(cameraId, info);
163 | WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
164 | int rotation = wm.getDefaultDisplay().getRotation();
165 | int degrees = 0;
166 | switch (rotation) {
167 | case Surface.ROTATION_0:
168 | degrees = 0;
169 | break;
170 | case Surface.ROTATION_90:
171 | degrees = 90;
172 | break;
173 | case Surface.ROTATION_180:
174 | degrees = 180;
175 | break;
176 | case Surface.ROTATION_270:
177 | degrees = 270;
178 | break;
179 | }
180 | int result;
181 | if (info.facing == Camera.CameraInfo.CAMERA_FACING_FRONT) {
182 | result = (info.orientation + degrees) % 360;
183 | result = (360 - result) % 360; // compensate the mirror
184 | } else {
185 | // back-facing
186 | result = (info.orientation - degrees + 360) % 360;
187 | }
188 | return result;
189 | }
190 |
191 | public static int createShaderProgram(String vss, String fss) {
192 | int vshader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER);
193 | GLES20.glShaderSource(vshader, vss);
194 | GLES20.glCompileShader(vshader);
195 | int[] status = new int[1];
196 | GLES20.glGetShaderiv(vshader, GLES20.GL_COMPILE_STATUS, status, 0);
197 | if (status[0] == 0) {
198 | Log.e(TAG, GLES20.glGetShaderInfoLog(vshader));
199 | GLES20.glDeleteShader(vshader);
200 | vshader = 0;
201 | return 0;
202 | }
203 |
204 | int fshader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER);
205 | GLES20.glShaderSource(fshader, fss);
206 | GLES20.glCompileShader(fshader);
207 | GLES20.glGetShaderiv(fshader, GLES20.GL_COMPILE_STATUS, status, 0);
208 | if (status[0] == 0) {
209 | Log.e(TAG, GLES20.glGetShaderInfoLog(fshader));
210 | GLES20.glDeleteShader(vshader);
211 | GLES20.glDeleteShader(fshader);
212 | fshader = 0;
213 | return 0;
214 | }
215 |
216 | int program = GLES20.glCreateProgram();
217 | GLES20.glAttachShader(program, vshader);
218 | GLES20.glAttachShader(program, fshader);
219 | GLES20.glLinkProgram(program);
220 | GLES20.glDeleteShader(vshader);
221 | GLES20.glDeleteShader(fshader);
222 | GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, status, 0);
223 | if (status[0] == 0) {
224 | Log.e(TAG, GLES20.glGetProgramInfoLog(program));
225 | program = 0;
226 | return 0;
227 | }
228 | GLES20.glValidateProgram(program);
229 | GLES20.glGetProgramiv(program, GLES20.GL_VALIDATE_STATUS, status, 0);
230 | if (status[0] == 0) {
231 | Log.e(TAG, GLES20.glGetProgramInfoLog(program));
232 | GLES20.glDeleteProgram(program);
233 | program = 0;
234 | return 0;
235 | }
236 |
237 | return program;
238 | }
239 |
240 | public static boolean isSupportedNPU() {
241 | String hardware = android.os.Build.HARDWARE;
242 | return hardware.equalsIgnoreCase("kirin810") || hardware.equalsIgnoreCase("kirin990");
243 | }
244 | }
245 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/picodetncnn/CameraFragment.java:
--------------------------------------------------------------------------------
1 | package com.baidu.picodetncnn;
2 |
3 | import android.Manifest;
4 | import android.app.AlertDialog;
5 | import android.content.DialogInterface;
6 | import android.content.Intent;
7 | import android.content.SharedPreferences;
8 | import android.content.pm.PackageManager;
9 | import android.graphics.PixelFormat;
10 | import android.os.Bundle;
11 | import android.preference.PreferenceManager;
12 | import android.util.Log;
13 | import android.view.LayoutInflater;
14 | import android.view.SurfaceHolder;
15 | import android.view.SurfaceView;
16 | import android.view.View;
17 | import android.view.ViewGroup;
18 | import android.widget.AdapterView;
19 | import android.widget.Button;
20 | import android.widget.ImageButton;
21 | import android.widget.Spinner;
22 | import android.widget.TextView;
23 | import android.widget.Toast;
24 |
25 | import androidx.annotation.NonNull;
26 | import androidx.core.app.ActivityCompat;
27 | import androidx.core.content.ContextCompat;
28 | import androidx.fragment.app.Fragment;
29 |
30 | import com.baidu.common.CameraSurfaceView;
31 | import com.baidu.common.Utils;
32 |
33 | import java.io.File;
34 | import java.text.SimpleDateFormat;
35 | import java.util.Date;
36 |
37 | public class CameraFragment extends Fragment implements View.OnClickListener, SurfaceHolder.Callback {
38 | private static final String TAG = CameraFragment.class.getSimpleName();
39 |
40 | private NanoDetNcnn nanodetncnn = new NanoDetNcnn();
41 | private int facing = 1;
42 |
43 | // CameraSurfaceView svPreview;
44 | private SurfaceView cameraView;
45 | ImageButton btnSwitch;
46 | ImageButton btnShutter;
47 | ImageButton btnSettings;
48 |
49 | private Spinner spinnerModel;
50 | private Spinner spinnerCPUGPU;
51 | private int current_model = 0;
52 | private int current_cpugpu = 0;
53 |
54 | String savedImagePath = "";
55 | int lastFrameIndex = 0;
56 | long lastFrameTime;
57 |
58 |
59 | @Override
60 | public View onCreateView(LayoutInflater inflater, ViewGroup container,
61 | Bundle savedInstanceState) {
62 | // Inflate the layout for this fragment
63 | return inflater.inflate(R.layout.fragment_camera, container, false);
64 | }
65 |
66 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
67 | super.onViewCreated(view, savedInstanceState);
68 | // Init the camera preview and UI components
69 | initView(view);
70 | // Check and request CAMERA and WRITE_EXTERNAL_STORAGE permissions
71 | if (!checkAllPermissions()) {
72 | requestAllPermissions();
73 | }
74 | }
75 |
76 | @Override
77 | public void onClick(View v) {
78 | switch (v.getId()) {
79 | case R.id.btn_switch:
80 | int new_facing = 1 - facing;
81 | nanodetncnn.closeCamera();
82 | nanodetncnn.openCamera(new_facing);
83 | facing = new_facing;
84 | break;
85 | case R.id.btn_shutter:
86 | SimpleDateFormat date = new SimpleDateFormat("yyyy_MM_dd_HH_mm_ss");
87 | synchronized (this) {
88 | savedImagePath = Utils.getDCIMDirectory() + File.separator + date.format(new Date()).toString() + ".png";
89 | }
90 | Toast.makeText(getActivity(), "Save snapshot to " + savedImagePath, Toast.LENGTH_SHORT).show();
91 | break;
92 | }
93 | }
94 |
95 | @Override
96 | public void onResume() {
97 | super.onResume();
98 | nanodetncnn.openCamera(facing);
99 | }
100 |
101 | @Override
102 | public void onPause() {
103 | super.onPause();
104 | nanodetncnn.closeCamera();
105 | }
106 |
107 | @Override
108 | public void onDestroy() {
109 |
110 | super.onDestroy();
111 | }
112 |
113 | public void initView(@NonNull View view) {
114 | // svPreview = (CameraSurfaceView) view.findViewById(R.id.sv_preview);
115 | cameraView = (SurfaceView) view.findViewById(R.id.sv_preview);
116 | cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);
117 | cameraView.getHolder().addCallback(this);
118 |
119 | btnSwitch = (ImageButton) view.findViewById(R.id.btn_switch);
120 | btnSwitch.setOnClickListener(this);
121 | btnShutter = (ImageButton) view.findViewById(R.id.btn_shutter);
122 | btnShutter.setOnClickListener(this);
123 | btnSettings = (ImageButton) view.findViewById(R.id.btn_settings);
124 | btnSettings.setOnClickListener(this);
125 |
126 | spinnerModel = (Spinner) view.findViewById(R.id.spinnerModel);
127 | spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
128 | @Override
129 | public void onItemSelected(AdapterView> arg0, View arg1, int position, long id)
130 | {
131 | if (position != current_model)
132 | {
133 | current_model = position;
134 | System.out.println("current_model => "+current_model);
135 | reload();
136 | }
137 | }
138 |
139 | @Override
140 | public void onNothingSelected(AdapterView> arg0)
141 | {
142 | }
143 | });
144 |
145 | spinnerCPUGPU = (Spinner) view.findViewById(R.id.spinnerCPUGPU);
146 | spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
147 | @Override
148 | public void onItemSelected(AdapterView> arg0, View arg1, int position, long id)
149 | {
150 | if (position != current_cpugpu)
151 | {
152 | current_cpugpu = position;
153 | reload();
154 | }
155 | }
156 |
157 | @Override
158 | public void onNothingSelected(AdapterView> arg0)
159 | {
160 | }
161 | });
162 |
163 | reload();
164 | }
165 |
166 | private void reload()
167 | {
168 | boolean ret_init = nanodetncnn.loadModel(getActivity().getAssets(), current_model, current_cpugpu);
169 | if (!ret_init)
170 | {
171 | Toast.makeText(getActivity(),"切换模型失败",Toast.LENGTH_LONG).show();
172 | Log.e("camera", "ncnn loadModel failed");
173 | }else{
174 | Toast.makeText(getActivity(),"切换模型成功",Toast.LENGTH_LONG).show();
175 | }
176 | }
177 |
178 | @Override
179 | public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions,
180 | @NonNull int[] grantResults) {
181 | super.onRequestPermissionsResult(requestCode, permissions, grantResults);
182 | if (grantResults[0] != PackageManager.PERMISSION_GRANTED || grantResults[1] != PackageManager.PERMISSION_GRANTED) {
183 | new AlertDialog.Builder(getActivity())
184 | .setTitle("Permission denied")
185 | .setMessage("Click to force quit the app, then open Settings->Apps & notifications->Target " +
186 | "App->Permissions to grant all of the permissions.")
187 | .setCancelable(false)
188 | .setPositiveButton("Exit", new DialogInterface.OnClickListener() {
189 | @Override
190 | public void onClick(DialogInterface dialog, int which) {
191 | getActivity().finish();
192 | }
193 | }).show();
194 | }
195 | }
196 |
197 | private void requestAllPermissions() {
198 | ActivityCompat.requestPermissions(getActivity(), new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE,
199 | Manifest.permission.CAMERA}, 0);
200 | }
201 |
202 | private boolean checkAllPermissions() {
203 | return ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED
204 | && ContextCompat.checkSelfPermission(getActivity(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED;
205 | }
206 |
207 | @Override
208 | public void surfaceCreated(@NonNull SurfaceHolder holder) {
209 | nanodetncnn.setOutputWindow(holder.getSurface());
210 | }
211 |
212 | @Override
213 | public void surfaceChanged(@NonNull SurfaceHolder holder, int format, int width, int height) {
214 |
215 | }
216 |
217 | @Override
218 | public void surfaceDestroyed(@NonNull SurfaceHolder holder) {
219 |
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/picodetncnn/ContentFragment.java:
--------------------------------------------------------------------------------
1 | package com.baidu.picodetncnn;
2 |
3 | import android.os.Bundle;
4 | import android.view.LayoutInflater;
5 | import android.view.View;
6 | import android.view.ViewGroup;
7 |
8 | import androidx.annotation.NonNull;
9 | import androidx.fragment.app.Fragment;
10 | import androidx.navigation.fragment.NavHostFragment;
11 |
12 | public class ContentFragment extends Fragment {
13 |
14 | @Override
15 | public View onCreateView(
16 | LayoutInflater inflater, ViewGroup container,
17 | Bundle savedInstanceState
18 | ) {
19 | // Inflate the layout for this fragment
20 | return inflater.inflate(R.layout.fragment_content, container, false);
21 | }
22 |
23 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
24 | super.onViewCreated(view, savedInstanceState);
25 |
26 | view.findViewById(R.id.camera).setOnClickListener(new View.OnClickListener() {
27 | @Override
28 | public void onClick(View view) {
29 | NavHostFragment.findNavController(ContentFragment.this)
30 | .navigate(R.id.action_ContentFragment_to_CameraFragment);
31 |
32 | }
33 | });
34 |
35 | view.findViewById(R.id.photo).setOnClickListener(new View.OnClickListener() {
36 | @Override
37 | public void onClick(View view) {
38 | NavHostFragment.findNavController(ContentFragment.this)
39 | .navigate(R.id.action_ContentFragment_to_PhotoFragment);
40 | }
41 | });
42 | }
43 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/picodetncnn/MainActivity.java:
--------------------------------------------------------------------------------
1 | package com.baidu.picodetncnn;
2 |
3 | import android.os.Bundle;
4 | import android.view.Menu;
5 | import android.view.MenuItem;
6 |
7 | import androidx.appcompat.app.AppCompatActivity;
8 | import androidx.appcompat.widget.Toolbar;
9 |
10 | import com.google.android.material.navigation.NavigationView;
11 |
12 | public class MainActivity extends AppCompatActivity {
13 | private NavigationView navigationView;
14 |
15 | @Override
16 | protected void onCreate(Bundle savedInstanceState) {
17 | super.onCreate(savedInstanceState);
18 | setContentView(R.layout.activity_main);
19 | Toolbar toolbar = findViewById(R.id.toolbar);
20 | setSupportActionBar(toolbar);
21 |
22 | }
23 |
24 | @Override
25 | public boolean onCreateOptionsMenu(Menu menu) {
26 | // Inflate the menu; this adds items to the action bar if it is present.
27 | getMenuInflater().inflate(R.menu.menu_main, menu);
28 | return true;
29 | }
30 |
31 | @Override
32 | public boolean onOptionsItemSelected(MenuItem item) {
33 | // Handle action bar item clicks here. The action bar will
34 | // automatically handle clicks on the Home/Up button, so long
35 | // as you specify a parent activity in AndroidManifest.xml.
36 | int id = item.getItemId();
37 |
38 | //noinspection SimplifiableIfStatement
39 | if (id == R.id.action_settings) {
40 | return true;
41 | }
42 |
43 | return super.onOptionsItemSelected(item);
44 | }
45 | }
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/picodetncnn/NanoDetNcnn.java:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | package com.baidu.picodetncnn;
16 |
17 | import android.content.res.AssetManager;
18 | import android.view.Surface;
19 |
20 | public class NanoDetNcnn
21 | {
22 | public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);
23 | public native boolean openCamera(int facing);
24 | public native boolean closeCamera();
25 | public native boolean setOutputWindow(Surface surface);
26 | public native double testInferTime(AssetManager mgr, int modelid, int cpugpu);
27 |
28 | public native boolean genVideoByImg();
29 |
30 | static {
31 | System.loadLibrary("picodetncnn");
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/app/src/main/java/com/baidu/picodetncnn/PhotoFragment.java:
--------------------------------------------------------------------------------
1 | package com.baidu.picodetncnn;
2 |
3 | import android.app.ProgressDialog;
4 | import android.graphics.Bitmap;
5 | import android.graphics.BitmapFactory;
6 | import android.os.Bundle;
7 | import android.os.Handler;
8 | import android.os.HandlerThread;
9 | import android.os.Message;
10 | import android.util.Log;
11 | import android.view.LayoutInflater;
12 | import android.view.View;
13 | import android.view.ViewGroup;
14 | import android.widget.AdapterView;
15 | import android.widget.ImageView;
16 | import android.widget.Spinner;
17 | import android.widget.TextView;
18 | import android.widget.Toast;
19 |
20 | import androidx.annotation.NonNull;
21 | import androidx.fragment.app.Fragment;
22 |
23 | import java.io.File;
24 | import java.io.FileOutputStream;
25 | import java.io.InputStream;
26 | import java.text.DecimalFormat;
27 |
28 |
29 | public class PhotoFragment extends Fragment {
30 |
31 | String video_file = "out.mp4";
32 | // String video_file = "test3.mp4";
33 |
34 | private static final String TAG = PhotoFragment.class.getSimpleName();
35 | private Spinner spinnerModel;
36 | private Spinner spinnerCPUGPU;
37 | NanoDetNcnn nanoDetNcnn = new NanoDetNcnn();
38 | private int current_model = 0;
39 | private int current_cpugpu = 0;
40 | ImageView inferImageView;
41 | TextView fpsTextView;
42 | int count = 0;
43 | int frameCount = 249;
44 | // int frameCount = 630;
45 | boolean isRunThread = true;
46 |
47 | ProgressDialog dialog = null;
48 | protected Handler sender = null; // Send command to worker thread
49 | public static final int REQUEST_RUN_MODEL = 0;
50 | public static final int RESPONSE_RUN_MODEL_SUCCESSED = 2;
51 | public static final int RESPONSE_RUN_MODEL_FAILED = 3;
52 | protected HandlerThread worker = null; // Worker thread to load&run model
53 | public Handler receiver = null; // Receive messages from worker thread
54 |
55 |
56 | @Override
57 | public View onCreateView(
58 | LayoutInflater inflater, ViewGroup container,
59 | Bundle savedInstanceState
60 | ) {
61 | // Inflate the layout for this fragment
62 | return inflater.inflate(R.layout.fragment_photo, container, false);
63 | }
64 |
65 | public void onViewCreated(@NonNull View view, Bundle savedInstanceState) {
66 | super.onViewCreated(view, savedInstanceState);
67 | initView(view);
68 | start_run_model();
69 | }
70 |
71 | public void start_run_model(){
72 | dialog = ProgressDialog.show(getActivity(), "", "Running, please wait...", false, false);
73 | sender.sendEmptyMessage(REQUEST_RUN_MODEL);
74 | }
75 |
76 | public boolean run_detect_video(){
77 |
78 | isRunThread = false;
79 | double inferTime = nanoDetNcnn.testInferTime(getActivity().getAssets(), current_model, current_cpugpu);
80 | double fps = frameCount*1000/inferTime;
81 | DecimalFormat decimalFormat = new DecimalFormat("#.00");
82 | String fpsStr = decimalFormat.format(fps);
83 | fpsTextView.setText("FPS: "+fpsStr);
84 | isRunThread = true;
85 | getShowImgThread().start();
86 | return true;
87 | }
88 |
89 | public void initView(@NonNull View view) {
90 | spinnerModel = (Spinner) view.findViewById(R.id.spinnerModel_1);
91 | spinnerCPUGPU = (Spinner) view.findViewById(R.id.spinnerCPUGPU_1);
92 | inferImageView = view.findViewById(R.id.showInferImg);
93 | fpsTextView = view.findViewById(R.id.fpsTextView);
94 | System.out.println("ncnn: copyMP42Cache");
95 | copyMP42Cache();
96 |
97 | spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
98 | @Override
99 | public void onItemSelected(AdapterView> arg0, View arg1, int position, long id)
100 | {
101 | if (position != current_model)
102 | {
103 | isRunThread = false;
104 | current_model = position;
105 | System.out.println("current_model => "+current_model);
106 | try{
107 | isRunThread = false;
108 | }catch (Exception e){
109 | Log.d("ncnn: ", "stop thread ...");
110 | }
111 |
112 | start_run_model();
113 | }
114 | }
115 |
116 | @Override
117 | public void onNothingSelected(AdapterView> arg0)
118 | {
119 | }
120 | });
121 | // 切换cpu/gpu
122 | spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
123 | @Override
124 | public void onItemSelected(AdapterView> arg0, View arg1, int position, long id)
125 | {
126 | if (position != current_cpugpu)
127 | {
128 | current_cpugpu = position;
129 | System.out.println("current_model => "+current_model);
130 | try{
131 | isRunThread = false;
132 | }catch (Exception e){
133 | Log.d("ncnn: ", "stop thread ...");
134 | }
135 |
136 | start_run_model();
137 | }
138 | }
139 |
140 | @Override
141 | public void onNothingSelected(AdapterView> arg0)
142 | {
143 | }
144 | });
145 |
146 | receiver = new Handler() {
147 | @Override
148 | public void handleMessage(Message msg) {
149 | switch (msg.what) {
150 | case RESPONSE_RUN_MODEL_SUCCESSED:
151 | dialog.dismiss();
152 | break;
153 | case RESPONSE_RUN_MODEL_FAILED:
154 | dialog.dismiss();
155 | Toast.makeText(getActivity(), "Run model failed!", Toast.LENGTH_SHORT).show();
156 | break;
157 | default:
158 | break;
159 | }
160 | }
161 | };
162 |
163 |
164 | worker = new HandlerThread("Predictor Worker");
165 | worker.start();
166 | sender = new Handler(worker.getLooper()) {
167 | public void handleMessage(Message msg) {
168 | switch (msg.what) {
169 | case REQUEST_RUN_MODEL:
170 | // Run model if model is loaded
171 | if (run_detect_video()) {
172 | receiver.sendEmptyMessage(RESPONSE_RUN_MODEL_SUCCESSED);
173 | } else {
174 | receiver.sendEmptyMessage(RESPONSE_RUN_MODEL_FAILED);
175 | }
176 | break;
177 | default:
178 | break;
179 | }
180 | }
181 | };
182 |
183 | }
184 |
185 | public Thread getShowImgThread(){
186 | return new Thread(new Runnable() {
187 | @Override
188 | public void run() {
189 | File fileDir = new File(getActivity().getExternalCacheDir()+"");
190 | Log.e("ncnn:","file path =>"+fileDir.getAbsolutePath());
191 | while(isRunThread){
192 | try {
193 | final String imageName = fileDir.list()[count%frameCount];
194 | count ++;
195 | if(imageName.contains(".jpg")){
196 | getActivity().runOnUiThread(new Runnable() {
197 | @Override
198 | public void run() {
199 | Bitmap bitmap = BitmapFactory.decodeFile(getActivity().getExternalCacheDir() +"/"+imageName);
200 | inferImageView.setImageBitmap(bitmap);
201 | // inferImageView.setRotation(90);
202 | }
203 | });
204 | }
205 | Thread.sleep(50);
206 | } catch (Exception e) {
207 | e.printStackTrace();
208 | }
209 | }
210 |
211 | }
212 | });
213 |
214 | }
215 |
216 | public void copyMP42Cache() {
217 | File file = new File(getActivity().getExternalCacheDir()+"/"+video_file);
218 | Log.e("ncnn: src video dir => ", file.getAbsolutePath());
219 | if (!file.exists()) {
220 | try {
221 | InputStream is = getActivity().getAssets().open(video_file);
222 | int size = is.available();
223 | byte[] buffer = new byte[size];
224 | is.read(buffer);
225 | is.close();
226 | FileOutputStream fos = new FileOutputStream(file);
227 | fos.write(buffer);
228 | fos.close();
229 | } catch (Exception e) {
230 | Log.e("***************ncnn: copy src file to dst file failed => ", file.getAbsolutePath());
231 | throw new RuntimeException(e);
232 | }
233 | } else {
234 | Log.e("*******************ncnn: dst file exist => ", file.getAbsolutePath());
235 | }
236 | }
237 |
238 | @Override
239 | public void onResume() {
240 | super.onResume();
241 | }
242 |
243 | @Override
244 | public void onDestroy() {
245 | super.onDestroy();
246 | }
247 | }
--------------------------------------------------------------------------------
/app/src/main/jni/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | #project(picodetncnn)
2 | #cmake_minimum_required(VERSION 3.10)
3 | #set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni)
4 | ##set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/aaa/sdk/native/jni)
5 | ##set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.5.3-android/sdk/native/jni)
6 | ##set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni)
7 | ## jiwei
8 | ##include_directories(${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni/include)
9 | #find_package(OpenCV REQUIRED core imgproc highgui)
10 | #set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
11 | #find_package(ncnn REQUIRED)
12 | #add_library(picodetncnn SHARED nanodetncnn.cpp nanodet.cpp ndkcamera.cpp)
13 | #target_link_libraries(picodetncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)
14 |
15 |
16 |
17 |
18 | #project(picodetncnn)
19 | ##include(ndk-stl-config.cmake)
20 | #cmake_minimum_required(VERSION 3.10)
21 | #
22 | ## add name==picodetncnn, source file can be denoted
23 | #include_directories(${CMAKE_SOURCE_DIR}/opencv/native/jni/include)
24 | ##add_library(lib_opencv SHARED IMPORTED)
25 | ##set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/opencv/native/libs/${ANDROID_ABI}/libopencv_java4.so)
26 | #
27 | ## ncnn
28 | #set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
29 | #find_package(ncnn REQUIRED)
30 | #
31 | ## picodetncnn
32 | #add_library(picodetncnn SHARED nanodetncnn.cpp nanodet.cpp ndkcamera.cpp)
33 | ## 被依赖的库放在依赖的库后面
34 | ##target_link_libraries(picodetncnn ncnn camera2ndk mediandk lib_opencv)
35 | #
36 | #target_link_libraries(picodetncnn ncnn camera2ndk mediandk)
37 | #
38 | #
39 | #
40 | #
41 | #
42 |
43 | project(picodetncnn)
44 | cmake_minimum_required(VERSION 3.10)
45 |
46 | set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv/sdk/native/jni)
47 | #set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/OpenCV-android-sdk/sdk/native/jni)
48 | #find_package(OpenCV REQUIRED core imgproc video videoio highgui)
49 | find_package(OpenCV REQUIRED)
50 |
51 | set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20210720-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
52 | find_package(ncnn REQUIRED)
53 | add_library(picodetncnn SHARED nanodetncnn.cpp nanodet.cpp ndkcamera.cpp)
54 | target_link_libraries(picodetncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)
--------------------------------------------------------------------------------
/app/src/main/jni/nanodet.h:
--------------------------------------------------------------------------------
1 | // Tencent is pleased to support the open source community by making ncnn available.
2 | //
3 | // Copyright (C) 2021 THL A29 Limited, a Tencent company. All rights reserved.
4 | //
5 | // Licensed under the BSD 3-Clause License (the "License"); you may not use this file except
6 | // in compliance with the License. You may obtain a copy of the License at
7 | //
8 | // https://opensource.org/licenses/BSD-3-Clause
9 | //
10 | // Unless required by applicable law or agreed to in writing, software distributed
11 | // under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
12 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the
13 | // specific language governing permissions and limitations under the License.
14 |
15 | #ifndef NANODET_H
16 | #define NANODET_H
17 |
18 | #include
19 |
20 | #include
21 |
22 |
23 | struct Object
24 | {
25 | cv::Rect_ rect;
26 | int label;
27 | float prob;
28 | //yolov5
29 | float x;
30 | float y;
31 | float w;
32 | float h;
33 | // int label;
34 | // float prob;
35 | };
36 |
37 | class NanoDet
38 | {
39 | public:
40 | NanoDet();
41 |
42 | int load(const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);
43 |
44 | int load(AAssetManager* mgr, const char* modeltype, int target_size, const float* mean_vals, const float* norm_vals, bool use_gpu = false);
45 |
46 | int detect(const cv::Mat& rgb, std::vector