Skip to content

Commit

Permalink
Support Android APP
Browse files Browse the repository at this point in the history
  • Loading branch information
triple-Mu authored and Chilicyy committed Apr 29, 2023
1 parent 160822d commit 8137950
Show file tree
Hide file tree
Showing 30 changed files with 4,210 additions and 0 deletions.
37 changes: 37 additions & 0 deletions deploy/NCNN/Android/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
# ncnn-android-yolov6

The yolov6 object detection in `Android` .

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


## 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

## Reference:
https://github.com/nihui/ncnn-android-nanodet
https://github.com/Tencent/ncnn
29 changes: 29 additions & 0 deletions deploy/NCNN/Android/app/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apply plugin: 'com.android.application'

android {
compileSdkVersion 24
buildToolsVersion "29.0.2"

defaultConfig {
applicationId "com.tencent.yolov6ncnn"
archivesBaseName = "$applicationId"

minSdkVersion 24
}

externalNativeBuild {
cmake {
version "3.10.2"
path file('src/main/jni/CMakeLists.txt')
}
}

dependencies {
implementation 'com.android.support:support-v4:24.0.0'
}
ndkVersion '24.0.8215888'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
}
19 changes: 19 additions & 0 deletions deploy/NCNN/Android/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.tencent.yolov6ncnn"
android:versionCode="1"
android:versionName="1.1">
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera2.full" />

<application android:label="@string/app_name">
<activity android:name="MainActivity"
android:label="@string/app_name"
android:screenOrientation="portrait">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
Binary file not shown.
379 changes: 379 additions & 0 deletions deploy/NCNN/Android/app/src/main/assets/yolov6-lite-l0.param

Large diffs are not rendered by default.

Binary file not shown.
379 changes: 379 additions & 0 deletions deploy/NCNN/Android/app/src/main/assets/yolov6-lite-l1.param

Large diffs are not rendered by default.

Binary file not shown.
379 changes: 379 additions & 0 deletions deploy/NCNN/Android/app/src/main/assets/yolov6-lite-l2.param

Large diffs are not rendered by default.

Binary file not shown.
379 changes: 379 additions & 0 deletions deploy/NCNN/Android/app/src/main/assets/yolov6-lite-m.param

Large diffs are not rendered by default.

Binary file not shown.
379 changes: 379 additions & 0 deletions deploy/NCNN/Android/app/src/main/assets/yolov6-lite-s.param

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,162 @@
// 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.yolov6ncnn;

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 Yolov6Ncnn yolov6ncnn = new Yolov6Ncnn();
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;

yolov6ncnn.closeCamera();

yolov6ncnn.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 = yolov6ncnn.loadModel(getAssets(), current_model, current_cpugpu);
if (!ret_init)
{
Log.e("MainActivity", "yolov6ncnn loadModel failed");
}
}

@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height)
{
yolov6ncnn.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);
}

yolov6ncnn.openCamera(facing);
}

@Override
public void onPause()
{
super.onPause();

yolov6ncnn.closeCamera();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// 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.yolov6ncnn;

import android.content.res.AssetManager;
import android.view.Surface;

public class Yolov6Ncnn
{
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("yolov6ncnn");
}
}
13 changes: 13 additions & 0 deletions deploy/NCNN/Android/app/src/main/jni/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
project(yolov6ncnn)

cmake_minimum_required(VERSION 3.10)

set(OpenCV_DIR ${CMAKE_SOURCE_DIR}/opencv-mobile-4.6.0-android/sdk/native/jni)
find_package(OpenCV REQUIRED core imgproc)

set(ncnn_DIR ${CMAKE_SOURCE_DIR}/ncnn-20230223-android-vulkan/${ANDROID_ABI}/lib/cmake/ncnn)
find_package(ncnn REQUIRED)

add_library(yolov6ncnn SHARED yolov6ncnn.cpp yolo.cpp ndkcamera.cpp)

target_link_libraries(yolov6ncnn ncnn ${OpenCV_LIBS} camera2ndk mediandk)
Loading

0 comments on commit 8137950

Please sign in to comment.