Repository: nihui/ncnn-android-scrfd
Branch: master
Commit: f94e2630ac1b
Files: 28
Total size: 164.8 KB
Directory structure:
gitextract_t36i4fjw/
├── .github/
│ └── workflows/
│ └── release-apk.yml
├── README.md
├── app/
│ ├── build.gradle
│ └── src/
│ └── main/
│ ├── AndroidManifest.xml
│ ├── assets/
│ │ ├── scrfd_10g-opt2.param
│ │ ├── scrfd_10g_kps-opt2.param
│ │ ├── scrfd_1g-opt2.param
│ │ ├── scrfd_2.5g-opt2.param
│ │ ├── scrfd_2.5g_kps-opt2.param
│ │ ├── scrfd_34g-opt2.param
│ │ ├── scrfd_500m-opt2.param
│ │ └── scrfd_500m_kps-opt2.param
│ ├── java/
│ │ └── com/
│ │ └── tencent/
│ │ └── scrfdncnn/
│ │ ├── MainActivity.java
│ │ └── SCRFDNcnn.java
│ ├── jni/
│ │ ├── CMakeLists.txt
│ │ ├── ndkcamera.cpp
│ │ ├── ndkcamera.h
│ │ ├── scrfd.cpp
│ │ ├── scrfd.h
│ │ └── scrfdncnn.cpp
│ └── res/
│ ├── layout/
│ │ └── main.xml
│ └── values/
│ └── strings.xml
├── build.gradle
├── gradle/
│ └── wrapper/
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
└── settings.gradle
================================================
FILE CONTENTS
================================================
================================================
FILE: .github/workflows/release-apk.yml
================================================
name: release-apk
on: workflow_dispatch
env:
NCNN_VERSION: 20260113
OPENCV_VERSION: 4.13.0
OPENCV_MOBILE_TAG: v35
BUILD_TOOLS_VERSION: 36.0.0
jobs:
release-apk:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
distribution: 'temurin'
java-version: '21'
- name: ncnn
run: |
wget -q https://github.com/Tencent/ncnn/releases/download/${NCNN_VERSION}/ncnn-${NCNN_VERSION}-android-vulkan.zip
unzip -q ncnn-${NCNN_VERSION}-android-vulkan.zip -d app/src/main/jni
- name: opencv-mobile
run: |
wget -q https://github.com/nihui/opencv-mobile/releases/download/${OPENCV_MOBILE_TAG}/opencv-mobile-${OPENCV_VERSION}-android.zip
unzip -q opencv-mobile-${OPENCV_VERSION}-android.zip -d app/src/main/jni
- name: modify-jni-cmakelists
run: |
sed -i "s@ncnn-[^-]*-android-vulkan@ncnn-${NCNN_VERSION}-android-vulkan@g" app/src/main/jni/CMakeLists.txt
sed -i "s@opencv-mobile-[^-]*-android@opencv-mobile-${OPENCV_VERSION}-android@g" app/src/main/jni/CMakeLists.txt
- name: build-apk
run: |
bash ./gradlew assembleRelease --stacktrace
- name: sign-apk
id: signapk
run: |
DATE=`date +'%Y%m%d'`
SHA_SHORT=`git rev-parse --short HEAD`
UNSIGNED_APK=`find app/build/outputs/apk/release -type f -name "*-release-unsigned.apk" | head -n 1`
ALIGNED_APK=${UNSIGNED_APK//-release-unsigned.apk/-release-unsigned-aligned.apk}
SIGNED_APK=${{ github.event.repository.name }}-${DATE}.${SHA_SHORT}.apk
keytool -genkey -noprompt -alias ncnn \
-dname "CN=mqttserver.ibm.com, OU=ID, O=IBM, L=Hursley, S=Hants, C=GB"\
-keystore ncnn.keystore -storepass 7767517 -keypass 7767517 \
-keyalg RSA -keysize 2048 -validity 10000
${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/zipalign -f -v 4 ${UNSIGNED_APK} ${SIGNED_APK}
${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner sign --ks ncnn.keystore --ks-key-alias ncnn \
--ks-pass pass:7767517 --key-pass pass:7767517 --out ${SIGNED_APK} ${SIGNED_APK}
${ANDROID_HOME}/build-tools/${BUILD_TOOLS_VERSION}/apksigner verify ${SIGNED_APK}
echo "SIGNED_APK=${SIGNED_APK}" >> $GITHUB_OUTPUT
echo "APK_VERSION=${DATE}.${SHA_SHORT}" >> $GITHUB_OUTPUT
- name: create-release
uses: softprops/action-gh-release@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
tag_name: ${{ steps.signapk.outputs.APK_VERSION }}
name: Release ${{ steps.signapk.outputs.APK_VERSION }}
files: ${{ steps.signapk.outputs.SIGNED_APK }}
================================================
FILE: README.md
================================================
# ncnn-android-scrfd
The SCRFD face detection
This is a sample ncnn android project, it depends on ncnn library and opencv
https://github.com/Tencent/ncnn
https://github.com/nihui/opencv-mobile
## android apk file download
https://github.com/nihui/ncnn-android-scrfd/releases/latest
## 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!
## some notes
* Android ndk camera is used for best efficiency
* Crash may happen on very old devices for lacking HAL3 camera interface
* All models are manually modified to accept dynamic input shape
* Most small models run slower on GPU than on CPU, this is common
* FPS may be lower in dark environment because of longer camera exposure time
## screenshot

================================================
FILE: app/build.gradle
================================================
plugins {
id 'com.android.application'
}
android {
namespace 'com.tencent.scrfdncnn'
compileSdk 33
ndkVersion "29.0.14206865"
defaultConfig {
applicationId "com.tencent.scrfdncnn"
archivesBaseName = "$applicationId"
minSdkVersion 24
targetSdkVersion 35
externalNativeBuild {
cmake {
arguments "-DANDROID_SUPPORT_FLEXIBLE_PAGE_SIZES=ON"
}
}
}
externalNativeBuild {
cmake {
version "3.31.5"
path file('src/main/jni/CMakeLists.txt')
}
}
dependencies {
implementation 'com.android.support:support-v4:24.0.0'
}
packaging {
jniLibs {
useLegacyPackaging true
}
}
}
================================================
FILE: app/src/main/AndroidManifest.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
android:versionCode="1"
android:versionName="1.1">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera2.full" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<application android:label="@string/app_name">
<activity android:name="MainActivity" android:label="@string/app_name" android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
================================================
FILE: app/src/main/assets/scrfd_10g-opt2.param
================================================
7767517
133 154
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 220 0=28 1=3 3=2 4=1 5=1 6=756 9=1
Convolution Conv_2 1 1 220 223 0=28 1=3 4=1 5=1 6=7056 9=1
Convolution Conv_4 1 1 223 226 0=56 1=3 4=1 5=1 6=14112 9=1
Pooling MaxPool_6 1 1 226 227 1=2 2=2 5=1
Split splitncnn_0 1 2 227 227_splitncnn_0 227_splitncnn_1
Convolution Conv_7 1 1 227_splitncnn_1 230 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_9 1 1 230 532 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_10 2 1 532 227_splitncnn_0 233
ReLU Relu_11 1 1 233 234
Split splitncnn_1 1 2 234 234_splitncnn_0 234_splitncnn_1
Convolution Conv_12 1 1 234_splitncnn_1 237 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_14 1 1 237 538 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_15 2 1 538 234_splitncnn_0 240
ReLU Relu_16 1 1 240 241
Split splitncnn_2 1 2 241 241_splitncnn_0 241_splitncnn_1
Convolution Conv_17 1 1 241_splitncnn_1 244 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_19 1 1 244 544 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_20 2 1 544 241_splitncnn_0 247
ReLU Relu_21 1 1 247 248
Split splitncnn_3 1 2 248 248_splitncnn_0 248_splitncnn_1
Convolution Conv_22 1 1 248_splitncnn_1 251 0=88 1=3 3=2 4=1 5=1 6=44352 9=1
Convolution Conv_24 1 1 251 550 0=88 1=3 4=1 5=1 6=69696
Pooling AveragePool_25 1 1 248_splitncnn_0 254 0=1 1=2 2=2
Convolution Conv_26 1 1 254 553 0=88 1=1 5=1 6=4928
BinaryOp Add_27 2 1 550 553 257
ReLU Relu_28 1 1 257 258
Split splitncnn_4 1 2 258 258_splitncnn_0 258_splitncnn_1
Convolution Conv_29 1 1 258_splitncnn_1 261 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_31 1 1 261 559 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_32 2 1 559 258_splitncnn_0 264
ReLU Relu_33 1 1 264 265
Split splitncnn_5 1 2 265 265_splitncnn_0 265_splitncnn_1
Convolution Conv_34 1 1 265_splitncnn_1 268 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_36 1 1 268 565 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_37 2 1 565 265_splitncnn_0 271
ReLU Relu_38 1 1 271 272
Split splitncnn_6 1 2 272 272_splitncnn_0 272_splitncnn_1
Convolution Conv_39 1 1 272_splitncnn_1 275 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_41 1 1 275 571 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_42 2 1 571 272_splitncnn_0 278
ReLU Relu_43 1 1 278 279
Split splitncnn_7 1 3 279 279_splitncnn_0 279_splitncnn_1 279_splitncnn_2
Convolution Conv_44 1 1 279_splitncnn_2 282 0=88 1=3 3=2 4=1 5=1 6=69696 9=1
Convolution Conv_46 1 1 282 577 0=88 1=3 4=1 5=1 6=69696
Pooling AveragePool_47 1 1 279_splitncnn_1 285 0=1 1=2 2=2
Convolution Conv_48 1 1 285 580 0=88 1=1 5=1 6=7744
BinaryOp Add_49 2 1 577 580 288
ReLU Relu_50 1 1 288 289
Split splitncnn_8 1 2 289 289_splitncnn_0 289_splitncnn_1
Convolution Conv_51 1 1 289_splitncnn_1 292 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_53 1 1 292 586 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_54 2 1 586 289_splitncnn_0 295
ReLU Relu_55 1 1 295 296
Split splitncnn_9 1 3 296 296_splitncnn_0 296_splitncnn_1 296_splitncnn_2
Convolution Conv_56 1 1 296_splitncnn_2 299 0=224 1=3 3=2 4=1 5=1 6=177408 9=1
Convolution Conv_58 1 1 299 592 0=224 1=3 4=1 5=1 6=451584
Pooling AveragePool_59 1 1 296_splitncnn_1 302 0=1 1=2 2=2
Convolution Conv_60 1 1 302 595 0=224 1=1 5=1 6=19712
BinaryOp Add_61 2 1 592 595 305
ReLU Relu_62 1 1 305 306
Split splitncnn_10 1 2 306 306_splitncnn_0 306_splitncnn_1
Convolution Conv_63 1 1 306_splitncnn_1 309 0=224 1=3 4=1 5=1 6=451584 9=1
Convolution Conv_65 1 1 309 601 0=224 1=3 4=1 5=1 6=451584
BinaryOp Add_66 2 1 601 306_splitncnn_0 312
ReLU Relu_67 1 1 312 313
Split splitncnn_11 1 2 313 313_splitncnn_0 313_splitncnn_1
Convolution Conv_68 1 1 313_splitncnn_1 316 0=224 1=3 4=1 5=1 6=451584 9=1
Convolution Conv_70 1 1 316 607 0=224 1=3 4=1 5=1 6=451584
BinaryOp Add_71 2 1 607 313_splitncnn_0 319
ReLU Relu_72 1 1 319 320
Convolution Conv_73 1 1 279_splitncnn_0 321 0=56 1=1 5=1 6=4928
Convolution Conv_74 1 1 296_splitncnn_0 322 0=56 1=1 5=1 6=4928
Convolution Conv_75 1 1 320 323 0=56 1=1 5=1 6=12544
Split splitncnn_12 1 2 323 323_splitncnn_0 323_splitncnn_1
Interp Resize_94 1 1 323_splitncnn_1 342 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_95 2 1 322 342 343
Split splitncnn_13 1 2 343 343_splitncnn_0 343_splitncnn_1
Interp Resize_114 1 1 343_splitncnn_1 362 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_115 2 1 321 362 363
Convolution Conv_116 1 1 363 364 0=56 1=3 4=1 5=1 6=28224
Split splitncnn_14 1 2 364 364_splitncnn_0 364_splitncnn_1
Convolution Conv_117 1 1 343_splitncnn_0 365 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_118 1 1 323_splitncnn_0 366 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_119 1 1 364_splitncnn_1 367 0=56 1=3 3=2 4=1 5=1 6=28224
BinaryOp Add_120 2 1 365 367 368
Split splitncnn_15 1 2 368 368_splitncnn_0 368_splitncnn_1
Convolution Conv_121 1 1 368_splitncnn_1 369 0=56 1=3 3=2 4=1 5=1 6=28224
BinaryOp Add_122 2 1 366 369 370
Convolution Conv_123 1 1 368_splitncnn_0 371 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_124 1 1 370 372 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_125 1 1 364_splitncnn_0 373 0=80 1=3 4=1 6=40320
GroupNorm Add_134 1 1 373 384 0=16 1=80 2=1.000000e-05
ReLU Relu_135 1 1 384 385
Convolution Conv_136 1 1 385 386 0=80 1=3 4=1 6=57600
GroupNorm Add_145 1 1 386 397 0=16 1=80 2=1.000000e-05
ReLU Relu_146 1 1 397 398
Convolution Conv_147 1 1 398 399 0=80 1=3 4=1 6=57600
GroupNorm Add_156 1 1 399 410 0=16 1=80 2=1.000000e-05
ReLU Relu_157 1 1 410 411
Split splitncnn_16 1 2 411 411_splitncnn_0 411_splitncnn_1
Convolution Conv_158 1 1 411_splitncnn_1 417 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_159 1 1 411_splitncnn_0 413 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_160 1 1 413 bbox_8 0=2 1=1 2=8.170338e-01
Sigmoid Sigmoid_164 1 1 417 score_8
Convolution Conv_168 1 1 371 422 0=80 1=3 4=1 6=40320
GroupNorm Add_177 1 1 422 433 0=16 1=80 2=1.000000e-05
ReLU Relu_178 1 1 433 434
Convolution Conv_179 1 1 434 435 0=80 1=3 4=1 6=57600
GroupNorm Add_188 1 1 435 446 0=16 1=80 2=1.000000e-05
ReLU Relu_189 1 1 446 447
Convolution Conv_190 1 1 447 448 0=80 1=3 4=1 6=57600
GroupNorm Add_199 1 1 448 459 0=16 1=80 2=1.000000e-05
ReLU Relu_200 1 1 459 460
Split splitncnn_17 1 2 460 460_splitncnn_0 460_splitncnn_1
Convolution Conv_201 1 1 460_splitncnn_1 466 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_202 1 1 460_splitncnn_0 462 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_203 1 1 462 bbox_16 0=2 1=1 2=1.195922e+00
Sigmoid Sigmoid_207 1 1 466 score_16
Convolution Conv_211 1 1 372 471 0=80 1=3 4=1 6=40320
GroupNorm Add_220 1 1 471 482 0=16 1=80 2=1.000000e-05
ReLU Relu_221 1 1 482 483
Convolution Conv_222 1 1 483 484 0=80 1=3 4=1 6=57600
GroupNorm Add_231 1 1 484 495 0=16 1=80 2=1.000000e-05
ReLU Relu_232 1 1 495 496
Convolution Conv_233 1 1 496 497 0=80 1=3 4=1 6=57600
GroupNorm Add_242 1 1 497 508 0=16 1=80 2=1.000000e-05
ReLU Relu_243 1 1 508 509
Split splitncnn_18 1 2 509 509_splitncnn_0 509_splitncnn_1
Convolution Conv_244 1 1 509_splitncnn_1 515 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_245 1 1 509_splitncnn_0 511 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_246 1 1 511 bbox_32 0=2 1=1 2=1.814443e+00
Sigmoid Sigmoid_250 1 1 515 score_32
================================================
FILE: app/src/main/assets/scrfd_10g_kps-opt2.param
================================================
7767517
118 142
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 279 0=28 1=3 3=2 4=1 5=1 6=756 9=1
Convolution Conv_2 1 1 279 282 0=28 1=3 4=1 5=1 6=7056 9=1
Convolution Conv_4 1 1 282 285 0=56 1=3 4=1 5=1 6=14112 9=1
Pooling MaxPool_6 1 1 285 286 1=2 2=2 5=1
Split splitncnn_0 1 2 286 286_splitncnn_0 286_splitncnn_1
Convolution Conv_7 1 1 286_splitncnn_1 289 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_9 1 1 289 513 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_10 2 1 513 286_splitncnn_0 292
ReLU Relu_11 1 1 292 293
Split splitncnn_1 1 2 293 293_splitncnn_0 293_splitncnn_1
Convolution Conv_12 1 1 293_splitncnn_1 296 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_14 1 1 296 519 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_15 2 1 519 293_splitncnn_0 299
ReLU Relu_16 1 1 299 300
Split splitncnn_2 1 2 300 300_splitncnn_0 300_splitncnn_1
Convolution Conv_17 1 1 300_splitncnn_1 303 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_19 1 1 303 525 0=56 1=3 4=1 5=1 6=28224
BinaryOp Add_20 2 1 525 300_splitncnn_0 306
ReLU Relu_21 1 1 306 307
Split splitncnn_3 1 2 307 307_splitncnn_0 307_splitncnn_1
Convolution Conv_22 1 1 307_splitncnn_1 310 0=88 1=3 3=2 4=1 5=1 6=44352 9=1
Convolution Conv_24 1 1 310 531 0=88 1=3 4=1 5=1 6=69696
Pooling AveragePool_25 1 1 307_splitncnn_0 313 0=1 1=2 2=2
Convolution Conv_26 1 1 313 534 0=88 1=1 5=1 6=4928
BinaryOp Add_27 2 1 531 534 316
ReLU Relu_28 1 1 316 317
Split splitncnn_4 1 2 317 317_splitncnn_0 317_splitncnn_1
Convolution Conv_29 1 1 317_splitncnn_1 320 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_31 1 1 320 540 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_32 2 1 540 317_splitncnn_0 323
ReLU Relu_33 1 1 323 324
Split splitncnn_5 1 2 324 324_splitncnn_0 324_splitncnn_1
Convolution Conv_34 1 1 324_splitncnn_1 327 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_36 1 1 327 546 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_37 2 1 546 324_splitncnn_0 330
ReLU Relu_38 1 1 330 331
Split splitncnn_6 1 2 331 331_splitncnn_0 331_splitncnn_1
Convolution Conv_39 1 1 331_splitncnn_1 334 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_41 1 1 334 552 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_42 2 1 552 331_splitncnn_0 337
ReLU Relu_43 1 1 337 338
Split splitncnn_7 1 3 338 338_splitncnn_0 338_splitncnn_1 338_splitncnn_2
Convolution Conv_44 1 1 338_splitncnn_2 341 0=88 1=3 3=2 4=1 5=1 6=69696 9=1
Convolution Conv_46 1 1 341 558 0=88 1=3 4=1 5=1 6=69696
Pooling AveragePool_47 1 1 338_splitncnn_1 344 0=1 1=2 2=2
Convolution Conv_48 1 1 344 561 0=88 1=1 5=1 6=7744
BinaryOp Add_49 2 1 558 561 347
ReLU Relu_50 1 1 347 348
Split splitncnn_8 1 2 348 348_splitncnn_0 348_splitncnn_1
Convolution Conv_51 1 1 348_splitncnn_1 351 0=88 1=3 4=1 5=1 6=69696 9=1
Convolution Conv_53 1 1 351 567 0=88 1=3 4=1 5=1 6=69696
BinaryOp Add_54 2 1 567 348_splitncnn_0 354
ReLU Relu_55 1 1 354 355
Split splitncnn_9 1 3 355 355_splitncnn_0 355_splitncnn_1 355_splitncnn_2
Convolution Conv_56 1 1 355_splitncnn_2 358 0=224 1=3 3=2 4=1 5=1 6=177408 9=1
Convolution Conv_58 1 1 358 573 0=224 1=3 4=1 5=1 6=451584
Pooling AveragePool_59 1 1 355_splitncnn_1 361 0=1 1=2 2=2
Convolution Conv_60 1 1 361 576 0=224 1=1 5=1 6=19712
BinaryOp Add_61 2 1 573 576 364
ReLU Relu_62 1 1 364 365
Split splitncnn_10 1 2 365 365_splitncnn_0 365_splitncnn_1
Convolution Conv_63 1 1 365_splitncnn_1 368 0=224 1=3 4=1 5=1 6=451584 9=1
Convolution Conv_65 1 1 368 582 0=224 1=3 4=1 5=1 6=451584
BinaryOp Add_66 2 1 582 365_splitncnn_0 371
ReLU Relu_67 1 1 371 372
Split splitncnn_11 1 2 372 372_splitncnn_0 372_splitncnn_1
Convolution Conv_68 1 1 372_splitncnn_1 375 0=224 1=3 4=1 5=1 6=451584 9=1
Convolution Conv_70 1 1 375 588 0=224 1=3 4=1 5=1 6=451584
BinaryOp Add_71 2 1 588 372_splitncnn_0 378
ReLU Relu_72 1 1 378 379
Convolution Conv_73 1 1 338_splitncnn_0 380 0=56 1=1 5=1 6=4928
Convolution Conv_74 1 1 355_splitncnn_0 381 0=56 1=1 5=1 6=4928
Convolution Conv_75 1 1 379 382 0=56 1=1 5=1 6=12544
Split splitncnn_12 1 2 382 382_splitncnn_0 382_splitncnn_1
Interp Resize_94 1 1 382_splitncnn_1 401 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_95 2 1 381 401 402
Split splitncnn_13 1 2 402 402_splitncnn_0 402_splitncnn_1
Interp Resize_114 1 1 402_splitncnn_1 421 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_115 2 1 380 421 422
Convolution Conv_116 1 1 422 423 0=56 1=3 4=1 5=1 6=28224
Split splitncnn_14 1 2 423 423_splitncnn_0 423_splitncnn_1
Convolution Conv_117 1 1 402_splitncnn_0 424 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_118 1 1 382_splitncnn_0 425 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_119 1 1 423_splitncnn_1 426 0=56 1=3 3=2 4=1 5=1 6=28224
BinaryOp Add_120 2 1 424 426 427
Split splitncnn_15 1 2 427 427_splitncnn_0 427_splitncnn_1
Convolution Conv_121 1 1 427_splitncnn_1 428 0=56 1=3 3=2 4=1 5=1 6=28224
BinaryOp Add_122 2 1 425 428 429
Convolution Conv_123 1 1 427_splitncnn_0 430 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_124 1 1 429 431 0=56 1=3 4=1 5=1 6=28224
Convolution Conv_125 1 1 423_splitncnn_0 434 0=80 1=3 4=1 5=1 6=40320 9=1
Convolution Conv_127 1 1 434 437 0=80 1=3 4=1 5=1 6=57600 9=1
Convolution Conv_129 1 1 437 440 0=80 1=3 4=1 5=1 6=57600 9=1
Split splitncnn_16 1 3 440 440_splitncnn_0 440_splitncnn_1 440_splitncnn_2
Convolution Conv_131 1 1 440_splitncnn_2 447 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_132 1 1 440_splitncnn_1 442 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_133 1 1 442 bbox_8 0=2 1=1 2=8.463594e-01
Convolution Conv_134 1 1 440_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=14400
Sigmoid Sigmoid_138 1 1 447 score_8
Convolution Conv_145 1 1 430 457 0=80 1=3 4=1 5=1 6=40320 9=1
Convolution Conv_147 1 1 457 460 0=80 1=3 4=1 5=1 6=57600 9=1
Convolution Conv_149 1 1 460 463 0=80 1=3 4=1 5=1 6=57600 9=1
Split splitncnn_17 1 3 463 463_splitncnn_0 463_splitncnn_1 463_splitncnn_2
Convolution Conv_151 1 1 463_splitncnn_2 470 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_152 1 1 463_splitncnn_1 465 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_153 1 1 465 bbox_16 0=2 1=1 2=8.996264e-01
Convolution Conv_154 1 1 463_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=14400
Sigmoid Sigmoid_158 1 1 470 score_16
Convolution Conv_165 1 1 431 480 0=80 1=3 4=1 5=1 6=40320 9=1
Convolution Conv_167 1 1 480 483 0=80 1=3 4=1 5=1 6=57600 9=1
Convolution Conv_169 1 1 483 486 0=80 1=3 4=1 5=1 6=57600 9=1
Split splitncnn_18 1 3 486 486_splitncnn_0 486_splitncnn_1 486_splitncnn_2
Convolution Conv_171 1 1 486_splitncnn_2 493 0=2 1=3 4=1 5=1 6=1440
Convolution Conv_172 1 1 486_splitncnn_1 488 0=8 1=3 4=1 5=1 6=5760
BinaryOp Mul_173 1 1 488 bbox_32 0=2 1=1 2=1.081209e+00
Convolution Conv_174 1 1 486_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=14400
Sigmoid Sigmoid_178 1 1 493 score_32
================================================
FILE: app/src/main/assets/scrfd_1g-opt2.param
================================================
7767517
99 108
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 193 0=32 1=3 3=2 4=1 5=1 6=864 9=1
ConvolutionDepthWise Conv_2 1 1 193 196 0=32 1=3 4=1 5=1 6=288 7=32 9=1
Convolution Conv_4 1 1 196 199 0=48 1=1 5=1 6=1536 9=1
ConvolutionDepthWise Conv_6 1 1 199 202 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1
Convolution Conv_8 1 1 202 205 0=48 1=1 5=1 6=2304 9=1
ConvolutionDepthWise Conv_10 1 1 205 208 0=48 1=3 4=1 5=1 6=432 7=48 9=1
Convolution Conv_12 1 1 208 211 0=48 1=1 5=1 6=2304 9=1
ConvolutionDepthWise Conv_14 1 1 211 214 0=48 1=3 4=1 5=1 6=432 7=48 9=1
Convolution Conv_16 1 1 214 217 0=48 1=1 5=1 6=2304 9=1
ConvolutionDepthWise Conv_18 1 1 217 220 0=48 1=3 3=2 4=1 5=1 6=432 7=48 9=1
Convolution Conv_20 1 1 220 223 0=160 1=1 5=1 6=7680 9=1
ConvolutionDepthWise Conv_22 1 1 223 226 0=160 1=3 4=1 5=1 6=1440 7=160 9=1
Convolution Conv_24 1 1 226 229 0=160 1=1 5=1 6=25600 9=1
Split splitncnn_0 1 2 229 229_splitncnn_0 229_splitncnn_1
ConvolutionDepthWise Conv_26 1 1 229_splitncnn_1 232 0=160 1=3 3=2 4=1 5=1 6=1440 7=160 9=1
Convolution Conv_28 1 1 232 235 0=216 1=1 5=1 6=34560 9=1
Split splitncnn_1 1 2 235 235_splitncnn_0 235_splitncnn_1
ConvolutionDepthWise Conv_30 1 1 235_splitncnn_1 238 0=216 1=3 3=2 4=1 5=1 6=1944 7=216 9=1
Convolution Conv_32 1 1 238 241 0=312 1=1 5=1 6=67392 9=1
ConvolutionDepthWise Conv_34 1 1 241 244 0=312 1=3 4=1 5=1 6=2808 7=312 9=1
Convolution Conv_36 1 1 244 247 0=312 1=1 5=1 6=97344 9=1
ConvolutionDepthWise Conv_38 1 1 247 250 0=312 1=3 4=1 5=1 6=2808 7=312 9=1
Convolution Conv_40 1 1 250 253 0=312 1=1 5=1 6=97344 9=1
ConvolutionDepthWise Conv_42 1 1 253 256 0=312 1=3 4=1 5=1 6=2808 7=312 9=1
Convolution Conv_44 1 1 256 259 0=312 1=1 5=1 6=97344 9=1
ConvolutionDepthWise Conv_46 1 1 259 262 0=312 1=3 4=1 5=1 6=2808 7=312 9=1
Convolution Conv_48 1 1 262 265 0=312 1=1 5=1 6=97344 9=1
Convolution Conv_50 1 1 229_splitncnn_0 266 0=24 1=1 5=1 6=3840
Convolution Conv_51 1 1 235_splitncnn_0 267 0=24 1=1 5=1 6=5184
Convolution Conv_52 1 1 265 268 0=24 1=1 5=1 6=7488
Split splitncnn_2 1 2 268 268_splitncnn_0 268_splitncnn_1
Interp Resize_71 1 1 268_splitncnn_1 287 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_72 2 1 267 287 288
Split splitncnn_3 1 2 288 288_splitncnn_0 288_splitncnn_1
Interp Resize_91 1 1 288_splitncnn_1 307 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_92 2 1 266 307 308
Convolution Conv_93 1 1 308 309 0=24 1=3 4=1 5=1 6=5184
Split splitncnn_4 1 2 309 309_splitncnn_0 309_splitncnn_1
Convolution Conv_94 1 1 288_splitncnn_0 310 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_95 1 1 268_splitncnn_0 311 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_96 1 1 309_splitncnn_1 312 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_97 2 1 310 312 313
Split splitncnn_5 1 2 313 313_splitncnn_0 313_splitncnn_1
Convolution Conv_98 1 1 313_splitncnn_1 314 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_99 2 1 311 314 315
Convolution Conv_100 1 1 313_splitncnn_0 316 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_101 1 1 315 317 0=24 1=3 4=1 5=1 6=5184
ConvolutionDepthWise Conv_102 1 1 309_splitncnn_0 318 0=24 1=3 4=1 6=216 7=24
GroupNorm Add_111 1 1 318 329 0=8 1=24 2=1.000000e-05
ReLU Relu_112 1 1 329 330
Convolution Conv_113 1 1 330 331 0=96 1=1 6=2304
GroupNorm Add_122 1 1 331 342 0=8 1=96 2=1.000000e-05
ReLU Relu_123 1 1 342 343
ConvolutionDepthWise Conv_124 1 1 343 344 0=96 1=3 4=1 6=864 7=96
GroupNorm Add_133 1 1 344 355 0=8 1=96 2=1.000000e-05
ReLU Relu_134 1 1 355 356
Convolution Conv_135 1 1 356 357 0=96 1=1 6=9216
GroupNorm Add_144 1 1 357 368 0=8 1=96 2=1.000000e-05
ReLU Relu_145 1 1 368 369
Split splitncnn_6 1 2 369 369_splitncnn_0 369_splitncnn_1
Convolution Conv_146 1 1 369_splitncnn_1 375 0=2 1=3 4=1 5=1 6=1728
Convolution Conv_147 1 1 369_splitncnn_0 371 0=8 1=3 4=1 5=1 6=6912
BinaryOp Mul_148 1 1 371 bbox_8 0=2 1=1 2=8.200800e-01
Sigmoid Sigmoid_152 1 1 375 score_8
ConvolutionDepthWise Conv_156 1 1 316 380 0=24 1=3 4=1 6=216 7=24
GroupNorm Add_165 1 1 380 391 0=8 1=24 2=1.000000e-05
ReLU Relu_166 1 1 391 392
Convolution Conv_167 1 1 392 393 0=96 1=1 6=2304
GroupNorm Add_176 1 1 393 404 0=8 1=96 2=1.000000e-05
ReLU Relu_177 1 1 404 405
ConvolutionDepthWise Conv_178 1 1 405 406 0=96 1=3 4=1 6=864 7=96
GroupNorm Add_187 1 1 406 417 0=8 1=96 2=1.000000e-05
ReLU Relu_188 1 1 417 418
Convolution Conv_189 1 1 418 419 0=96 1=1 6=9216
GroupNorm Add_198 1 1 419 430 0=8 1=96 2=1.000000e-05
ReLU Relu_199 1 1 430 431
Split splitncnn_7 1 2 431 431_splitncnn_0 431_splitncnn_1
Convolution Conv_200 1 1 431_splitncnn_1 437 0=2 1=3 4=1 5=1 6=1728
Convolution Conv_201 1 1 431_splitncnn_0 433 0=8 1=3 4=1 5=1 6=6912
BinaryOp Mul_202 1 1 433 bbox_16 0=2 1=1 2=1.225648e+00
Sigmoid Sigmoid_206 1 1 437 score_16
ConvolutionDepthWise Conv_210 1 1 317 442 0=24 1=3 4=1 6=216 7=24
GroupNorm Add_219 1 1 442 453 0=8 1=24 2=1.000000e-05
ReLU Relu_220 1 1 453 454
Convolution Conv_221 1 1 454 455 0=96 1=1 6=2304
GroupNorm Add_230 1 1 455 466 0=8 1=96 2=1.000000e-05
ReLU Relu_231 1 1 466 467
ConvolutionDepthWise Conv_232 1 1 467 468 0=96 1=3 4=1 6=864 7=96
GroupNorm Add_241 1 1 468 479 0=8 1=96 2=1.000000e-05
ReLU Relu_242 1 1 479 480
Convolution Conv_243 1 1 480 481 0=96 1=1 6=9216
GroupNorm Add_252 1 1 481 492 0=8 1=96 2=1.000000e-05
ReLU Relu_253 1 1 492 493
Split splitncnn_8 1 2 493 493_splitncnn_0 493_splitncnn_1
Convolution Conv_254 1 1 493_splitncnn_1 499 0=2 1=3 4=1 5=1 6=1728
Convolution Conv_255 1 1 493_splitncnn_0 495 0=8 1=3 4=1 5=1 6=6912
BinaryOp Mul_256 1 1 495 bbox_32 0=2 1=1 2=1.842380e+00
Sigmoid Sigmoid_260 1 1 499 score_32
================================================
FILE: app/src/main/assets/scrfd_2.5g-opt2.param
================================================
7767517
129 151
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 229 0=12 1=3 3=2 4=1 5=1 6=324 9=1
Convolution Conv_2 1 1 229 232 0=12 1=3 4=1 5=1 6=1296 9=1
Convolution Conv_4 1 1 232 235 0=24 1=3 4=1 5=1 6=2592 9=1
Pooling MaxPool_6 1 1 235 236 1=2 2=2 5=1
Split splitncnn_0 1 2 236 236_splitncnn_0 236_splitncnn_1
Convolution Conv_7 1 1 236_splitncnn_1 239 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_9 1 1 239 509 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_10 2 1 509 236_splitncnn_0 242
ReLU Relu_11 1 1 242 243
Split splitncnn_1 1 2 243 243_splitncnn_0 243_splitncnn_1
Convolution Conv_12 1 1 243_splitncnn_1 246 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_14 1 1 246 515 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_15 2 1 515 243_splitncnn_0 249
ReLU Relu_16 1 1 249 250
Split splitncnn_2 1 2 250 250_splitncnn_0 250_splitncnn_1
Convolution Conv_17 1 1 250_splitncnn_1 253 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_19 1 1 253 521 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_20 2 1 521 250_splitncnn_0 256
ReLU Relu_21 1 1 256 257
Split splitncnn_3 1 2 257 257_splitncnn_0 257_splitncnn_1
Convolution Conv_22 1 1 257_splitncnn_1 260 0=48 1=3 3=2 4=1 5=1 6=10368 9=1
Convolution Conv_24 1 1 260 527 0=48 1=3 4=1 5=1 6=20736
Pooling AveragePool_25 1 1 257_splitncnn_0 263 0=1 1=2 2=2
Convolution Conv_26 1 1 263 530 0=48 1=1 5=1 6=1152
BinaryOp Add_27 2 1 527 530 266
ReLU Relu_28 1 1 266 267
Split splitncnn_4 1 2 267 267_splitncnn_0 267_splitncnn_1
Convolution Conv_29 1 1 267_splitncnn_1 270 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_31 1 1 270 536 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_32 2 1 536 267_splitncnn_0 273
ReLU Relu_33 1 1 273 274
Split splitncnn_5 1 2 274 274_splitncnn_0 274_splitncnn_1
Convolution Conv_34 1 1 274_splitncnn_1 277 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_36 1 1 277 542 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_37 2 1 542 274_splitncnn_0 280
ReLU Relu_38 1 1 280 281
Split splitncnn_6 1 2 281 281_splitncnn_0 281_splitncnn_1
Convolution Conv_39 1 1 281_splitncnn_1 284 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_41 1 1 284 548 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_42 2 1 548 281_splitncnn_0 287
ReLU Relu_43 1 1 287 288
Split splitncnn_7 1 2 288 288_splitncnn_0 288_splitncnn_1
Convolution Conv_44 1 1 288_splitncnn_1 291 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_46 1 1 291 554 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_47 2 1 554 288_splitncnn_0 294
ReLU Relu_48 1 1 294 295
Split splitncnn_8 1 3 295 295_splitncnn_0 295_splitncnn_1 295_splitncnn_2
Convolution Conv_49 1 1 295_splitncnn_2 298 0=48 1=3 3=2 4=1 5=1 6=20736 9=1
Convolution Conv_51 1 1 298 560 0=48 1=3 4=1 5=1 6=20736
Pooling AveragePool_52 1 1 295_splitncnn_1 301 0=1 1=2 2=2
Convolution Conv_53 1 1 301 563 0=48 1=1 5=1 6=2304
BinaryOp Add_54 2 1 560 563 304
ReLU Relu_55 1 1 304 305
Split splitncnn_9 1 2 305 305_splitncnn_0 305_splitncnn_1
Convolution Conv_56 1 1 305_splitncnn_1 308 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_58 1 1 308 569 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_59 2 1 569 305_splitncnn_0 311
ReLU Relu_60 1 1 311 312
Split splitncnn_10 1 2 312 312_splitncnn_0 312_splitncnn_1
Convolution Conv_61 1 1 312_splitncnn_1 315 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_63 1 1 315 575 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_64 2 1 575 312_splitncnn_0 318
ReLU Relu_65 1 1 318 319
Split splitncnn_11 1 3 319 319_splitncnn_0 319_splitncnn_1 319_splitncnn_2
Convolution Conv_66 1 1 319_splitncnn_2 322 0=80 1=3 3=2 4=1 5=1 6=34560 9=1
Convolution Conv_68 1 1 322 581 0=80 1=3 4=1 5=1 6=57600
Pooling AveragePool_69 1 1 319_splitncnn_1 325 0=1 1=2 2=2
Convolution Conv_70 1 1 325 584 0=80 1=1 5=1 6=3840
BinaryOp Add_71 2 1 581 584 328
ReLU Relu_72 1 1 328 329
Split splitncnn_12 1 2 329 329_splitncnn_0 329_splitncnn_1
Convolution Conv_73 1 1 329_splitncnn_1 332 0=80 1=3 4=1 5=1 6=57600 9=1
Convolution Conv_75 1 1 332 590 0=80 1=3 4=1 5=1 6=57600
BinaryOp Add_76 2 1 590 329_splitncnn_0 335
ReLU Relu_77 1 1 335 336
Convolution Conv_78 1 1 295_splitncnn_0 337 0=24 1=1 5=1 6=1152
Convolution Conv_79 1 1 319_splitncnn_0 338 0=24 1=1 5=1 6=1152
Convolution Conv_80 1 1 336 339 0=24 1=1 5=1 6=1920
Split splitncnn_13 1 2 339 339_splitncnn_0 339_splitncnn_1
Interp Resize_99 1 1 339_splitncnn_1 358 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_100 2 1 338 358 359
Split splitncnn_14 1 2 359 359_splitncnn_0 359_splitncnn_1
Interp Resize_119 1 1 359_splitncnn_1 378 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_120 2 1 337 378 379
Convolution Conv_121 1 1 379 380 0=24 1=3 4=1 5=1 6=5184
Split splitncnn_15 1 2 380 380_splitncnn_0 380_splitncnn_1
Convolution Conv_122 1 1 359_splitncnn_0 381 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_123 1 1 339_splitncnn_0 382 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_124 1 1 380_splitncnn_1 383 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_125 2 1 381 383 384
Split splitncnn_16 1 2 384 384_splitncnn_0 384_splitncnn_1
Convolution Conv_126 1 1 384_splitncnn_1 385 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_127 2 1 382 385 386
Convolution Conv_128 1 1 384_splitncnn_0 387 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_129 1 1 386 388 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_130 1 1 380_splitncnn_0 389 0=64 1=3 4=1 6=13824
GroupNorm Add_139 1 1 389 400 0=16 1=64 2=1.000000e-05
ReLU Relu_140 1 1 400 401
Convolution Conv_141 1 1 401 402 0=64 1=3 4=1 6=36864
GroupNorm Add_150 1 1 402 413 0=16 1=64 2=1.000000e-05
ReLU Relu_151 1 1 413 414
Split splitncnn_17 1 2 414 414_splitncnn_0 414_splitncnn_1
Convolution Conv_152 1 1 414_splitncnn_1 420 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_153 1 1 414_splitncnn_0 416 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_154 1 1 416 bbox_8 0=2 1=1 2=8.394209e-01
Sigmoid Sigmoid_158 1 1 420 score_8
Convolution Conv_162 1 1 387 425 0=64 1=3 4=1 6=13824
GroupNorm Add_171 1 1 425 436 0=16 1=64 2=1.000000e-05
ReLU Relu_172 1 1 436 437
Convolution Conv_173 1 1 437 438 0=64 1=3 4=1 6=36864
GroupNorm Add_182 1 1 438 449 0=16 1=64 2=1.000000e-05
ReLU Relu_183 1 1 449 450
Split splitncnn_18 1 2 450 450_splitncnn_0 450_splitncnn_1
Convolution Conv_184 1 1 450_splitncnn_1 456 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_185 1 1 450_splitncnn_0 452 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_186 1 1 452 bbox_16 0=2 1=1 2=1.251327e+00
Sigmoid Sigmoid_190 1 1 456 score_16
Convolution Conv_194 1 1 388 461 0=64 1=3 4=1 6=13824
GroupNorm Add_203 1 1 461 472 0=16 1=64 2=1.000000e-05
ReLU Relu_204 1 1 472 473
Convolution Conv_205 1 1 473 474 0=64 1=3 4=1 6=36864
GroupNorm Add_214 1 1 474 485 0=16 1=64 2=1.000000e-05
ReLU Relu_215 1 1 485 486
Split splitncnn_19 1 2 486 486_splitncnn_0 486_splitncnn_1
Convolution Conv_216 1 1 486_splitncnn_1 492 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_217 1 1 486_splitncnn_0 488 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_218 1 1 488 bbox_32 0=2 1=1 2=1.961941e+00
Sigmoid Sigmoid_222 1 1 492 score_32
================================================
FILE: app/src/main/assets/scrfd_2.5g_kps-opt2.param
================================================
7767517
120 145
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 273 0=12 1=3 3=2 4=1 5=1 6=324 9=1
Convolution Conv_2 1 1 273 276 0=12 1=3 4=1 5=1 6=1296 9=1
Convolution Conv_4 1 1 276 279 0=24 1=3 4=1 5=1 6=2592 9=1
Pooling MaxPool_6 1 1 279 280 1=2 2=2 5=1
Split splitncnn_0 1 2 280 280_splitncnn_0 280_splitncnn_1
Convolution Conv_7 1 1 280_splitncnn_1 283 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_9 1 1 283 505 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_10 2 1 505 280_splitncnn_0 286
ReLU Relu_11 1 1 286 287
Split splitncnn_1 1 2 287 287_splitncnn_0 287_splitncnn_1
Convolution Conv_12 1 1 287_splitncnn_1 290 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_14 1 1 290 511 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_15 2 1 511 287_splitncnn_0 293
ReLU Relu_16 1 1 293 294
Split splitncnn_2 1 2 294 294_splitncnn_0 294_splitncnn_1
Convolution Conv_17 1 1 294_splitncnn_1 297 0=24 1=3 4=1 5=1 6=5184 9=1
Convolution Conv_19 1 1 297 517 0=24 1=3 4=1 5=1 6=5184
BinaryOp Add_20 2 1 517 294_splitncnn_0 300
ReLU Relu_21 1 1 300 301
Split splitncnn_3 1 2 301 301_splitncnn_0 301_splitncnn_1
Convolution Conv_22 1 1 301_splitncnn_1 304 0=48 1=3 3=2 4=1 5=1 6=10368 9=1
Convolution Conv_24 1 1 304 523 0=48 1=3 4=1 5=1 6=20736
Pooling AveragePool_25 1 1 301_splitncnn_0 307 0=1 1=2 2=2
Convolution Conv_26 1 1 307 526 0=48 1=1 5=1 6=1152
BinaryOp Add_27 2 1 523 526 310
ReLU Relu_28 1 1 310 311
Split splitncnn_4 1 2 311 311_splitncnn_0 311_splitncnn_1
Convolution Conv_29 1 1 311_splitncnn_1 314 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_31 1 1 314 532 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_32 2 1 532 311_splitncnn_0 317
ReLU Relu_33 1 1 317 318
Split splitncnn_5 1 2 318 318_splitncnn_0 318_splitncnn_1
Convolution Conv_34 1 1 318_splitncnn_1 321 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_36 1 1 321 538 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_37 2 1 538 318_splitncnn_0 324
ReLU Relu_38 1 1 324 325
Split splitncnn_6 1 2 325 325_splitncnn_0 325_splitncnn_1
Convolution Conv_39 1 1 325_splitncnn_1 328 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_41 1 1 328 544 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_42 2 1 544 325_splitncnn_0 331
ReLU Relu_43 1 1 331 332
Split splitncnn_7 1 2 332 332_splitncnn_0 332_splitncnn_1
Convolution Conv_44 1 1 332_splitncnn_1 335 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_46 1 1 335 550 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_47 2 1 550 332_splitncnn_0 338
ReLU Relu_48 1 1 338 339
Split splitncnn_8 1 3 339 339_splitncnn_0 339_splitncnn_1 339_splitncnn_2
Convolution Conv_49 1 1 339_splitncnn_2 342 0=48 1=3 3=2 4=1 5=1 6=20736 9=1
Convolution Conv_51 1 1 342 556 0=48 1=3 4=1 5=1 6=20736
Pooling AveragePool_52 1 1 339_splitncnn_1 345 0=1 1=2 2=2
Convolution Conv_53 1 1 345 559 0=48 1=1 5=1 6=2304
BinaryOp Add_54 2 1 556 559 348
ReLU Relu_55 1 1 348 349
Split splitncnn_9 1 2 349 349_splitncnn_0 349_splitncnn_1
Convolution Conv_56 1 1 349_splitncnn_1 352 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_58 1 1 352 565 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_59 2 1 565 349_splitncnn_0 355
ReLU Relu_60 1 1 355 356
Split splitncnn_10 1 2 356 356_splitncnn_0 356_splitncnn_1
Convolution Conv_61 1 1 356_splitncnn_1 359 0=48 1=3 4=1 5=1 6=20736 9=1
Convolution Conv_63 1 1 359 571 0=48 1=3 4=1 5=1 6=20736
BinaryOp Add_64 2 1 571 356_splitncnn_0 362
ReLU Relu_65 1 1 362 363
Split splitncnn_11 1 3 363 363_splitncnn_0 363_splitncnn_1 363_splitncnn_2
Convolution Conv_66 1 1 363_splitncnn_2 366 0=80 1=3 3=2 4=1 5=1 6=34560 9=1
Convolution Conv_68 1 1 366 577 0=80 1=3 4=1 5=1 6=57600
Pooling AveragePool_69 1 1 363_splitncnn_1 369 0=1 1=2 2=2
Convolution Conv_70 1 1 369 580 0=80 1=1 5=1 6=3840
BinaryOp Add_71 2 1 577 580 372
ReLU Relu_72 1 1 372 373
Split splitncnn_12 1 2 373 373_splitncnn_0 373_splitncnn_1
Convolution Conv_73 1 1 373_splitncnn_1 376 0=80 1=3 4=1 5=1 6=57600 9=1
Convolution Conv_75 1 1 376 586 0=80 1=3 4=1 5=1 6=57600
BinaryOp Add_76 2 1 586 373_splitncnn_0 379
ReLU Relu_77 1 1 379 380
Convolution Conv_78 1 1 339_splitncnn_0 381 0=24 1=1 5=1 6=1152
Convolution Conv_79 1 1 363_splitncnn_0 382 0=24 1=1 5=1 6=1152
Convolution Conv_80 1 1 380 383 0=24 1=1 5=1 6=1920
Split splitncnn_13 1 2 383 383_splitncnn_0 383_splitncnn_1
Interp Resize_99 1 1 383_splitncnn_1 402 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_100 2 1 382 402 403
Split splitncnn_14 1 2 403 403_splitncnn_0 403_splitncnn_1
Interp Resize_119 1 1 403_splitncnn_1 422 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_120 2 1 381 422 423
Convolution Conv_121 1 1 423 424 0=24 1=3 4=1 5=1 6=5184
Split splitncnn_15 1 2 424 424_splitncnn_0 424_splitncnn_1
Convolution Conv_122 1 1 403_splitncnn_0 425 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_123 1 1 383_splitncnn_0 426 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_124 1 1 424_splitncnn_1 427 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_125 2 1 425 427 428
Split splitncnn_16 1 2 428 428_splitncnn_0 428_splitncnn_1
Convolution Conv_126 1 1 428_splitncnn_1 429 0=24 1=3 3=2 4=1 5=1 6=5184
BinaryOp Add_127 2 1 426 429 430
Convolution Conv_128 1 1 428_splitncnn_0 431 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_129 1 1 430 432 0=24 1=3 4=1 5=1 6=5184
Convolution Conv_130 1 1 424_splitncnn_0 435 0=64 1=3 4=1 5=1 6=13824 9=1
Convolution Conv_132 1 1 435 438 0=64 1=3 4=1 5=1 6=36864 9=1
Split splitncnn_17 1 3 438 438_splitncnn_0 438_splitncnn_1 438_splitncnn_2
Convolution Conv_134 1 1 438_splitncnn_2 445 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_135 1 1 438_splitncnn_1 440 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_136 1 1 440 bbox_8 0=2 1=1 2=8.807251e-01
Convolution Conv_137 1 1 438_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_141 1 1 445 score_8
Convolution Conv_148 1 1 431 455 0=64 1=3 4=1 5=1 6=13824 9=1
Convolution Conv_150 1 1 455 458 0=64 1=3 4=1 5=1 6=36864 9=1
Split splitncnn_18 1 3 458 458_splitncnn_0 458_splitncnn_1 458_splitncnn_2
Convolution Conv_152 1 1 458_splitncnn_2 465 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_153 1 1 458_splitncnn_1 460 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_154 1 1 460 bbox_16 0=2 1=1 2=9.315465e-01
Convolution Conv_155 1 1 458_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_159 1 1 465 score_16
Convolution Conv_166 1 1 432 475 0=64 1=3 4=1 5=1 6=13824 9=1
Convolution Conv_168 1 1 475 478 0=64 1=3 4=1 5=1 6=36864 9=1
Split splitncnn_19 1 3 478 478_splitncnn_0 478_splitncnn_1 478_splitncnn_2
Convolution Conv_170 1 1 478_splitncnn_2 485 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_171 1 1 478_splitncnn_1 480 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_172 1 1 480 bbox_32 0=2 1=1 2=1.142366e+00
Convolution Conv_173 1 1 478_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_177 1 1 485 score_32
================================================
FILE: app/src/main/assets/scrfd_34g-opt2.param
================================================
7767517
323 375
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 853 0=28 1=3 3=2 4=1 5=1 6=756 9=1
Convolution Conv_2 1 1 853 856 0=28 1=3 4=1 5=1 6=7056 9=1
Convolution Conv_4 1 1 856 859 0=56 1=3 4=1 5=1 6=14112 9=1
Pooling MaxPool_6 1 1 859 860 1=2 2=2 5=1
Split splitncnn_0 1 2 860 869 860_splitncnn_1
Convolution Conv_7 1 1 860_splitncnn_1 863 0=56 1=1 5=1 6=3136 9=1
Convolution Conv_9 1 1 863 866 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_11 1 1 866 1478 0=224 1=1 5=1 6=12544
Convolution Conv_13 1 1 869 1481 0=224 1=1 5=1 6=12544
BinaryOp Add_14 2 1 1478 1481 872
ReLU Relu_15 1 1 872 873
Split splitncnn_1 1 2 873 873_splitncnn_0 873_splitncnn_1
Convolution Conv_16 1 1 873_splitncnn_1 876 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_18 1 1 876 879 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_20 1 1 879 1490 0=224 1=1 5=1 6=12544
BinaryOp Add_21 2 1 1490 873_splitncnn_0 882
ReLU Relu_22 1 1 882 883
Split splitncnn_2 1 2 883 883_splitncnn_0 883_splitncnn_1
Convolution Conv_23 1 1 883_splitncnn_1 886 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_25 1 1 886 889 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_27 1 1 889 1499 0=224 1=1 5=1 6=12544
BinaryOp Add_28 2 1 1499 883_splitncnn_0 892
ReLU Relu_29 1 1 892 893
Split splitncnn_3 1 2 893 893_splitncnn_0 893_splitncnn_1
Convolution Conv_30 1 1 893_splitncnn_1 896 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_32 1 1 896 899 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_34 1 1 899 1508 0=224 1=1 5=1 6=12544
BinaryOp Add_35 2 1 1508 893_splitncnn_0 902
ReLU Relu_36 1 1 902 903
Split splitncnn_4 1 2 903 903_splitncnn_0 903_splitncnn_1
Convolution Conv_37 1 1 903_splitncnn_1 906 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_39 1 1 906 909 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_41 1 1 909 1517 0=224 1=1 5=1 6=12544
BinaryOp Add_42 2 1 1517 903_splitncnn_0 912
ReLU Relu_43 1 1 912 913
Split splitncnn_5 1 2 913 913_splitncnn_0 913_splitncnn_1
Convolution Conv_44 1 1 913_splitncnn_1 916 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_46 1 1 916 919 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_48 1 1 919 1526 0=224 1=1 5=1 6=12544
BinaryOp Add_49 2 1 1526 913_splitncnn_0 922
ReLU Relu_50 1 1 922 923
Split splitncnn_6 1 2 923 923_splitncnn_0 923_splitncnn_1
Convolution Conv_51 1 1 923_splitncnn_1 926 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_53 1 1 926 929 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_55 1 1 929 1535 0=224 1=1 5=1 6=12544
BinaryOp Add_56 2 1 1535 923_splitncnn_0 932
ReLU Relu_57 1 1 932 933
Split splitncnn_7 1 2 933 933_splitncnn_0 933_splitncnn_1
Convolution Conv_58 1 1 933_splitncnn_1 936 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_60 1 1 936 939 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_62 1 1 939 1544 0=224 1=1 5=1 6=12544
BinaryOp Add_63 2 1 1544 933_splitncnn_0 942
ReLU Relu_64 1 1 942 943
Split splitncnn_8 1 2 943 943_splitncnn_0 943_splitncnn_1
Convolution Conv_65 1 1 943_splitncnn_1 946 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_67 1 1 946 949 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_69 1 1 949 1553 0=224 1=1 5=1 6=12544
BinaryOp Add_70 2 1 1553 943_splitncnn_0 952
ReLU Relu_71 1 1 952 953
Split splitncnn_9 1 2 953 953_splitncnn_0 953_splitncnn_1
Convolution Conv_72 1 1 953_splitncnn_1 956 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_74 1 1 956 959 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_76 1 1 959 1562 0=224 1=1 5=1 6=12544
BinaryOp Add_77 2 1 1562 953_splitncnn_0 962
ReLU Relu_78 1 1 962 963
Split splitncnn_10 1 2 963 963_splitncnn_0 963_splitncnn_1
Convolution Conv_79 1 1 963_splitncnn_1 966 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_81 1 1 966 969 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_83 1 1 969 1571 0=224 1=1 5=1 6=12544
BinaryOp Add_84 2 1 1571 963_splitncnn_0 972
ReLU Relu_85 1 1 972 973
Split splitncnn_11 1 2 973 973_splitncnn_0 973_splitncnn_1
Convolution Conv_86 1 1 973_splitncnn_1 976 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_88 1 1 976 979 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_90 1 1 979 1580 0=224 1=1 5=1 6=12544
BinaryOp Add_91 2 1 1580 973_splitncnn_0 982
ReLU Relu_92 1 1 982 983
Split splitncnn_12 1 2 983 983_splitncnn_0 983_splitncnn_1
Convolution Conv_93 1 1 983_splitncnn_1 986 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_95 1 1 986 989 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_97 1 1 989 1589 0=224 1=1 5=1 6=12544
BinaryOp Add_98 2 1 1589 983_splitncnn_0 992
ReLU Relu_99 1 1 992 993
Split splitncnn_13 1 2 993 993_splitncnn_0 993_splitncnn_1
Convolution Conv_100 1 1 993_splitncnn_1 996 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_102 1 1 996 999 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_104 1 1 999 1598 0=224 1=1 5=1 6=12544
BinaryOp Add_105 2 1 1598 993_splitncnn_0 1002
ReLU Relu_106 1 1 1002 1003
Split splitncnn_14 1 2 1003 1003_splitncnn_0 1003_splitncnn_1
Convolution Conv_107 1 1 1003_splitncnn_1 1006 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_109 1 1 1006 1009 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_111 1 1 1009 1607 0=224 1=1 5=1 6=12544
BinaryOp Add_112 2 1 1607 1003_splitncnn_0 1012
ReLU Relu_113 1 1 1012 1013
Split splitncnn_15 1 2 1013 1013_splitncnn_0 1013_splitncnn_1
Convolution Conv_114 1 1 1013_splitncnn_1 1016 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_116 1 1 1016 1019 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_118 1 1 1019 1616 0=224 1=1 5=1 6=12544
BinaryOp Add_119 2 1 1616 1013_splitncnn_0 1022
ReLU Relu_120 1 1 1022 1023
Split splitncnn_16 1 2 1023 1023_splitncnn_0 1023_splitncnn_1
Convolution Conv_121 1 1 1023_splitncnn_1 1026 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_123 1 1 1026 1029 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_125 1 1 1029 1625 0=224 1=1 5=1 6=12544
BinaryOp Add_126 2 1 1625 1023_splitncnn_0 1032
ReLU Relu_127 1 1 1032 1033
Split splitncnn_17 1 2 1033 1033_splitncnn_0 1033_splitncnn_1
Convolution Conv_128 1 1 1033_splitncnn_1 1036 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_130 1 1 1036 1039 0=56 1=3 3=2 4=1 5=1 6=28224 9=1
Convolution Conv_132 1 1 1039 1634 0=224 1=1 5=1 6=12544
Pooling AveragePool_133 1 1 1033_splitncnn_0 1042 0=1 1=2 2=2
Convolution Conv_134 1 1 1042 1637 0=224 1=1 5=1 6=50176
BinaryOp Add_135 2 1 1634 1637 1045
ReLU Relu_136 1 1 1045 1046
Split splitncnn_18 1 2 1046 1046_splitncnn_0 1046_splitncnn_1
Convolution Conv_137 1 1 1046_splitncnn_1 1049 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_139 1 1 1049 1052 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_141 1 1 1052 1646 0=224 1=1 5=1 6=12544
BinaryOp Add_142 2 1 1646 1046_splitncnn_0 1055
ReLU Relu_143 1 1 1055 1056
Split splitncnn_19 1 2 1056 1056_splitncnn_0 1056_splitncnn_1
Convolution Conv_144 1 1 1056_splitncnn_1 1059 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_146 1 1 1059 1062 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_148 1 1 1062 1655 0=224 1=1 5=1 6=12544
BinaryOp Add_149 2 1 1655 1056_splitncnn_0 1065
ReLU Relu_150 1 1 1065 1066
Split splitncnn_20 1 2 1066 1066_splitncnn_0 1066_splitncnn_1
Convolution Conv_151 1 1 1066_splitncnn_1 1069 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_153 1 1 1069 1072 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_155 1 1 1072 1664 0=224 1=1 5=1 6=12544
BinaryOp Add_156 2 1 1664 1066_splitncnn_0 1075
ReLU Relu_157 1 1 1075 1076
Split splitncnn_21 1 2 1076 1076_splitncnn_0 1076_splitncnn_1
Convolution Conv_158 1 1 1076_splitncnn_1 1079 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_160 1 1 1079 1082 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_162 1 1 1082 1673 0=224 1=1 5=1 6=12544
BinaryOp Add_163 2 1 1673 1076_splitncnn_0 1085
ReLU Relu_164 1 1 1085 1086
Split splitncnn_22 1 2 1086 1086_splitncnn_0 1086_splitncnn_1
Convolution Conv_165 1 1 1086_splitncnn_1 1089 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_167 1 1 1089 1092 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_169 1 1 1092 1682 0=224 1=1 5=1 6=12544
BinaryOp Add_170 2 1 1682 1086_splitncnn_0 1095
ReLU Relu_171 1 1 1095 1096
Split splitncnn_23 1 2 1096 1096_splitncnn_0 1096_splitncnn_1
Convolution Conv_172 1 1 1096_splitncnn_1 1099 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_174 1 1 1099 1102 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_176 1 1 1102 1691 0=224 1=1 5=1 6=12544
BinaryOp Add_177 2 1 1691 1096_splitncnn_0 1105
ReLU Relu_178 1 1 1105 1106
Split splitncnn_24 1 2 1106 1106_splitncnn_0 1106_splitncnn_1
Convolution Conv_179 1 1 1106_splitncnn_1 1109 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_181 1 1 1109 1112 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_183 1 1 1112 1700 0=224 1=1 5=1 6=12544
BinaryOp Add_184 2 1 1700 1106_splitncnn_0 1115
ReLU Relu_185 1 1 1115 1116
Split splitncnn_25 1 2 1116 1116_splitncnn_0 1116_splitncnn_1
Convolution Conv_186 1 1 1116_splitncnn_1 1119 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_188 1 1 1119 1122 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_190 1 1 1122 1709 0=224 1=1 5=1 6=12544
BinaryOp Add_191 2 1 1709 1116_splitncnn_0 1125
ReLU Relu_192 1 1 1125 1126
Split splitncnn_26 1 2 1126 1126_splitncnn_0 1126_splitncnn_1
Convolution Conv_193 1 1 1126_splitncnn_1 1129 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_195 1 1 1129 1132 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_197 1 1 1132 1718 0=224 1=1 5=1 6=12544
BinaryOp Add_198 2 1 1718 1126_splitncnn_0 1135
ReLU Relu_199 1 1 1135 1136
Split splitncnn_27 1 2 1136 1136_splitncnn_0 1136_splitncnn_1
Convolution Conv_200 1 1 1136_splitncnn_1 1139 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_202 1 1 1139 1142 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_204 1 1 1142 1727 0=224 1=1 5=1 6=12544
BinaryOp Add_205 2 1 1727 1136_splitncnn_0 1145
ReLU Relu_206 1 1 1145 1146
Split splitncnn_28 1 2 1146 1146_splitncnn_0 1146_splitncnn_1
Convolution Conv_207 1 1 1146_splitncnn_1 1149 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_209 1 1 1149 1152 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_211 1 1 1152 1736 0=224 1=1 5=1 6=12544
BinaryOp Add_212 2 1 1736 1146_splitncnn_0 1155
ReLU Relu_213 1 1 1155 1156
Split splitncnn_29 1 2 1156 1156_splitncnn_0 1156_splitncnn_1
Convolution Conv_214 1 1 1156_splitncnn_1 1159 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_216 1 1 1159 1162 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_218 1 1 1162 1745 0=224 1=1 5=1 6=12544
BinaryOp Add_219 2 1 1745 1156_splitncnn_0 1165
ReLU Relu_220 1 1 1165 1166
Split splitncnn_30 1 2 1166 1166_splitncnn_0 1166_splitncnn_1
Convolution Conv_221 1 1 1166_splitncnn_1 1169 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_223 1 1 1169 1172 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_225 1 1 1172 1754 0=224 1=1 5=1 6=12544
BinaryOp Add_226 2 1 1754 1166_splitncnn_0 1175
ReLU Relu_227 1 1 1175 1176
Split splitncnn_31 1 2 1176 1176_splitncnn_0 1176_splitncnn_1
Convolution Conv_228 1 1 1176_splitncnn_1 1179 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_230 1 1 1179 1182 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_232 1 1 1182 1763 0=224 1=1 5=1 6=12544
BinaryOp Add_233 2 1 1763 1176_splitncnn_0 1185
ReLU Relu_234 1 1 1185 1186
Split splitncnn_32 1 2 1186 1186_splitncnn_0 1186_splitncnn_1
Convolution Conv_235 1 1 1186_splitncnn_1 1189 0=56 1=1 5=1 6=12544 9=1
Convolution Conv_237 1 1 1189 1192 0=56 1=3 4=1 5=1 6=28224 9=1
Convolution Conv_239 1 1 1192 1772 0=224 1=1 5=1 6=12544
BinaryOp Add_240 2 1 1772 1186_splitncnn_0 1195
ReLU Relu_241 1 1 1195 1196
Split splitncnn_33 1 3 1196 1196_splitncnn_0 1196_splitncnn_1 1196_splitncnn_2
Convolution Conv_242 1 1 1196_splitncnn_2 1199 0=144 1=1 5=1 6=32256 9=1
Convolution Conv_244 1 1 1199 1202 0=144 1=3 3=2 4=1 5=1 6=186624 9=1
Convolution Conv_246 1 1 1202 1781 0=576 1=1 5=1 6=82944
Pooling AveragePool_247 1 1 1196_splitncnn_1 1205 0=1 1=2 2=2
Convolution Conv_248 1 1 1205 1784 0=576 1=1 5=1 6=129024
BinaryOp Add_249 2 1 1781 1784 1208
ReLU Relu_250 1 1 1208 1209
Split splitncnn_34 1 2 1209 1209_splitncnn_0 1209_splitncnn_1
Convolution Conv_251 1 1 1209_splitncnn_1 1212 0=144 1=1 5=1 6=82944 9=1
Convolution Conv_253 1 1 1212 1215 0=144 1=3 4=1 5=1 6=186624 9=1
Convolution Conv_255 1 1 1215 1793 0=576 1=1 5=1 6=82944
BinaryOp Add_256 2 1 1793 1209_splitncnn_0 1218
ReLU Relu_257 1 1 1218 1219
Split splitncnn_35 1 3 1219 1219_splitncnn_0 1219_splitncnn_1 1219_splitncnn_2
Convolution Conv_258 1 1 1219_splitncnn_2 1222 0=184 1=1 5=1 6=105984 9=1
Convolution Conv_260 1 1 1222 1225 0=184 1=3 3=2 4=1 5=1 6=304704 9=1
Convolution Conv_262 1 1 1225 1802 0=736 1=1 5=1 6=135424
Pooling AveragePool_263 1 1 1219_splitncnn_1 1228 0=1 1=2 2=2
Convolution Conv_264 1 1 1228 1805 0=736 1=1 5=1 6=423936
BinaryOp Add_265 2 1 1802 1805 1231
ReLU Relu_266 1 1 1231 1232
Split splitncnn_36 1 2 1232 1232_splitncnn_0 1232_splitncnn_1
Convolution Conv_267 1 1 1232_splitncnn_1 1235 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_269 1 1 1235 1238 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_271 1 1 1238 1814 0=736 1=1 5=1 6=135424
BinaryOp Add_272 2 1 1814 1232_splitncnn_0 1241
ReLU Relu_273 1 1 1241 1242
Split splitncnn_37 1 2 1242 1242_splitncnn_0 1242_splitncnn_1
Convolution Conv_274 1 1 1242_splitncnn_1 1245 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_276 1 1 1245 1248 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_278 1 1 1248 1823 0=736 1=1 5=1 6=135424
BinaryOp Add_279 2 1 1823 1242_splitncnn_0 1251
ReLU Relu_280 1 1 1251 1252
Split splitncnn_38 1 2 1252 1252_splitncnn_0 1252_splitncnn_1
Convolution Conv_281 1 1 1252_splitncnn_1 1255 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_283 1 1 1255 1258 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_285 1 1 1258 1832 0=736 1=1 5=1 6=135424
BinaryOp Add_286 2 1 1832 1252_splitncnn_0 1261
ReLU Relu_287 1 1 1261 1262
Split splitncnn_39 1 2 1262 1262_splitncnn_0 1262_splitncnn_1
Convolution Conv_288 1 1 1262_splitncnn_1 1265 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_290 1 1 1265 1268 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_292 1 1 1268 1841 0=736 1=1 5=1 6=135424
BinaryOp Add_293 2 1 1841 1262_splitncnn_0 1271
ReLU Relu_294 1 1 1271 1272
Split splitncnn_40 1 2 1272 1272_splitncnn_0 1272_splitncnn_1
Convolution Conv_295 1 1 1272_splitncnn_1 1275 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_297 1 1 1275 1278 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_299 1 1 1278 1850 0=736 1=1 5=1 6=135424
BinaryOp Add_300 2 1 1850 1272_splitncnn_0 1281
ReLU Relu_301 1 1 1281 1282
Split splitncnn_41 1 2 1282 1282_splitncnn_0 1282_splitncnn_1
Convolution Conv_302 1 1 1282_splitncnn_1 1285 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_304 1 1 1285 1288 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_306 1 1 1288 1859 0=736 1=1 5=1 6=135424
BinaryOp Add_307 2 1 1859 1282_splitncnn_0 1291
ReLU Relu_308 1 1 1291 1292
Split splitncnn_42 1 2 1292 1292_splitncnn_0 1292_splitncnn_1
Convolution Conv_309 1 1 1292_splitncnn_1 1295 0=184 1=1 5=1 6=135424 9=1
Convolution Conv_311 1 1 1295 1298 0=184 1=3 4=1 5=1 6=304704 9=1
Convolution Conv_313 1 1 1298 1868 0=736 1=1 5=1 6=135424
BinaryOp Add_314 2 1 1868 1292_splitncnn_0 1301
ReLU Relu_315 1 1 1301 1302
Convolution Conv_316 1 1 1196_splitncnn_0 1303 0=128 1=1 5=1 6=28672
Convolution Conv_317 1 1 1219_splitncnn_0 1304 0=128 1=1 5=1 6=73728
Convolution Conv_318 1 1 1302 1305 0=128 1=1 5=1 6=94208
Split splitncnn_43 1 2 1305 1305_splitncnn_0 1305_splitncnn_1
Interp Resize_337 1 1 1305_splitncnn_1 1324 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_338 2 1 1304 1324 1325
Split splitncnn_44 1 2 1325 1325_splitncnn_0 1325_splitncnn_1
Interp Resize_357 1 1 1325_splitncnn_1 1344 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_358 2 1 1303 1344 1345
Convolution Conv_359 1 1 1345 1346 0=128 1=3 4=1 5=1 6=147456
Split splitncnn_45 1 2 1346 1346_splitncnn_0 1346_splitncnn_1
Convolution Conv_360 1 1 1325_splitncnn_0 1347 0=128 1=3 4=1 5=1 6=147456
Convolution Conv_361 1 1 1305_splitncnn_0 1348 0=128 1=3 4=1 5=1 6=147456
Convolution Conv_362 1 1 1346_splitncnn_1 1349 0=128 1=3 3=2 4=1 5=1 6=147456
BinaryOp Add_363 2 1 1347 1349 1350
Split splitncnn_46 1 2 1350 1350_splitncnn_0 1350_splitncnn_1
Convolution Conv_364 1 1 1350_splitncnn_1 1351 0=128 1=3 3=2 4=1 5=1 6=147456
BinaryOp Add_365 2 1 1348 1351 1352
Convolution Conv_366 1 1 1350_splitncnn_0 1353 0=128 1=3 4=1 5=1 6=147456
Convolution Conv_367 1 1 1352 1354 0=128 1=3 4=1 5=1 6=147456
Convolution Conv_368 1 1 1346_splitncnn_0 1355 0=256 1=3 4=1 6=294912
GroupNorm Add_377 1 1 1355 1366 0=32 1=256 2=1.000000e-05
ReLU Relu_378 1 1 1366 1367
Convolution Conv_379 1 1 1367 1368 0=256 1=3 4=1 6=589824
GroupNorm Add_388 1 1 1368 1379 0=32 1=256 2=1.000000e-05
ReLU Relu_389 1 1 1379 1380
Split splitncnn_47 1 2 1380 1380_splitncnn_0 1380_splitncnn_1
Convolution Conv_390 1 1 1380_splitncnn_1 1386 0=2 1=3 4=1 5=1 6=4608
Convolution Conv_391 1 1 1380_splitncnn_0 1382 0=8 1=3 4=1 5=1 6=18432
BinaryOp Mul_392 1 1 1382 bbox_8 0=2 1=1 2=9.446464e-01
Sigmoid Sigmoid_396 1 1 1386 score_8
Convolution Conv_400 1 1 1353 1391 0=256 1=3 4=1 6=294912
GroupNorm Add_409 1 1 1391 1402 0=32 1=256 2=1.000000e-05
ReLU Relu_410 1 1 1402 1403
Convolution Conv_411 1 1 1403 1404 0=256 1=3 4=1 6=589824
GroupNorm Add_420 1 1 1404 1415 0=32 1=256 2=1.000000e-05
ReLU Relu_421 1 1 1415 1416
Split splitncnn_48 1 2 1416 1416_splitncnn_0 1416_splitncnn_1
Convolution Conv_422 1 1 1416_splitncnn_1 1422 0=2 1=3 4=1 5=1 6=4608
Convolution Conv_423 1 1 1416_splitncnn_0 1418 0=8 1=3 4=1 5=1 6=18432
BinaryOp Mul_424 1 1 1418 bbox_16 0=2 1=1 2=1.461800e+00
Sigmoid Sigmoid_428 1 1 1422 score_16
Convolution Conv_432 1 1 1354 1427 0=256 1=3 4=1 6=294912
GroupNorm Add_441 1 1 1427 1438 0=32 1=256 2=1.000000e-05
ReLU Relu_442 1 1 1438 1439
Convolution Conv_443 1 1 1439 1440 0=256 1=3 4=1 6=589824
GroupNorm Add_452 1 1 1440 1451 0=32 1=256 2=1.000000e-05
ReLU Relu_453 1 1 1451 1452
Split splitncnn_49 1 2 1452 1452_splitncnn_0 1452_splitncnn_1
Convolution Conv_454 1 1 1452_splitncnn_1 1458 0=2 1=3 4=1 5=1 6=4608
Convolution Conv_455 1 1 1452_splitncnn_0 1454 0=8 1=3 4=1 5=1 6=18432
BinaryOp Mul_456 1 1 1454 bbox_32 0=2 1=1 2=1.589572e+00
Sigmoid Sigmoid_460 1 1 1458 score_32
================================================
FILE: app/src/main/assets/scrfd_500m-opt2.param
================================================
7767517
103 112
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 217 0=16 1=3 3=2 4=1 5=1 6=432 9=1
ConvolutionDepthWise Conv_2 1 1 217 220 0=16 1=3 4=1 5=1 6=144 7=16 9=1
Convolution Conv_4 1 1 220 223 0=16 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_6 1 1 223 226 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1
Convolution Conv_8 1 1 226 229 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_10 1 1 229 232 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution Conv_12 1 1 232 235 0=40 1=1 5=1 6=1600 9=1
ConvolutionDepthWise Conv_14 1 1 235 238 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1
Convolution Conv_16 1 1 238 241 0=72 1=1 5=1 6=2880 9=1
ConvolutionDepthWise Conv_18 1 1 241 244 0=72 1=3 4=1 5=1 6=648 7=72 9=1
Convolution Conv_20 1 1 244 247 0=72 1=1 5=1 6=5184 9=1
ConvolutionDepthWise Conv_22 1 1 247 250 0=72 1=3 4=1 5=1 6=648 7=72 9=1
Convolution Conv_24 1 1 250 253 0=72 1=1 5=1 6=5184 9=1
Split splitncnn_0 1 2 253 253_splitncnn_0 253_splitncnn_1
ConvolutionDepthWise Conv_26 1 1 253_splitncnn_1 256 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1
Convolution Conv_28 1 1 256 259 0=152 1=1 5=1 6=10944 9=1
ConvolutionDepthWise Conv_30 1 1 259 262 0=152 1=3 4=1 5=1 6=1368 7=152 9=1
Convolution Conv_32 1 1 262 265 0=152 1=1 5=1 6=23104 9=1
Split splitncnn_1 1 2 265 265_splitncnn_0 265_splitncnn_1
ConvolutionDepthWise Conv_34 1 1 265_splitncnn_1 268 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1
Convolution Conv_36 1 1 268 271 0=288 1=1 5=1 6=43776 9=1
ConvolutionDepthWise Conv_38 1 1 271 274 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_40 1 1 274 277 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_42 1 1 277 280 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_44 1 1 280 283 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_46 1 1 283 286 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_48 1 1 286 289 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_50 1 1 289 292 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_52 1 1 292 295 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_54 1 1 295 298 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_56 1 1 298 301 0=288 1=1 5=1 6=82944 9=1
Convolution Conv_58 1 1 253_splitncnn_0 302 0=16 1=1 5=1 6=1152
Convolution Conv_59 1 1 265_splitncnn_0 303 0=16 1=1 5=1 6=2432
Convolution Conv_60 1 1 301 304 0=16 1=1 5=1 6=4608
Split splitncnn_2 1 2 304 304_splitncnn_0 304_splitncnn_1
Interp Resize_79 1 1 304_splitncnn_1 323 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_80 2 1 303 323 324
Split splitncnn_3 1 2 324 324_splitncnn_0 324_splitncnn_1
Interp Resize_99 1 1 324_splitncnn_1 343 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_100 2 1 302 343 344
Convolution Conv_101 1 1 344 345 0=16 1=3 4=1 5=1 6=2304
Split splitncnn_4 1 2 345 345_splitncnn_0 345_splitncnn_1
Convolution Conv_102 1 1 324_splitncnn_0 346 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_103 1 1 304_splitncnn_0 347 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_104 1 1 345_splitncnn_1 348 0=16 1=3 3=2 4=1 5=1 6=2304
BinaryOp Add_105 2 1 346 348 349
Split splitncnn_5 1 2 349 349_splitncnn_0 349_splitncnn_1
Convolution Conv_106 1 1 349_splitncnn_1 350 0=16 1=3 3=2 4=1 5=1 6=2304
BinaryOp Add_107 2 1 347 350 351
Convolution Conv_108 1 1 349_splitncnn_0 352 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_109 1 1 351 353 0=16 1=3 4=1 5=1 6=2304
ConvolutionDepthWise Conv_110 1 1 345_splitncnn_0 354 0=16 1=3 4=1 6=144 7=16
GroupNorm Add_119 1 1 354 365 0=16 1=16 2=1.000000e-05
ReLU Relu_120 1 1 365 366
Convolution Conv_121 1 1 366 367 0=64 1=1 6=1024
GroupNorm Add_130 1 1 367 378 0=16 1=64 2=1.000000e-05
ReLU Relu_131 1 1 378 379
ConvolutionDepthWise Conv_132 1 1 379 380 0=64 1=3 4=1 6=576 7=64
GroupNorm Add_141 1 1 380 391 0=16 1=64 2=1.000000e-05
ReLU Relu_142 1 1 391 392
Convolution Conv_143 1 1 392 393 0=64 1=1 6=4096
GroupNorm Add_152 1 1 393 404 0=16 1=64 2=1.000000e-05
ReLU Relu_153 1 1 404 405
Split splitncnn_6 1 2 405 405_splitncnn_0 405_splitncnn_1
Convolution Conv_154 1 1 405_splitncnn_1 411 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_155 1 1 405_splitncnn_0 407 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_156 1 1 407 bbox_8 0=2 1=1 2=7.957783e-01
Sigmoid Sigmoid_160 1 1 411 score_8
ConvolutionDepthWise Conv_164 1 1 352 416 0=16 1=3 4=1 6=144 7=16
GroupNorm Add_173 1 1 416 427 0=16 1=16 2=1.000000e-05
ReLU Relu_174 1 1 427 428
Convolution Conv_175 1 1 428 429 0=64 1=1 6=1024
GroupNorm Add_184 1 1 429 440 0=16 1=64 2=1.000000e-05
ReLU Relu_185 1 1 440 441
ConvolutionDepthWise Conv_186 1 1 441 442 0=64 1=3 4=1 6=576 7=64
GroupNorm Add_195 1 1 442 453 0=16 1=64 2=1.000000e-05
ReLU Relu_196 1 1 453 454
Convolution Conv_197 1 1 454 455 0=64 1=1 6=4096
GroupNorm Add_206 1 1 455 466 0=16 1=64 2=1.000000e-05
ReLU Relu_207 1 1 466 467
Split splitncnn_7 1 2 467 467_splitncnn_0 467_splitncnn_1
Convolution Conv_208 1 1 467_splitncnn_1 473 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_209 1 1 467_splitncnn_0 469 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_210 1 1 469 bbox_16 0=2 1=1 2=1.201926e+00
Sigmoid Sigmoid_214 1 1 473 score_16
ConvolutionDepthWise Conv_218 1 1 353 478 0=16 1=3 4=1 6=144 7=16
GroupNorm Add_227 1 1 478 489 0=16 1=16 2=1.000000e-05
ReLU Relu_228 1 1 489 490
Convolution Conv_229 1 1 490 491 0=64 1=1 6=1024
GroupNorm Add_238 1 1 491 502 0=16 1=64 2=1.000000e-05
ReLU Relu_239 1 1 502 503
ConvolutionDepthWise Conv_240 1 1 503 504 0=64 1=3 4=1 6=576 7=64
GroupNorm Add_249 1 1 504 515 0=16 1=64 2=1.000000e-05
ReLU Relu_250 1 1 515 516
Convolution Conv_251 1 1 516 517 0=64 1=1 6=4096
GroupNorm Add_260 1 1 517 528 0=16 1=64 2=1.000000e-05
ReLU Relu_261 1 1 528 529
Split splitncnn_8 1 2 529 529_splitncnn_0 529_splitncnn_1
Convolution Conv_262 1 1 529_splitncnn_1 535 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_263 1 1 529_splitncnn_0 531 0=8 1=3 4=1 5=1 6=4608
BinaryOp Mul_264 1 1 531 bbox_32 0=2 1=1 2=1.992024e+00
Sigmoid Sigmoid_268 1 1 535 score_32
================================================
FILE: app/src/main/assets/scrfd_500m_kps-opt2.param
================================================
7767517
79 91
Input input.1 0 1 input.1
Convolution Conv_0 1 1 input.1 288 0=16 1=3 3=2 4=1 5=1 6=432 9=1
ConvolutionDepthWise Conv_3 1 1 288 291 0=16 1=3 4=1 5=1 6=144 7=16 9=1
Convolution Conv_6 1 1 291 294 0=16 1=1 5=1 6=256 9=1
ConvolutionDepthWise Conv_9 1 1 294 297 0=16 1=3 3=2 4=1 5=1 6=144 7=16 9=1
Convolution Conv_12 1 1 297 300 0=40 1=1 5=1 6=640 9=1
ConvolutionDepthWise Conv_15 1 1 300 303 0=40 1=3 4=1 5=1 6=360 7=40 9=1
Convolution Conv_18 1 1 303 306 0=40 1=1 5=1 6=1600 9=1
ConvolutionDepthWise Conv_21 1 1 306 309 0=40 1=3 3=2 4=1 5=1 6=360 7=40 9=1
Convolution Conv_24 1 1 309 312 0=72 1=1 5=1 6=2880 9=1
ConvolutionDepthWise Conv_27 1 1 312 315 0=72 1=3 4=1 5=1 6=648 7=72 9=1
Convolution Conv_30 1 1 315 318 0=72 1=1 5=1 6=5184 9=1
ConvolutionDepthWise Conv_33 1 1 318 321 0=72 1=3 4=1 5=1 6=648 7=72 9=1
Convolution Conv_36 1 1 321 324 0=72 1=1 5=1 6=5184 9=1
Split splitncnn_0 1 2 324 324_splitncnn_0 324_splitncnn_1
ConvolutionDepthWise Conv_39 1 1 324_splitncnn_1 327 0=72 1=3 3=2 4=1 5=1 6=648 7=72 9=1
Convolution Conv_42 1 1 327 330 0=152 1=1 5=1 6=10944 9=1
ConvolutionDepthWise Conv_45 1 1 330 333 0=152 1=3 4=1 5=1 6=1368 7=152 9=1
Convolution Conv_48 1 1 333 336 0=152 1=1 5=1 6=23104 9=1
Split splitncnn_1 1 2 336 336_splitncnn_0 336_splitncnn_1
ConvolutionDepthWise Conv_51 1 1 336_splitncnn_1 339 0=152 1=3 3=2 4=1 5=1 6=1368 7=152 9=1
Convolution Conv_54 1 1 339 342 0=288 1=1 5=1 6=43776 9=1
ConvolutionDepthWise Conv_57 1 1 342 345 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_60 1 1 345 348 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_63 1 1 348 351 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_66 1 1 351 354 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_69 1 1 354 357 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_72 1 1 357 360 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_75 1 1 360 363 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_78 1 1 363 366 0=288 1=1 5=1 6=82944 9=1
ConvolutionDepthWise Conv_81 1 1 366 369 0=288 1=3 4=1 5=1 6=2592 7=288 9=1
Convolution Conv_84 1 1 369 372 0=288 1=1 5=1 6=82944 9=1
Convolution Conv_87 1 1 324_splitncnn_0 373 0=16 1=1 5=1 6=1152
Convolution Conv_88 1 1 336_splitncnn_0 374 0=16 1=1 5=1 6=2432
Convolution Conv_89 1 1 372 375 0=16 1=1 5=1 6=4608
Split splitncnn_2 1 2 375 375_splitncnn_0 375_splitncnn_1
Interp Resize_108 1 1 375_splitncnn_1 394 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_109 2 1 374 394 395
Split splitncnn_3 1 2 395 395_splitncnn_0 395_splitncnn_1
Interp Resize_128 1 1 395_splitncnn_1 414 0=1 1=2.000000e+00 2=2.000000e+00
BinaryOp Add_129 2 1 373 414 415
Convolution Conv_130 1 1 415 416 0=16 1=3 4=1 5=1 6=2304
Split splitncnn_4 1 2 416 416_splitncnn_0 416_splitncnn_1
Convolution Conv_131 1 1 395_splitncnn_0 417 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_132 1 1 375_splitncnn_0 418 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_133 1 1 416_splitncnn_1 419 0=16 1=3 3=2 4=1 5=1 6=2304
BinaryOp Add_134 2 1 417 419 420
Split splitncnn_5 1 2 420 420_splitncnn_0 420_splitncnn_1
Convolution Conv_135 1 1 420_splitncnn_1 421 0=16 1=3 3=2 4=1 5=1 6=2304
BinaryOp Add_136 2 1 418 421 422
Convolution Conv_137 1 1 420_splitncnn_0 423 0=16 1=3 4=1 5=1 6=2304
Convolution Conv_138 1 1 422 424 0=16 1=3 4=1 5=1 6=2304
ConvolutionDepthWise Conv_139 1 1 416_splitncnn_0 427 0=16 1=3 4=1 5=1 6=144 7=16 9=1
Convolution Conv_142 1 1 427 430 0=64 1=1 5=1 6=1024 9=1
ConvolutionDepthWise Conv_145 1 1 430 433 0=64 1=3 4=1 5=1 6=576 7=64 9=1
Convolution Conv_148 1 1 433 436 0=64 1=1 5=1 6=4096 9=1
Split splitncnn_6 1 3 436 436_splitncnn_0 436_splitncnn_1 436_splitncnn_2
Convolution Conv_151 1 1 436_splitncnn_2 442 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_152 1 1 436_splitncnn_1 bbox_8 0=8 1=3 4=1 5=1 6=4608
Convolution Conv_153 1 1 436_splitncnn_0 kps_8 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_157 1 1 442 score_8
ConvolutionDepthWise Conv_164 1 1 423 452 0=16 1=3 4=1 5=1 6=144 7=16 9=1
Convolution Conv_167 1 1 452 455 0=64 1=1 5=1 6=1024 9=1
ConvolutionDepthWise Conv_170 1 1 455 458 0=64 1=3 4=1 5=1 6=576 7=64 9=1
Convolution Conv_173 1 1 458 461 0=64 1=1 5=1 6=4096 9=1
Split splitncnn_7 1 3 461 461_splitncnn_0 461_splitncnn_1 461_splitncnn_2
Convolution Conv_176 1 1 461_splitncnn_2 467 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_177 1 1 461_splitncnn_1 bbox_16 0=8 1=3 4=1 5=1 6=4608
Convolution Conv_178 1 1 461_splitncnn_0 kps_16 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_182 1 1 467 score_16
ConvolutionDepthWise Conv_189 1 1 424 477 0=16 1=3 4=1 5=1 6=144 7=16 9=1
Convolution Conv_192 1 1 477 480 0=64 1=1 5=1 6=1024 9=1
ConvolutionDepthWise Conv_195 1 1 480 483 0=64 1=3 4=1 5=1 6=576 7=64 9=1
Convolution Conv_198 1 1 483 486 0=64 1=1 5=1 6=4096 9=1
Split splitncnn_8 1 3 486 486_splitncnn_0 486_splitncnn_1 486_splitncnn_2
Convolution Conv_201 1 1 486_splitncnn_2 492 0=2 1=3 4=1 5=1 6=1152
Convolution Conv_202 1 1 486_splitncnn_1 bbox_32 0=8 1=3 4=1 5=1 6=4608
Convolution Conv_203 1 1 486_splitncnn_0 kps_32 0=20 1=3 4=1 5=1 6=11520
Sigmoid Sigmoid_207 1 1 492 score_32
================================================
FILE: app/src/main/java/com/tencent/scrfdncnn/MainActivity.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.scrfdncnn;
import android.Manifest;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.PixelFormat;
import android.os.Bundle;
import android.util.Log;
import android.view.Surface;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.Spinner;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
public class MainActivity extends Activity implements SurfaceHolder.Callback
{
public static final int REQUEST_CAMERA = 100;
private SCRFDNcnn scrfdncnn = new SCRFDNcnn();
private int facing = 0;
private Spinner spinnerModel;
private Spinner spinnerCPUGPU;
private int current_model = 0;
private int current_cpugpu = 0;
private SurfaceView cameraView;
/** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
cameraView = (SurfaceView) findViewById(R.id.cameraview);
cameraView.getHolder().setFormat(PixelFormat.RGBA_8888);
cameraView.getHolder().addCallback(this);
Button buttonSwitchCamera = (Button) findViewById(R.id.buttonSwitchCamera);
buttonSwitchCamera.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View arg0) {
int new_facing = 1 - facing;
scrfdncnn.closeCamera();
scrfdncnn.openCamera(new_facing);
facing = new_facing;
}
});
spinnerModel = (Spinner) findViewById(R.id.spinnerModel);
spinnerModel.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)
{
if (position != current_model)
{
current_model = position;
reload();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
spinnerCPUGPU = (Spinner) findViewById(R.id.spinnerCPUGPU);
spinnerCPUGPU.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
@Override
public void onItemSelected(AdapterView<?> arg0, View arg1, int position, long id)
{
if (position != current_cpugpu)
{
current_cpugpu = position;
reload();
}
}
@Override
public void onNothingSelected(AdapterView<?> arg0)
{
}
});
reload();
}
private void reload()
{
boolean ret_init = scrfdncnn.loadModel(getAssets(), current_model, current_cpugpu);
if (!ret_init)
{
Log.e("MainActivity", "scrfdncnn loadModel failed");
}
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
scrfdncnn.setOutputWindow(holder.getSurface());
}
@Override
public void surfaceCreated(SurfaceHolder holder)
{
}
@Override
public void surfaceDestroyed(SurfaceHolder holder)
{
}
@Override
public void onResume()
{
super.onResume();
if (ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.CAMERA) == PackageManager.PERMISSION_DENIED)
{
ActivityCompat.requestPermissions(this, new String[] {Manifest.permission.CAMERA}, REQUEST_CAMERA);
}
scrfdncnn.openCamera(facing);
}
@Override
public void onPause()
{
super.onPause();
scrfdncnn.closeCamera();
}
}
================================================
FILE: app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.scrfdncnn;
import android.content.res.AssetManager;
import android.view.Surface;
public class SCRFDNcnn
{
public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);
public native boolean openCamera(int facing);
public native boolean closeCamera();
public native boolean setOutputWindow(Surface surface);
static {
System.loadLibrary("scrfdncnn");
}
}
================================================
FILE: app/src/main/jni/CMakeLists.txt
================================================
project(scrfdncnn)
cmake_minimum_required(VERSION 3.10)
set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.13.0-android/sdk/native/jni)
find_package(OpenCV REQUIRED core imgproc)
set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20260113-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)
add_library(scrfdncnn SHARED scrfdncnn.cpp scrfd.cpp ndkcamera.cpp)
target_link_libraries(scrfdncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)
================================================
FILE: app/src/main/jni/ndkcamera.cpp
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.
#include "ndkcamera.h"
#include <string>
#include <android/log.h>
#include <opencv2/core/core.hpp>
#include "mat.h"
static void onDisconnected(void* context, ACameraDevice* device)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onDisconnected %p", device);
}
static void onError(void* context, ACameraDevice* device, int error)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onError %p %d", device, error);
}
static void onImageAvailable(void* context, AImageReader* reader)
{
// __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onImageAvailable %p", reader);
AImage* image = 0;
media_status_t status = AImageReader_acquireLatestImage(reader, &image);
if (status != AMEDIA_OK)
{
// error
return;
}
int32_t format;
AImage_getFormat(image, &format);
// assert format == AIMAGE_FORMAT_YUV_420_888
int32_t width = 0;
int32_t height = 0;
AImage_getWidth(image, &width);
AImage_getHeight(image, &height);
int32_t y_pixelStride = 0;
int32_t u_pixelStride = 0;
int32_t v_pixelStride = 0;
AImage_getPlanePixelStride(image, 0, &y_pixelStride);
AImage_getPlanePixelStride(image, 1, &u_pixelStride);
AImage_getPlanePixelStride(image, 2, &v_pixelStride);
int32_t y_rowStride = 0;
int32_t u_rowStride = 0;
int32_t v_rowStride = 0;
AImage_getPlaneRowStride(image, 0, &y_rowStride);
AImage_getPlaneRowStride(image, 1, &u_rowStride);
AImage_getPlaneRowStride(image, 2, &v_rowStride);
uint8_t* y_data = 0;
uint8_t* u_data = 0;
uint8_t* v_data = 0;
int y_len = 0;
int u_len = 0;
int v_len = 0;
AImage_getPlaneData(image, 0, &y_data, &y_len);
AImage_getPlaneData(image, 1, &u_data, &u_len);
AImage_getPlaneData(image, 2, &v_data, &v_len);
if (u_data == v_data + 1 && v_data == y_data + width * height && y_pixelStride == 1 && u_pixelStride == 2 && v_pixelStride == 2 && y_rowStride == width && u_rowStride == width && v_rowStride == width)
{
// already nv21 :)
((NdkCamera*)context)->on_image((unsigned char*)y_data, (int)width, (int)height);
}
else
{
// construct nv21
unsigned char* nv21 = new unsigned char[width * height + width * height / 2];
{
// Y
unsigned char* yptr = nv21;
for (int y=0; y<height; y++)
{
const unsigned char* y_data_ptr = y_data + y_rowStride * y;
for (int x=0; x<width; x++)
{
yptr[0] = y_data_ptr[0];
yptr++;
y_data_ptr += y_pixelStride;
}
}
// UV
unsigned char* uvptr = nv21 + width * height;
for (int y=0; y<height/2; y++)
{
const unsigned char* v_data_ptr = v_data + v_rowStride * y;
const unsigned char* u_data_ptr = u_data + u_rowStride * y;
for (int x=0; x<width/2; x++)
{
uvptr[0] = v_data_ptr[0];
uvptr[1] = u_data_ptr[0];
uvptr += 2;
v_data_ptr += v_pixelStride;
u_data_ptr += u_pixelStride;
}
}
}
((NdkCamera*)context)->on_image((unsigned char*)nv21, (int)width, (int)height);
delete[] nv21;
}
AImage_delete(image);
}
static void onSessionActive(void* context, ACameraCaptureSession *session)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionActive %p", session);
}
static void onSessionReady(void* context, ACameraCaptureSession *session)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionReady %p", session);
}
static void onSessionClosed(void* context, ACameraCaptureSession *session)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onSessionClosed %p", session);
}
void onCaptureFailed(void* context, ACameraCaptureSession* session, ACaptureRequest* request, ACameraCaptureFailure* failure)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureFailed %p %p %p", session, request, failure);
}
void onCaptureSequenceCompleted(void* context, ACameraCaptureSession* session, int sequenceId, int64_t frameNumber)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureSequenceCompleted %p %d %ld", session, sequenceId, frameNumber);
}
void onCaptureSequenceAborted(void* context, ACameraCaptureSession* session, int sequenceId)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureSequenceAborted %p %d", session, sequenceId);
}
void onCaptureCompleted(void* context, ACameraCaptureSession* session, ACaptureRequest* request, const ACameraMetadata* result)
{
// __android_log_print(ANDROID_LOG_WARN, "NdkCamera", "onCaptureCompleted %p %p %p", session, request, result);
}
NdkCamera::NdkCamera()
{
camera_facing = 0;
camera_orientation = 0;
camera_manager = 0;
camera_device = 0;
image_reader = 0;
image_reader_surface = 0;
image_reader_target = 0;
capture_request = 0;
capture_session_output_container = 0;
capture_session_output = 0;
capture_session = 0;
// setup imagereader and its surface
{
AImageReader_new(640, 480, AIMAGE_FORMAT_YUV_420_888, /*maxImages*/2, &image_reader);
AImageReader_ImageListener listener;
listener.context = this;
listener.onImageAvailable = onImageAvailable;
AImageReader_setImageListener(image_reader, &listener);
AImageReader_getWindow(image_reader, &image_reader_surface);
ANativeWindow_acquire(image_reader_surface);
}
}
NdkCamera::~NdkCamera()
{
close();
if (image_reader)
{
AImageReader_delete(image_reader);
image_reader = 0;
}
if (image_reader_surface)
{
ANativeWindow_release(image_reader_surface);
image_reader_surface = 0;
}
}
int NdkCamera::open(int _camera_facing)
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open");
camera_facing = _camera_facing;
camera_manager = ACameraManager_create();
// find front camera
std::string camera_id;
{
ACameraIdList* camera_id_list = 0;
ACameraManager_getCameraIdList(camera_manager, &camera_id_list);
for (int i = 0; i < camera_id_list->numCameras; ++i)
{
const char* id = camera_id_list->cameraIds[i];
ACameraMetadata* camera_metadata = 0;
ACameraManager_getCameraCharacteristics(camera_manager, id, &camera_metadata);
// query faceing
acamera_metadata_enum_android_lens_facing_t facing = ACAMERA_LENS_FACING_FRONT;
{
ACameraMetadata_const_entry e = { 0 };
ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_LENS_FACING, &e);
facing = (acamera_metadata_enum_android_lens_facing_t)e.data.u8[0];
}
if (camera_facing == 0 && facing != ACAMERA_LENS_FACING_FRONT)
{
ACameraMetadata_free(camera_metadata);
continue;
}
if (camera_facing == 1 && facing != ACAMERA_LENS_FACING_BACK)
{
ACameraMetadata_free(camera_metadata);
continue;
}
camera_id = id;
// query orientation
int orientation = 0;
{
ACameraMetadata_const_entry e = { 0 };
ACameraMetadata_getConstEntry(camera_metadata, ACAMERA_SENSOR_ORIENTATION, &e);
orientation = (int)e.data.i32[0];
}
camera_orientation = orientation;
ACameraMetadata_free(camera_metadata);
break;
}
ACameraManager_deleteCameraIdList(camera_id_list);
}
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "open %s %d", camera_id.c_str(), camera_orientation);
// open camera
{
ACameraDevice_StateCallbacks camera_device_state_callbacks;
camera_device_state_callbacks.context = this;
camera_device_state_callbacks.onDisconnected = onDisconnected;
camera_device_state_callbacks.onError = onError;
ACameraManager_openCamera(camera_manager, camera_id.c_str(), &camera_device_state_callbacks, &camera_device);
}
// capture request
{
ACameraDevice_createCaptureRequest(camera_device, TEMPLATE_PREVIEW, &capture_request);
ACameraOutputTarget_create(image_reader_surface, &image_reader_target);
ACaptureRequest_addTarget(capture_request, image_reader_target);
}
// capture session
{
ACameraCaptureSession_stateCallbacks camera_capture_session_state_callbacks;
camera_capture_session_state_callbacks.context = this;
camera_capture_session_state_callbacks.onActive = onSessionActive;
camera_capture_session_state_callbacks.onReady = onSessionReady;
camera_capture_session_state_callbacks.onClosed = onSessionClosed;
ACaptureSessionOutputContainer_create(&capture_session_output_container);
ACaptureSessionOutput_create(image_reader_surface, &capture_session_output);
ACaptureSessionOutputContainer_add(capture_session_output_container, capture_session_output);
ACameraDevice_createCaptureSession(camera_device, capture_session_output_container, &camera_capture_session_state_callbacks, &capture_session);
ACameraCaptureSession_captureCallbacks camera_capture_session_capture_callbacks;
camera_capture_session_capture_callbacks.context = this;
camera_capture_session_capture_callbacks.onCaptureStarted = 0;
camera_capture_session_capture_callbacks.onCaptureProgressed = 0;
camera_capture_session_capture_callbacks.onCaptureCompleted = onCaptureCompleted;
camera_capture_session_capture_callbacks.onCaptureFailed = onCaptureFailed;
camera_capture_session_capture_callbacks.onCaptureSequenceCompleted = onCaptureSequenceCompleted;
camera_capture_session_capture_callbacks.onCaptureSequenceAborted = onCaptureSequenceAborted;
camera_capture_session_capture_callbacks.onCaptureBufferLost = 0;
ACameraCaptureSession_setRepeatingRequest(capture_session, &camera_capture_session_capture_callbacks, 1, &capture_request, nullptr);
}
return 0;
}
void NdkCamera::close()
{
__android_log_print(ANDROID_LOG_WARN, "NdkCamera", "close");
if (capture_session)
{
ACameraCaptureSession_stopRepeating(capture_session);
ACameraCaptureSession_close(capture_session);
capture_session = 0;
}
if (camera_device)
{
ACameraDevice_close(camera_device);
camera_device = 0;
}
if (capture_session_output_container)
{
ACaptureSessionOutputContainer_free(capture_session_output_container);
capture_session_output_container = 0;
}
if (capture_session_output)
{
ACaptureSessionOutput_free(capture_session_output);
capture_session_output = 0;
}
if (capture_request)
{
ACaptureRequest_free(capture_request);
capture_request = 0;
}
if (image_reader_target)
{
ACameraOutputTarget_free(image_reader_target);
image_reader_target = 0;
}
if (camera_manager)
{
ACameraManager_delete(camera_manager);
camera_manager = 0;
}
}
void NdkCamera::on_image(const cv::Mat& rgb) const
{
}
void NdkCamera::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const
{
// rotate nv21
int w = 0;
int h = 0;
int rotate_type = 0;
{
if (camera_orientation == 0)
{
w = nv21_width;
h = nv21_height;
rotate_type = camera_facing == 0 ? 2 : 1;
}
if (camera_orientation == 90)
{
w = nv21_height;
h = nv21_width;
rotate_type = camera_facing == 0 ? 5 : 6;
}
if (camera_orientation == 180)
{
w = nv21_width;
h = nv21_height;
rotate_type = camera_facing == 0 ? 4 : 3;
}
if (camera_orientation == 270)
{
w = nv21_height;
h = nv21_width;
rotate_type = camera_facing == 0 ? 7 : 8;
}
}
cv::Mat nv21_rotated(h + h / 2, w, CV_8UC1);
ncnn::kanna_rotate_yuv420sp(nv21, nv21_width, nv21_height, nv21_rotated.data, w, h, rotate_type);
// nv21_rotated to rgb
cv::Mat rgb(h, w, CV_8UC3);
ncnn::yuv420sp2rgb(nv21_rotated.data, w, h, rgb.data);
on_image(rgb);
}
static const int NDKCAMERAWINDOW_ID = 233;
NdkCameraWindow::NdkCameraWindow() : NdkCamera()
{
sensor_manager = 0;
sensor_event_queue = 0;
accelerometer_sensor = 0;
win = 0;
accelerometer_orientation = 0;
// sensor
sensor_manager = ASensorManager_getInstance();
accelerometer_sensor = ASensorManager_getDefaultSensor(sensor_manager, ASENSOR_TYPE_ACCELEROMETER);
}
NdkCameraWindow::~NdkCameraWindow()
{
if (accelerometer_sensor)
{
ASensorEventQueue_disableSensor(sensor_event_queue, accelerometer_sensor);
accelerometer_sensor = 0;
}
if (sensor_event_queue)
{
ASensorManager_destroyEventQueue(sensor_manager, sensor_event_queue);
sensor_event_queue = 0;
}
if (win)
{
ANativeWindow_release(win);
}
}
void NdkCameraWindow::set_window(ANativeWindow* _win)
{
if (win)
{
ANativeWindow_release(win);
}
win = _win;
ANativeWindow_acquire(win);
}
void NdkCameraWindow::on_image_render(cv::Mat& rgb) const
{
}
void NdkCameraWindow::on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const
{
// resolve orientation from camera_orientation and accelerometer_sensor
{
if (!sensor_event_queue)
{
sensor_event_queue = ASensorManager_createEventQueue(sensor_manager, ALooper_prepare(ALOOPER_PREPARE_ALLOW_NON_CALLBACKS), NDKCAMERAWINDOW_ID, 0, 0);
ASensorEventQueue_enableSensor(sensor_event_queue, accelerometer_sensor);
}
int id = ALooper_pollOnce(0, 0, 0, 0);
if (id == NDKCAMERAWINDOW_ID)
{
ASensorEvent e[8];
ssize_t num_event = 0;
while (ASensorEventQueue_hasEvents(sensor_event_queue) == 1)
{
num_event = ASensorEventQueue_getEvents(sensor_event_queue, e, 8);
if (num_event < 0)
break;
}
if (num_event > 0)
{
float acceleration_x = e[num_event - 1].acceleration.x;
float acceleration_y = e[num_event - 1].acceleration.y;
float acceleration_z = e[num_event - 1].acceleration.z;
// __android_log_print(ANDROID_LOG_WARN, "NdkCameraWindow", "x = %f, y = %f, z = %f", x, y, z);
if (acceleration_y > 7)
{
accelerometer_orientation = 0;
}
if (acceleration_x < -7)
{
accelerometer_orientation = 90;
}
if (acceleration_y < -7)
{
accelerometer_orientation = 180;
}
if (acceleration_x > 7)
{
accelerometer_orientation = 270;
}
}
}
}
// roi crop and rotate nv21
int nv21_roi_x = 0;
int nv21_roi_y = 0;
int nv21_roi_w = 0;
int nv21_roi_h = 0;
int roi_x = 0;
int roi_y = 0;
int roi_w = 0;
int roi_h = 0;
int rotate_type = 0;
int render_w = 0;
int render_h = 0;
int render_rotate_type = 0;
{
int win_w = ANativeWindow_getWidth(win);
int win_h = ANativeWindow_getHeight(win);
if (accelerometer_orientation == 90 || accelerometer_orientation == 270)
{
std::swap(win_w, win_h);
}
const int final_orientation = (camera_orientation + accelerometer_orientation) % 360;
if (final_orientation == 0 || final_orientation == 180)
{
if (win_w * nv21_height > win_h * nv21_width)
{
roi_w = nv21_width;
roi_h = (nv21_width * win_h / win_w) / 2 * 2;
roi_x = 0;
roi_y = ((nv21_height - roi_h) / 2) / 2 * 2;
}
else
{
roi_h = nv21_height;
roi_w = (nv21_height * win_w / win_h) / 2 * 2;
roi_x = ((nv21_width - roi_w) / 2) / 2 * 2;
roi_y = 0;
}
nv21_roi_x = roi_x;
nv21_roi_y = roi_y;
nv21_roi_w = roi_w;
nv21_roi_h = roi_h;
}
if (final_orientation == 90 || final_orientation == 270)
{
if (win_w * nv21_width > win_h * nv21_height)
{
roi_w = nv21_height;
roi_h = (nv21_height * win_h / win_w) / 2 * 2;
roi_x = 0;
roi_y = ((nv21_width - roi_h) / 2) / 2 * 2;
}
else
{
roi_h = nv21_width;
roi_w = (nv21_width * win_w / win_h) / 2 * 2;
roi_x = ((nv21_height - roi_w) / 2) / 2 * 2;
roi_y = 0;
}
nv21_roi_x = roi_y;
nv21_roi_y = roi_x;
nv21_roi_w = roi_h;
nv21_roi_h = roi_w;
}
if (camera_facing == 0)
{
if (camera_orientation == 0 && accelerometer_orientation == 0)
{
rotate_type = 2;
}
if (camera_orientation == 0 && accelerometer_orientation == 90)
{
rotate_type = 7;
}
if (camera_orientation == 0 && accelerometer_orientation == 180)
{
rotate_type = 4;
}
if (camera_orientation == 0 && accelerometer_orientation == 270)
{
rotate_type = 5;
}
if (camera_orientation == 90 && accelerometer_orientation == 0)
{
rotate_type = 5;
}
if (camera_orientation == 90 && accelerometer_orientation == 90)
{
rotate_type = 2;
}
if (camera_orientation == 90 && accelerometer_orientation == 180)
{
rotate_type = 7;
}
if (camera_orientation == 90 && accelerometer_orientation == 270)
{
rotate_type = 4;
}
if (camera_orientation == 180 && accelerometer_orientation == 0)
{
rotate_type = 4;
}
if (camera_orientation == 180 && accelerometer_orientation == 90)
{
rotate_type = 5;
}
if (camera_orientation == 180 && accelerometer_orientation == 180)
{
rotate_type = 2;
}
if (camera_orientation == 180 && accelerometer_orientation == 270)
{
rotate_type = 7;
}
if (camera_orientation == 270 && accelerometer_orientation == 0)
{
rotate_type = 7;
}
if (camera_orientation == 270 && accelerometer_orientation == 90)
{
rotate_type = 4;
}
if (camera_orientation == 270 && accelerometer_orientation == 180)
{
rotate_type = 5;
}
if (camera_orientation == 270 && accelerometer_orientation == 270)
{
rotate_type = 2;
}
}
else
{
if (final_orientation == 0)
{
rotate_type = 1;
}
if (final_orientation == 90)
{
rotate_type = 6;
}
if (final_orientation == 180)
{
rotate_type = 3;
}
if (final_orientation == 270)
{
rotate_type = 8;
}
}
if (accelerometer_orientation == 0)
{
render_w = roi_w;
render_h = roi_h;
render_rotate_type = 1;
}
if (accelerometer_orientation == 90)
{
render_w = roi_h;
render_h = roi_w;
render_rotate_type = 8;
}
if (accelerometer_orientation == 180)
{
render_w = roi_w;
render_h = roi_h;
render_rotate_type = 3;
}
if (accelerometer_orientation == 270)
{
render_w = roi_h;
render_h = roi_w;
render_rotate_type = 6;
}
}
// crop and rotate nv21
cv::Mat nv21_croprotated(roi_h + roi_h / 2, roi_w, CV_8UC1);
{
const unsigned char* srcY = nv21 + nv21_roi_y * nv21_width + nv21_roi_x;
unsigned char* dstY = nv21_croprotated.data;
ncnn::kanna_rotate_c1(srcY, nv21_roi_w, nv21_roi_h, nv21_width, dstY, roi_w, roi_h, roi_w, rotate_type);
const unsigned char* srcUV = nv21 + nv21_width * nv21_height + nv21_roi_y * nv21_width / 2 + nv21_roi_x;
unsigned char* dstUV = nv21_croprotated.data + roi_w * roi_h;
ncnn::kanna_rotate_c2(srcUV, nv21_roi_w / 2, nv21_roi_h / 2, nv21_width, dstUV, roi_w / 2, roi_h / 2, roi_w, rotate_type);
}
// nv21_croprotated to rgb
cv::Mat rgb(roi_h, roi_w, CV_8UC3);
ncnn::yuv420sp2rgb(nv21_croprotated.data, roi_w, roi_h, rgb.data);
on_image_render(rgb);
// rotate to native window orientation
cv::Mat rgb_render(render_h, render_w, CV_8UC3);
ncnn::kanna_rotate_c3(rgb.data, roi_w, roi_h, rgb_render.data, render_w, render_h, render_rotate_type);
ANativeWindow_setBuffersGeometry(win, render_w, render_h, AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM);
ANativeWindow_Buffer buf;
ANativeWindow_lock(win, &buf, NULL);
// scale to target size
if (buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8A8_UNORM || buf.format == AHARDWAREBUFFER_FORMAT_R8G8B8X8_UNORM)
{
for (int y = 0; y < render_h; y++)
{
const unsigned char* ptr = rgb_render.ptr<const unsigned char>(y);
unsigned char* outptr = (unsigned char*)buf.bits + buf.stride * 4 * y;
int x = 0;
#if __ARM_NEON
for (; x + 7 < render_w; x += 8)
{
uint8x8x3_t _rgb = vld3_u8(ptr);
uint8x8x4_t _rgba;
_rgba.val[0] = _rgb.val[0];
_rgba.val[1] = _rgb.val[1];
_rgba.val[2] = _rgb.val[2];
_rgba.val[3] = vdup_n_u8(255);
vst4_u8(outptr, _rgba);
ptr += 24;
outptr += 32;
}
#endif // __ARM_NEON
for (; x < render_w; x++)
{
outptr[0] = ptr[0];
outptr[1] = ptr[1];
outptr[2] = ptr[2];
outptr[3] = 255;
ptr += 3;
outptr += 4;
}
}
}
ANativeWindow_unlockAndPost(win);
}
================================================
FILE: app/src/main/jni/ndkcamera.h
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.
#ifndef NDKCAMERA_H
#define NDKCAMERA_H
#include <android/looper.h>
#include <android/native_window.h>
#include <android/sensor.h>
#include <camera/NdkCameraDevice.h>
#include <camera/NdkCameraManager.h>
#include <camera/NdkCameraMetadata.h>
#include <media/NdkImageReader.h>
#include <opencv2/core/core.hpp>
class NdkCamera
{
public:
NdkCamera();
virtual ~NdkCamera();
// facing 0=front 1=back
int open(int camera_facing = 0);
void close();
virtual void on_image(const cv::Mat& rgb) const;
virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;
public:
int camera_facing;
int camera_orientation;
private:
ACameraManager* camera_manager;
ACameraDevice* camera_device;
AImageReader* image_reader;
ANativeWindow* image_reader_surface;
ACameraOutputTarget* image_reader_target;
ACaptureRequest* capture_request;
ACaptureSessionOutputContainer* capture_session_output_container;
ACaptureSessionOutput* capture_session_output;
ACameraCaptureSession* capture_session;
};
class NdkCameraWindow : public NdkCamera
{
public:
NdkCameraWindow();
virtual ~NdkCameraWindow();
void set_window(ANativeWindow* win);
virtual void on_image_render(cv::Mat& rgb) const;
virtual void on_image(const unsigned char* nv21, int nv21_width, int nv21_height) const;
public:
mutable int accelerometer_orientation;
private:
ASensorManager* sensor_manager;
mutable ASensorEventQueue* sensor_event_queue;
const ASensor* accelerometer_sensor;
ANativeWindow* win;
};
#endif // NDKCAMERA_H
================================================
FILE: app/src/main/jni/scrfd.cpp
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.
#include "scrfd.h"
#include <string.h>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include "cpu.h"
static inline float intersection_area(const FaceObject& a, const FaceObject& b)
{
cv::Rect_<float> inter = a.rect & b.rect;
return inter.area();
}
static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects, int left, int right)
{
int i = left;
int j = right;
float p = faceobjects[(left + right) / 2].prob;
while (i <= j)
{
while (faceobjects[i].prob > p)
i++;
while (faceobjects[j].prob < p)
j--;
if (i <= j)
{
// swap
std::swap(faceobjects[i], faceobjects[j]);
i++;
j--;
}
}
// #pragma omp parallel sections
{
// #pragma omp section
{
if (left < j) qsort_descent_inplace(faceobjects, left, j);
}
// #pragma omp section
{
if (i < right) qsort_descent_inplace(faceobjects, i, right);
}
}
}
static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects)
{
if (faceobjects.empty())
return;
qsort_descent_inplace(faceobjects, 0, faceobjects.size() - 1);
}
static void nms_sorted_bboxes(const std::vector<FaceObject>& faceobjects, std::vector<int>& picked, float nms_threshold)
{
picked.clear();
const int n = faceobjects.size();
std::vector<float> areas(n);
for (int i = 0; i < n; i++)
{
areas[i] = faceobjects[i].rect.area();
}
for (int i = 0; i < n; i++)
{
const FaceObject& a = faceobjects[i];
int keep = 1;
for (int j = 0; j < (int)picked.size(); j++)
{
const FaceObject& b = faceobjects[picked[j]];
// intersection over union
float inter_area = intersection_area(a, b);
float union_area = areas[i] + areas[picked[j]] - inter_area;
// float IoU = inter_area / union_area
if (inter_area / union_area > nms_threshold)
keep = 0;
}
if (keep)
picked.push_back(i);
}
}
// insightface/detection/scrfd/mmdet/core/anchor/anchor_generator.py gen_single_level_base_anchors()
static ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios, const ncnn::Mat& scales)
{
int num_ratio = ratios.w;
int num_scale = scales.w;
ncnn::Mat anchors;
anchors.create(4, num_ratio * num_scale);
const float cx = 0;
const float cy = 0;
for (int i = 0; i < num_ratio; i++)
{
float ar = ratios[i];
int r_w = round(base_size / sqrt(ar));
int r_h = round(r_w * ar); //round(base_size * sqrt(ar));
for (int j = 0; j < num_scale; j++)
{
float scale = scales[j];
float rs_w = r_w * scale;
float rs_h = r_h * scale;
float* anchor = anchors.row(i * num_scale + j);
anchor[0] = cx - rs_w * 0.5f;
anchor[1] = cy - rs_h * 0.5f;
anchor[2] = cx + rs_w * 0.5f;
anchor[3] = cy + rs_h * 0.5f;
}
}
return anchors;
}
static void generate_proposals(const ncnn::Mat& anchors, int feat_stride, const ncnn::Mat& score_blob, const ncnn::Mat& bbox_blob, const ncnn::Mat& kps_blob, float prob_threshold, std::vector<FaceObject>& faceobjects)
{
int w = score_blob.w;
int h = score_blob.h;
// generate face proposal from bbox deltas and shifted anchors
const int num_anchors = anchors.h;
for (int q = 0; q < num_anchors; q++)
{
const float* anchor = anchors.row(q);
const ncnn::Mat score = score_blob.channel(q);
const ncnn::Mat bbox = bbox_blob.channel_range(q * 4, 4);
// shifted anchor
float anchor_y = anchor[1];
float anchor_w = anchor[2] - anchor[0];
float anchor_h = anchor[3] - anchor[1];
for (int i = 0; i < h; i++)
{
float anchor_x = anchor[0];
for (int j = 0; j < w; j++)
{
int index = i * w + j;
float prob = score[index];
if (prob >= prob_threshold)
{
// insightface/detection/scrfd/mmdet/models/dense_heads/scrfd_head.py _get_bboxes_single()
float dx = bbox.channel(0)[index] * feat_stride;
float dy = bbox.channel(1)[index] * feat_stride;
float dw = bbox.channel(2)[index] * feat_stride;
float dh = bbox.channel(3)[index] * feat_stride;
// insightface/detection/scrfd/mmdet/core/bbox/transforms.py distance2bbox()
float cx = anchor_x + anchor_w * 0.5f;
float cy = anchor_y + anchor_h * 0.5f;
float x0 = cx - dx;
float y0 = cy - dy;
float x1 = cx + dw;
float y1 = cy + dh;
FaceObject obj;
obj.rect.x = x0;
obj.rect.y = y0;
obj.rect.width = x1 - x0 + 1;
obj.rect.height = y1 - y0 + 1;
obj.prob = prob;
if (!kps_blob.empty())
{
const ncnn::Mat kps = kps_blob.channel_range(q * 10, 10);
obj.landmark[0].x = cx + kps.channel(0)[index] * feat_stride;
obj.landmark[0].y = cy + kps.channel(1)[index] * feat_stride;
obj.landmark[1].x = cx + kps.channel(2)[index] * feat_stride;
obj.landmark[1].y = cy + kps.channel(3)[index] * feat_stride;
obj.landmark[2].x = cx + kps.channel(4)[index] * feat_stride;
obj.landmark[2].y = cy + kps.channel(5)[index] * feat_stride;
obj.landmark[3].x = cx + kps.channel(6)[index] * feat_stride;
obj.landmark[3].y = cy + kps.channel(7)[index] * feat_stride;
obj.landmark[4].x = cx + kps.channel(8)[index] * feat_stride;
obj.landmark[4].y = cy + kps.channel(9)[index] * feat_stride;
}
faceobjects.push_back(obj);
}
anchor_x += feat_stride;
}
anchor_y += feat_stride;
}
}
}
int SCRFD::load(const char* modeltype, bool use_gpu)
{
scrfd.clear();
ncnn::set_cpu_powersave(2);
ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());
scrfd.opt = ncnn::Option();
#if NCNN_VULKAN
scrfd.opt.use_vulkan_compute = use_gpu;
#endif
scrfd.opt.num_threads = ncnn::get_big_cpu_count();
char parampath[256];
char modelpath[256];
sprintf(parampath, "scrfd_%s-opt2.param", modeltype);
sprintf(modelpath, "scrfd_%s-opt2.bin", modeltype);
scrfd.load_param(parampath);
scrfd.load_model(modelpath);
has_kps = strstr(modeltype, "_kps") != NULL;
return 0;
}
int SCRFD::load(AAssetManager* mgr, const char* modeltype, bool use_gpu)
{
scrfd.clear();
ncnn::set_cpu_powersave(2);
ncnn::set_omp_num_threads(ncnn::get_big_cpu_count());
scrfd.opt = ncnn::Option();
#if NCNN_VULKAN
scrfd.opt.use_vulkan_compute = use_gpu;
#endif
scrfd.opt.num_threads = ncnn::get_big_cpu_count();
char parampath[256];
char modelpath[256];
sprintf(parampath, "scrfd_%s-opt2.param", modeltype);
sprintf(modelpath, "scrfd_%s-opt2.bin", modeltype);
scrfd.load_param(mgr, parampath);
scrfd.load_model(mgr, modelpath);
has_kps = strstr(modeltype, "_kps") != NULL;
return 0;
}
int SCRFD::detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold, float nms_threshold)
{
int width = rgb.cols;
int height = rgb.rows;
// insightface/detection/scrfd/configs/scrfd/scrfd_500m.py
const int target_size = 640;
// pad to multiple of 32
int w = width;
int h = height;
float scale = 1.f;
if (w > h)
{
scale = (float)target_size / w;
w = target_size;
h = h * scale;
}
else
{
scale = (float)target_size / h;
h = target_size;
w = w * scale;
}
ncnn::Mat in = ncnn::Mat::from_pixels_resize(rgb.data, ncnn::Mat::PIXEL_RGB, width, height, w, h);
// pad to target_size rectangle
int wpad = (w + 31) / 32 * 32 - w;
int hpad = (h + 31) / 32 * 32 - h;
ncnn::Mat in_pad;
ncnn::copy_make_border(in, in_pad, hpad / 2, hpad - hpad / 2, wpad / 2, wpad - wpad / 2, ncnn::BORDER_CONSTANT, 0.f);
const float mean_vals[3] = {127.5f, 127.5f, 127.5f};
const float norm_vals[3] = {1/128.f, 1/128.f, 1/128.f};
in_pad.substract_mean_normalize(mean_vals, norm_vals);
ncnn::Extractor ex = scrfd.create_extractor();
ex.input("input.1", in_pad);
std::vector<FaceObject> faceproposals;
// stride 8
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_8", score_blob);
ex.extract("bbox_8", bbox_blob);
if (has_kps)
ex.extract("kps_8", kps_blob);
const int base_size = 16;
const int feat_stride = 8;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects8;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects8);
faceproposals.insert(faceproposals.end(), faceobjects8.begin(), faceobjects8.end());
}
// stride 16
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_16", score_blob);
ex.extract("bbox_16", bbox_blob);
if (has_kps)
ex.extract("kps_16", kps_blob);
const int base_size = 64;
const int feat_stride = 16;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects16;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects16);
faceproposals.insert(faceproposals.end(), faceobjects16.begin(), faceobjects16.end());
}
// stride 32
{
ncnn::Mat score_blob, bbox_blob, kps_blob;
ex.extract("score_32", score_blob);
ex.extract("bbox_32", bbox_blob);
if (has_kps)
ex.extract("kps_32", kps_blob);
const int base_size = 256;
const int feat_stride = 32;
ncnn::Mat ratios(1);
ratios[0] = 1.f;
ncnn::Mat scales(2);
scales[0] = 1.f;
scales[1] = 2.f;
ncnn::Mat anchors = generate_anchors(base_size, ratios, scales);
std::vector<FaceObject> faceobjects32;
generate_proposals(anchors, feat_stride, score_blob, bbox_blob, kps_blob, prob_threshold, faceobjects32);
faceproposals.insert(faceproposals.end(), faceobjects32.begin(), faceobjects32.end());
}
// sort all proposals by score from highest to lowest
qsort_descent_inplace(faceproposals);
// apply nms with nms_threshold
std::vector<int> picked;
nms_sorted_bboxes(faceproposals, picked, nms_threshold);
int face_count = picked.size();
faceobjects.resize(face_count);
for (int i = 0; i < face_count; i++)
{
faceobjects[i] = faceproposals[picked[i]];
// adjust offset to original unpadded
float x0 = (faceobjects[i].rect.x - (wpad / 2)) / scale;
float y0 = (faceobjects[i].rect.y - (hpad / 2)) / scale;
float x1 = (faceobjects[i].rect.x + faceobjects[i].rect.width - (wpad / 2)) / scale;
float y1 = (faceobjects[i].rect.y + faceobjects[i].rect.height - (hpad / 2)) / scale;
x0 = std::max(std::min(x0, (float)width - 1), 0.f);
y0 = std::max(std::min(y0, (float)height - 1), 0.f);
x1 = std::max(std::min(x1, (float)width - 1), 0.f);
y1 = std::max(std::min(y1, (float)height - 1), 0.f);
faceobjects[i].rect.x = x0;
faceobjects[i].rect.y = y0;
faceobjects[i].rect.width = x1 - x0;
faceobjects[i].rect.height = y1 - y0;
if (has_kps)
{
float x0 = (faceobjects[i].landmark[0].x - (wpad / 2)) / scale;
float y0 = (faceobjects[i].landmark[0].y - (hpad / 2)) / scale;
float x1 = (faceobjects[i].landmark[1].x - (wpad / 2)) / scale;
float y1 = (faceobjects[i].landmark[1].y - (hpad / 2)) / scale;
float x2 = (faceobjects[i].landmark[2].x - (wpad / 2)) / scale;
float y2 = (faceobjects[i].landmark[2].y - (hpad / 2)) / scale;
float x3 = (faceobjects[i].landmark[3].x - (wpad / 2)) / scale;
float y3 = (faceobjects[i].landmark[3].y - (hpad / 2)) / scale;
float x4 = (faceobjects[i].landmark[4].x - (wpad / 2)) / scale;
float y4 = (faceobjects[i].landmark[4].y - (hpad / 2)) / scale;
faceobjects[i].landmark[0].x = std::max(std::min(x0, (float)width - 1), 0.f);
faceobjects[i].landmark[0].y = std::max(std::min(y0, (float)height - 1), 0.f);
faceobjects[i].landmark[1].x = std::max(std::min(x1, (float)width - 1), 0.f);
faceobjects[i].landmark[1].y = std::max(std::min(y1, (float)height - 1), 0.f);
faceobjects[i].landmark[2].x = std::max(std::min(x2, (float)width - 1), 0.f);
faceobjects[i].landmark[2].y = std::max(std::min(y2, (float)height - 1), 0.f);
faceobjects[i].landmark[3].x = std::max(std::min(x3, (float)width - 1), 0.f);
faceobjects[i].landmark[3].y = std::max(std::min(y3, (float)height - 1), 0.f);
faceobjects[i].landmark[4].x = std::max(std::min(x4, (float)width - 1), 0.f);
faceobjects[i].landmark[4].y = std::max(std::min(y4, (float)height - 1), 0.f);
}
}
return 0;
}
int SCRFD::draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects)
{
for (size_t i = 0; i < faceobjects.size(); i++)
{
const FaceObject& obj = faceobjects[i];
// fprintf(stderr, "%.5f at %.2f %.2f %.2f x %.2f\n", obj.prob,
// obj.rect.x, obj.rect.y, obj.rect.width, obj.rect.height);
cv::rectangle(rgb, obj.rect, cv::Scalar(0, 255, 0));
if (has_kps)
{
cv::circle(rgb, obj.landmark[0], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[1], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[2], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[3], 2, cv::Scalar(255, 255, 0), -1);
cv::circle(rgb, obj.landmark[4], 2, cv::Scalar(255, 255, 0), -1);
}
char text[256];
sprintf(text, "%.1f%%", obj.prob * 100);
int baseLine = 0;
cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
int x = obj.rect.x;
int y = obj.rect.y - label_size.height - baseLine;
if (y < 0)
y = 0;
if (x + label_size.width > rgb.cols)
x = rgb.cols - label_size.width;
cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)), cv::Scalar(255, 255, 255), -1);
cv::putText(rgb, text, cv::Point(x, y + label_size.height), cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0), 1);
}
return 0;
}
================================================
FILE: app/src/main/jni/scrfd.h
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.
#ifndef SCRFD_H
#define SCRFD_H
#include <opencv2/core/core.hpp>
#include <net.h>
struct FaceObject
{
cv::Rect_<float> rect;
cv::Point2f landmark[5];
float prob;
};
class SCRFD
{
public:
int load(const char* modeltype, bool use_gpu = false);
int load(AAssetManager* mgr, const char* modeltype, bool use_gpu = false);
int detect(const cv::Mat& rgb, std::vector<FaceObject>& faceobjects, float prob_threshold = 0.5f, float nms_threshold = 0.45f);
int draw(cv::Mat& rgb, const std::vector<FaceObject>& faceobjects);
private:
ncnn::Net scrfd;
bool has_kps;
};
#endif // SCRFD_H
================================================
FILE: app/src/main/jni/scrfdncnn.cpp
================================================
// Tencent is pleased to support the open source community by making ncnn available.
//
// Copyright (C) 2021 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.
#include <android/asset_manager_jni.h>
#include <android/native_window_jni.h>
#include <android/native_window.h>
#include <android/log.h>
#include <jni.h>
#include <string>
#include <vector>
#include <platform.h>
#include <benchmark.h>
#include "scrfd.h"
#include "ndkcamera.h"
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#if __ARM_NEON
#include <arm_neon.h>
#endif // __ARM_NEON
static int draw_unsupported(cv::Mat& rgb)
{
const char text[] = "unsupported";
int baseLine = 0;
cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 1.0, 1, &baseLine);
int y = (rgb.rows - label_size.height) / 2;
int x = (rgb.cols - label_size.width) / 2;
cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
cv::Scalar(255, 255, 255), -1);
cv::putText(rgb, text, cv::Point(x, y + label_size.height),
cv::FONT_HERSHEY_SIMPLEX, 1.0, cv::Scalar(0, 0, 0));
return 0;
}
static int draw_fps(cv::Mat& rgb)
{
// resolve moving average
float avg_fps = 0.f;
{
static double t0 = 0.f;
static float fps_history[10] = {0.f};
double t1 = ncnn::get_current_time();
if (t0 == 0.f)
{
t0 = t1;
return 0;
}
float fps = 1000.f / (t1 - t0);
t0 = t1;
for (int i = 9; i >= 1; i--)
{
fps_history[i] = fps_history[i - 1];
}
fps_history[0] = fps;
if (fps_history[9] == 0.f)
{
return 0;
}
for (int i = 0; i < 10; i++)
{
avg_fps += fps_history[i];
}
avg_fps /= 10.f;
}
char text[32];
sprintf(text, "FPS=%.2f", avg_fps);
int baseLine = 0;
cv::Size label_size = cv::getTextSize(text, cv::FONT_HERSHEY_SIMPLEX, 0.5, 1, &baseLine);
int y = 0;
int x = rgb.cols - label_size.width;
cv::rectangle(rgb, cv::Rect(cv::Point(x, y), cv::Size(label_size.width, label_size.height + baseLine)),
cv::Scalar(255, 255, 255), -1);
cv::putText(rgb, text, cv::Point(x, y + label_size.height),
cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(0, 0, 0));
return 0;
}
static SCRFD* g_scrfd = 0;
static ncnn::Mutex lock;
class MyNdkCamera : public NdkCameraWindow
{
public:
virtual void on_image_render(cv::Mat& rgb) const;
};
void MyNdkCamera::on_image_render(cv::Mat& rgb) const
{
// scrfd
{
ncnn::MutexLockGuard g(lock);
if (g_scrfd)
{
std::vector<FaceObject> faceobjects;
g_scrfd->detect(rgb, faceobjects);
g_scrfd->draw(rgb, faceobjects);
}
else
{
draw_unsupported(rgb);
}
}
draw_fps(rgb);
}
static MyNdkCamera* g_camera = 0;
extern "C" {
JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
{
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnLoad");
g_camera = new MyNdkCamera;
return JNI_VERSION_1_4;
}
JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
{
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "JNI_OnUnload");
{
ncnn::MutexLockGuard g(lock);
delete g_scrfd;
g_scrfd = 0;
}
delete g_camera;
g_camera = 0;
}
// public native boolean loadModel(AssetManager mgr, int modelid, int cpugpu);
JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_loadModel(JNIEnv* env, jobject thiz, jobject assetManager, jint modelid, jint cpugpu)
{
if (modelid < 0 || modelid > 7 || cpugpu < 0 || cpugpu > 1)
{
return JNI_FALSE;
}
AAssetManager* mgr = AAssetManager_fromJava(env, assetManager);
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "loadModel %p", mgr);
const char* modeltypes[] =
{
"500m",
"500m_kps",
"1g",
"2.5g",
"2.5g_kps",
"10g",
"10g_kps",
"34g"
};
const char* modeltype = modeltypes[(int)modelid];
bool use_gpu = (int)cpugpu == 1;
// reload
{
ncnn::MutexLockGuard g(lock);
if (use_gpu && ncnn::get_gpu_count() == 0)
{
// no gpu
delete g_scrfd;
g_scrfd = 0;
}
else
{
if (!g_scrfd)
g_scrfd = new SCRFD;
g_scrfd->load(mgr, modeltype, use_gpu);
}
}
return JNI_TRUE;
}
// public native boolean openCamera(int facing);
JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_openCamera(JNIEnv* env, jobject thiz, jint facing)
{
if (facing < 0 || facing > 1)
return JNI_FALSE;
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "openCamera %d", facing);
g_camera->open((int)facing);
return JNI_TRUE;
}
// public native boolean closeCamera();
JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_closeCamera(JNIEnv* env, jobject thiz)
{
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "closeCamera");
g_camera->close();
return JNI_TRUE;
}
// public native boolean setOutputWindow(Surface surface);
JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_setOutputWindow(JNIEnv* env, jobject thiz, jobject surface)
{
ANativeWindow* win = ANativeWindow_fromSurface(env, surface);
__android_log_print(ANDROID_LOG_DEBUG, "ncnn", "setOutputWindow %p", win);
g_camera->set_window(win);
return JNI_TRUE;
}
}
================================================
FILE: app/src/main/res/layout/main.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:orientation="vertical"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:fitsSystemWindows="true">
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Button
android:id="@+id/buttonSwitchCamera"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="切换摄像头" />
</LinearLayout>
<LinearLayout
android:orientation="horizontal"
android:layout_width="fill_parent"
android:layout_height="wrap_content">
<Spinner
android:id="@+id/spinnerModel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:entries="@array/model_array" />
<Spinner
android:id="@+id/spinnerCPUGPU"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawSelectorOnTop="true"
android:entries="@array/cpugpu_array" />
</LinearLayout>
<SurfaceView
android:id="@+id/cameraview"
android:layout_width="fill_parent"
android:layout_height="fill_parent" />
</LinearLayout>
================================================
FILE: app/src/main/res/values/strings.xml
================================================
<?xml version="1.0" encoding="utf-8"?>
<resources>
<string name="app_name">scrfdncnn</string>
<string-array name="model_array">
<item>500m</item>
<item>500m_kps</item>
<item>1g</item>
<item>2.5g</item>
<item>2.5g_kps</item>
<item>10g</item>
<item>10g_kps</item>
<item>34g</item>
</string-array>
<string-array name="cpugpu_array">
<item>CPU</item>
<item>GPU</item>
</string-array>
</resources>
================================================
FILE: build.gradle
================================================
// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '8.7.3' apply false
}
================================================
FILE: gradle/wrapper/gradle-wrapper.properties
================================================
#Wed Dec 25 17:36:46 CST 2024
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
================================================
FILE: gradlew
================================================
#!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
##############################################################################
##
## Gradle start up script for UN*X
##
##############################################################################
# Attempt to set APP_HOME
# Resolve links: $0 may be a link
PRG="$0"
# Need this for relative symlinks.
while [ -h "$PRG" ] ; do
ls=`ls -ld "$PRG"`
link=`expr "$ls" : '.*-> \(.*\)$'`
if expr "$link" : '/.*' > /dev/null; then
PRG="$link"
else
PRG=`dirname "$PRG"`"/$link"
fi
done
SAVED="`pwd`"
cd "`dirname \"$PRG\"`/" >/dev/null
APP_HOME="`pwd -P`"
cd "$SAVED" >/dev/null
APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
warn () {
echo "$*"
}
die () {
echo
echo "$*"
echo
exit 1
}
# OS specific support (must be 'true' or 'false').
cygwin=false
msys=false
darwin=false
nonstop=false
case "`uname`" in
CYGWIN* )
cygwin=true
;;
Darwin* )
darwin=true
;;
MINGW* )
msys=true
;;
NONSTOP* )
nonstop=true
;;
esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
# IBM's JDK on AIX uses strange locations for the executables
JAVACMD="$JAVA_HOME/jre/sh/java"
else
JAVACMD="$JAVA_HOME/bin/java"
fi
if [ ! -x "$JAVACMD" ] ; then
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
else
JAVACMD="java"
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation."
fi
# Increase the maximum file descriptors if we can.
if [ "$cygwin" = "false" -a "$darwin" = "false" -a "$nonstop" = "false" ] ; then
MAX_FD_LIMIT=`ulimit -H -n`
if [ $? -eq 0 ] ; then
if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
MAX_FD="$MAX_FD_LIMIT"
fi
ulimit -n $MAX_FD
if [ $? -ne 0 ] ; then
warn "Could not set maximum file descriptor limit: $MAX_FD"
fi
else
warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
fi
fi
# For Darwin, add options to specify how the application appears in the dock
if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
SEP=""
for dir in $ROOTDIRSRAW ; do
ROOTDIRS="$ROOTDIRS$SEP$dir"
SEP="|"
done
OURCYGPATTERN="(^($ROOTDIRS))"
# Add a user-defined pattern to the cygpath arguments
if [ "$GRADLE_CYGPATTERN" != "" ] ; then
OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
fi
# Now convert the arguments - kludge to limit ourselves to /bin/sh
i=0
for arg in "$@" ; do
CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
# Escape application args
save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
exec "$JAVACMD" "$@"
================================================
FILE: gradlew.bat
================================================
@rem
@rem Copyright 2015 the original author or authors.
@rem
@rem Licensed under the Apache License, Version 2.0 (the "License");
@rem you may not use this file except in compliance with the License.
@rem You may obtain a copy of the License at
@rem
@rem https://www.apache.org/licenses/LICENSE-2.0
@rem
@rem Unless required by applicable law or agreed to in writing, software
@rem distributed under the License is distributed on an "AS IS" BASIS,
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@rem See the License for the specific language governing permissions and
@rem limitations under the License.
@rem
@if "%DEBUG%" == "" @echo off
@rem ##########################################################################
@rem
@rem Gradle startup script for Windows
@rem
@rem ##########################################################################
@rem Set local scope for the variables with windows NT shell
if "%OS%"=="Windows_NT" setlocal
set DIRNAME=%~dp0
if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:findJavaFromJavaHome
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
echo.
echo Please set the JAVA_HOME variable in your environment to match the
echo location of your Java installation.
goto fail
:execute
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell
if "%ERRORLEVEL%"=="0" goto mainEnd
:fail
rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
rem the _cmd.exe /c_ return code!
if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
exit /b 1
:mainEnd
if "%OS%"=="Windows_NT" endlocal
:omega
================================================
FILE: settings.gradle
================================================
pluginManagement {
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
}
}
rootProject.name = "scrfdncnn"
include ':app'
gitextract_t36i4fjw/ ├── .github/ │ └── workflows/ │ └── release-apk.yml ├── README.md ├── app/ │ ├── build.gradle │ └── src/ │ └── main/ │ ├── AndroidManifest.xml │ ├── assets/ │ │ ├── scrfd_10g-opt2.param │ │ ├── scrfd_10g_kps-opt2.param │ │ ├── scrfd_1g-opt2.param │ │ ├── scrfd_2.5g-opt2.param │ │ ├── scrfd_2.5g_kps-opt2.param │ │ ├── scrfd_34g-opt2.param │ │ ├── scrfd_500m-opt2.param │ │ └── scrfd_500m_kps-opt2.param │ ├── java/ │ │ └── com/ │ │ └── tencent/ │ │ └── scrfdncnn/ │ │ ├── MainActivity.java │ │ └── SCRFDNcnn.java │ ├── jni/ │ │ ├── CMakeLists.txt │ │ ├── ndkcamera.cpp │ │ ├── ndkcamera.h │ │ ├── scrfd.cpp │ │ ├── scrfd.h │ │ └── scrfdncnn.cpp │ └── res/ │ ├── layout/ │ │ └── main.xml │ └── values/ │ └── strings.xml ├── build.gradle ├── gradle/ │ └── wrapper/ │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── gradlew ├── gradlew.bat └── settings.gradle
SYMBOL INDEX (42 symbols across 7 files)
FILE: app/src/main/java/com/tencent/scrfdncnn/MainActivity.java
class MainActivity (line 35) | public class MainActivity extends Activity implements SurfaceHolder.Call...
method onCreate (line 50) | @Override
method reload (line 117) | private void reload()
method surfaceChanged (line 126) | @Override
method surfaceCreated (line 132) | @Override
method surfaceDestroyed (line 137) | @Override
method onResume (line 142) | @Override
method onPause (line 155) | @Override
FILE: app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java
class SCRFDNcnn (line 20) | public class SCRFDNcnn
method loadModel (line 22) | public native boolean loadModel(AssetManager mgr, int modelid, int cpu...
method openCamera (line 23) | public native boolean openCamera(int facing);
method closeCamera (line 24) | public native boolean closeCamera();
method setOutputWindow (line 25) | public native boolean setOutputWindow(Surface surface);
FILE: app/src/main/jni/ndkcamera.cpp
function onDisconnected (line 25) | static void onDisconnected(void* context, ACameraDevice* device)
function onError (line 30) | static void onError(void* context, ACameraDevice* device, int error)
function onImageAvailable (line 35) | static void onImageAvailable(void* context, AImageReader* reader)
function onSessionActive (line 130) | static void onSessionActive(void* context, ACameraCaptureSession *session)
function onSessionReady (line 135) | static void onSessionReady(void* context, ACameraCaptureSession *session)
function onSessionClosed (line 140) | static void onSessionClosed(void* context, ACameraCaptureSession *session)
function onCaptureFailed (line 145) | void onCaptureFailed(void* context, ACameraCaptureSession* session, ACap...
function onCaptureSequenceCompleted (line 150) | void onCaptureSequenceCompleted(void* context, ACameraCaptureSession* se...
function onCaptureSequenceAborted (line 155) | void onCaptureSequenceAborted(void* context, ACameraCaptureSession* sess...
function onCaptureCompleted (line 160) | void onCaptureCompleted(void* context, ACameraCaptureSession* session, A...
FILE: app/src/main/jni/ndkcamera.h
function class (line 28) | class NdkCamera
function class (line 58) | class NdkCameraWindow : public NdkCamera
FILE: app/src/main/jni/scrfd.cpp
function intersection_area (line 23) | static inline float intersection_area(const FaceObject& a, const FaceObj...
function qsort_descent_inplace (line 29) | static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects, ...
function qsort_descent_inplace (line 66) | static void qsort_descent_inplace(std::vector<FaceObject>& faceobjects)
function nms_sorted_bboxes (line 74) | static void nms_sorted_bboxes(const std::vector<FaceObject>& faceobjects...
function generate_anchors (line 109) | static ncnn::Mat generate_anchors(int base_size, const ncnn::Mat& ratios...
function generate_proposals (line 146) | static void generate_proposals(const ncnn::Mat& anchors, int feat_stride...
FILE: app/src/main/jni/scrfd.h
type FaceObject (line 22) | struct FaceObject
function class (line 29) | class SCRFD
FILE: app/src/main/jni/scrfdncnn.cpp
function draw_unsupported (line 40) | static int draw_unsupported(cv::Mat& rgb)
function draw_fps (line 59) | static int draw_fps(cv::Mat& rgb)
class MyNdkCamera (line 116) | class MyNdkCamera : public NdkCameraWindow
function JNIEXPORT (line 148) | JNIEXPORT jint JNI_OnLoad(JavaVM* vm, void* reserved)
function JNIEXPORT (line 157) | JNIEXPORT void JNI_OnUnload(JavaVM* vm, void* reserved)
function JNIEXPORT (line 173) | JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_loadMode...
function JNIEXPORT (line 221) | JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_openCame...
function JNIEXPORT (line 234) | JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_closeCam...
function JNIEXPORT (line 244) | JNIEXPORT jboolean JNICALL Java_com_tencent_scrfdncnn_SCRFDNcnn_setOutpu...
Condensed preview — 28 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (175K chars).
[
{
"path": ".github/workflows/release-apk.yml",
"chars": 2708,
"preview": "name: release-apk\non: workflow_dispatch\n\nenv:\n NCNN_VERSION: 20260113\n OPENCV_VERSION: 4.13.0\n OPENCV_MOBILE_TAG: v35"
},
{
"path": "README.md",
"chars": 1289,
"preview": "# ncnn-android-scrfd\n\nThe SCRFD face detection\n\nThis is a sample ncnn android project, it depends on ncnn library and op"
},
{
"path": "app/build.gradle",
"chars": 777,
"preview": "plugins {\n id 'com.android.application'\n}\n\nandroid {\n namespace 'com.tencent.scrfdncnn'\n compileSdk 33\n ndkV"
},
{
"path": "app/src/main/AndroidManifest.xml",
"chars": 798,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<manifest xmlns:android=\"http://schemas.android.com/apk/res/android\"\n androi"
},
{
"path": "app/src/main/assets/scrfd_10g-opt2.param",
"chars": 11202,
"preview": "7767517\n133 154\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_10g_kps-opt2.param",
"chars": 10286,
"preview": "7767517\n118 142\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_1g-opt2.param",
"chars": 8460,
"preview": "7767517\n99 108\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_2.5g-opt2.param",
"chars": 10897,
"preview": "7767517\n129 151\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_2.5g_kps-opt2.param",
"chars": 10404,
"preview": "7767517\n120 145\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_34g-opt2.param",
"chars": 27841,
"preview": "7767517\n323 375\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_500m-opt2.param",
"chars": 8832,
"preview": "7767517\n103 112\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/assets/scrfd_500m_kps-opt2.param",
"chars": 7236,
"preview": "7767517\n79 91\nInput input.1 0 1 input.1\nConvolution Conv_0 "
},
{
"path": "app/src/main/java/com/tencent/scrfdncnn/MainActivity.java",
"chars": 4843,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/java/com/tencent/scrfdncnn/SCRFDNcnn.java",
"chars": 1133,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/jni/CMakeLists.txt",
"chars": 446,
"preview": "project(scrfdncnn)\n\ncmake_minimum_required(VERSION 3.10)\n\nset(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.13.0-androi"
},
{
"path": "app/src/main/jni/ndkcamera.cpp",
"chars": 24105,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/jni/ndkcamera.h",
"chars": 2328,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/jni/scrfd.cpp",
"chars": 16431,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/jni/scrfd.h",
"chars": 1330,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/jni/scrfdncnn.cpp",
"chars": 6199,
"preview": "// Tencent is pleased to support the open source community by making ncnn available.\n//\n// Copyright (C) 2021 THL A29 Li"
},
{
"path": "app/src/main/res/layout/main.xml",
"chars": 1449,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<LinearLayout xmlns:android=\"http://schemas.android.com/apk/res/android\"\n "
},
{
"path": "app/src/main/res/values/strings.xml",
"chars": 493,
"preview": "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n<resources>\n <string name=\"app_name\">scrfdncnn</string>\n <string-array name"
},
{
"path": "build.gradle",
"chars": 169,
"preview": "// Top-level build file where you can add configuration options common to all sub-projects/modules.\nplugins {\nid 'com.an"
},
{
"path": "gradle/wrapper/gradle-wrapper.properties",
"chars": 231,
"preview": "#Wed Dec 25 17:36:46 CST 2024\ndistributionBase=GRADLE_USER_HOME\ndistributionPath=wrapper/dists\ndistributionUrl=https\\://"
},
{
"path": "gradlew",
"chars": 5766,
"preview": "#!/usr/bin/env sh\n\n#\n# Copyright 2015 the original author or authors.\n#\n# Licensed under the Apache License, Version 2.0"
},
{
"path": "gradlew.bat",
"chars": 2763,
"preview": "@rem\r\n@rem Copyright 2015 the original author or authors.\r\n@rem\r\n@rem Licensed under the Apache License, Version 2.0 (th"
},
{
"path": "settings.gradle",
"chars": 327,
"preview": "pluginManagement {\n repositories {\n google()\n mavenCentral()\n gradlePluginPortal()\n }\n}\ndepen"
}
]
// ... and 1 more files (download for full content)
About this extraction
This page contains the full source code of the nihui/ncnn-android-scrfd GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 28 files (164.8 KB), approximately 56.8k tokens, and a symbol index with 42 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.