Full Code of nihui/ncnn-android-scrfd for AI

master f94e2630ac1b cached
28 files
164.8 KB
56.8k tokens
42 symbols
1 requests
Download .txt
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
![](screenshot.jpg)



================================================
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'
Download .txt
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
Download .txt
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.

Copied to clipboard!