-
Notifications
You must be signed in to change notification settings - Fork 90
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: QAIHM Team <[email protected]>
- Loading branch information
Showing
857 changed files
with
21,748 additions
and
4,591 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,3 @@ | ||
*.jpg filter=lfs diff=lfs merge=lfs -text | ||
*.png filter=lfs diff=lfs merge=lfs -text | ||
*.jar filter=lfs diff=lfs merge=lfs -text |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
### Requirements | ||
|
||
1. Java, android-sdk and sdkmanager is already set at user's end | ||
2. User should have Linux QNN SDK in local machine. | ||
|
||
|
||
## Info | ||
Right now we use mobilenet_v3_small.tflite model which takes 224x224 as input and gives array of 1000 as output. You can replace it with any tflite classification model, but you have to change the pre-processing, post-processing and dimensions in the app code based on model parameters. | ||
|
||
|
||
## Preprocessing | ||
|
||
|
||
``` | ||
for (int x = 0; x < input_dims1; x++) { | ||
for (int y = 0; y < input_dims2; y++) { | ||
int pixel = inputBitmap.getPixel(x, y); | ||
List<Float> rgb = Arrays.asList((float)Color.red(pixel), (float)Color.green(pixel), (float)Color.blue(pixel)); | ||
for(int z = 0;z<3; z++){ | ||
floatinputarray[0][z][x][y] = (float)((rgb.get(z))-ImageMean.get(z))/ImageStd.get(z); | ||
} | ||
} | ||
} | ||
``` | ||
|
||
|
||
## PostProcessing | ||
|
||
|
||
``` | ||
public static List<Integer> findTop3Indices(float[] arr) { | ||
List<Integer> topIndices = new ArrayList<>(); | ||
for (int i = 0; i < 3; i++) { | ||
int maxIndex = 0; | ||
float maxValue = arr[0]; | ||
for (int j = 1; j < arr.length; j++) { | ||
if (arr[j] > maxValue && !topIndices.contains(j)) { | ||
maxValue = arr[j]; | ||
maxIndex = j; | ||
} | ||
} | ||
topIndices.add(maxIndex); | ||
} | ||
return topIndices; | ||
} | ||
``` | ||
|
||
### Build App: | ||
|
||
You have to run build_apk.py for Image Classification. It will generate classification-debug.apk and install it in connected device. | ||
|
||
|
||
build_apk.py [-h] -q QNNSDK (-m MODEL_PATH | -e MODEL_NAME) | ||
|
||
|
||
|
||
### Example | ||
|
||
Here, with -m, give your tflite model path i.e. till `*.tflite file`, and it will copy model file to assets folder to build andoid app. | ||
``` | ||
python build_apk.py -q "<QNN_SDK_PATH>" -m "Path\to\TFLITE\Model" | ||
``` | ||
|
||
Also, you can use AI-HUB Model name as mentioned in models directory, to directly export the model from AI-Hub and copy it to app assets. | ||
|
||
``` | ||
python build_apk.py -q "<QNN_SDK_PATH>" -e <Model Name> | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
|
||
// Top-level build file where you can add configuration options common to all sub-projects/modules. | ||
plugins { | ||
id 'com.android.application' version '7.2.1' apply false | ||
id 'com.android.library' version '7.2.1' apply false | ||
} | ||
|
||
task clean(type: Delete) { | ||
delete rootProject.buildDir | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,163 @@ | ||
# --------------------------------------------------------------------- | ||
# Copyright (c) 2024 Qualcomm Innovation Center, Inc. All rights reserved. | ||
# SPDX-License-Identifier: BSD-3-Clause | ||
# --------------------------------------------------------------------- | ||
import argparse | ||
import glob | ||
import os | ||
import shutil | ||
import subprocess | ||
import sys | ||
from enum import Enum | ||
|
||
|
||
class MODELNAME(Enum): | ||
mobilenet_v3_large = 1 | ||
resnet50 = 2 | ||
resnext50 = 3 | ||
inception_v3 = 4 | ||
|
||
|
||
def printmenu(): | ||
print("*****************************") | ||
print("* TYPE OF MODEL *") | ||
print("*****************************") | ||
for m in MODELNAME: | ||
print(str(m.value) + ". " + m.name) | ||
print("*****************************") | ||
|
||
|
||
## Initialize parser | ||
parser = argparse.ArgumentParser() | ||
parser.add_argument("-q", "--qnnsdk", required=True, help="Give path of QNN SDK") | ||
|
||
parser.add_argument("-m", "--model_name", type=str, help="Model Name") | ||
|
||
|
||
# group = parser.add_mutually_exclusive_group() | ||
# group.add_argument('-stopdownload', '--stopdownload', action = "store_true", help = "Do NOT Download Model from AI HUB") | ||
parser.add_argument("-path", "--model_path", type=str, help="TFLITE model file") | ||
|
||
args = parser.parse_args() | ||
|
||
|
||
##based on this pre-post can be decided | ||
if not args.model_name: | ||
printmenu() | ||
inp_model_name = int(input("Please select one: ")) | ||
args.model_name = MODELNAME(inp_model_name).name | ||
|
||
|
||
destAsset = os.path.join(".", "classification", "src", "main", "assets") | ||
if not os.path.exists(destAsset): | ||
os.makedirs(destAsset) | ||
|
||
|
||
## MODEL PATH NOT MENTIONED, add information into model_path | ||
if not args.model_path: | ||
exportstatus = input("Do you want us to download the model from AI hub (y/n)") | ||
|
||
##DOWNLAOD USING EXPORT.PY | ||
if exportstatus.lower().startswith("y"): | ||
print("EXPORT form path") | ||
pathtomodel = os.path.join( | ||
"..", | ||
"..", | ||
"..", | ||
"", | ||
"qai_hub_models", | ||
"models", | ||
args.model_name, | ||
"export.py", | ||
) | ||
if not os.path.exists(pathtomodel): | ||
print("PATH DO NOT EXIST: " + pathtomodel) | ||
exit() | ||
subprocess.run(["python", pathtomodel, "--skip-inferencing"]) | ||
tflite_file = glob.glob( | ||
"build" + os.sep + args.model_name + os.sep + "*.tflite", recursive=True | ||
) | ||
args.model_path = tflite_file[0] | ||
# shutil.copy(tflite_file[0], destAsset+os.sep+"superresmodel.tflite") | ||
|
||
##GET USER TO GIVE PATH | ||
else: | ||
args.model_path = input("Give model File as input") | ||
# if not os.path.exists(tflite_file): | ||
# print("PATH DO NOT EXIST: "+tflite_file) | ||
# exit() | ||
# shutil.copy(tflite_file, destAsset+os.sep+"superresmodel.tflite") | ||
|
||
|
||
if args.model_path: | ||
print(args.model_path) | ||
if not os.path.exists(args.model_path): | ||
print("PATH DO NOT EXIST: " + args.model_path) | ||
exit() | ||
shutil.copy(args.model_path, destAsset + os.sep + "classification.tflite") | ||
|
||
|
||
## COPYING REQUIRED FILES FROM QNN SDK | ||
destJNI = os.path.join(".", "classification", "src", "main", "jniLibs", "arm64-v8a") | ||
if not os.path.exists(destJNI): | ||
os.makedirs(destJNI) | ||
|
||
# copy *.so from $qnn_sdk/libs/aarch64-android to $jni_lib_dir | ||
qnnbasiclibs = os.path.join(args.qnnsdk, "lib", "aarch64-android") | ||
shutil.copytree(qnnbasiclibs, destJNI, dirs_exist_ok=True) | ||
|
||
# copy $qnn_sdk/lib/hexagon-v**/unsigned/libQnnHtpV**Skel.so to $jni_lib_dir | ||
skelstubfiles = os.path.join(args.qnnsdk, "lib", "hexagon-v**", "unsigned", "*.so") | ||
for file in glob.glob(skelstubfiles): | ||
shutil.copy(file, destJNI) | ||
|
||
# copy qtld-release.aar to $test_app_root/Application/ | ||
destaar = os.path.join(".", "classification", "libs") | ||
if not os.path.exists(destaar): | ||
os.makedirs(destaar) | ||
aarfile = os.path.join(args.qnnsdk, "lib", "android", "qtld-release.aar") | ||
shutil.copy(aarfile, destaar) | ||
|
||
|
||
## BUILDING APK | ||
if sys.platform.startswith("win"): | ||
print("Detected platform is windows") | ||
gradleoutput = subprocess.run(["gradlew.bat", "assembleDebug"], cwd=".") | ||
elif sys.platform.startswith("darwin"): | ||
print("Detected platform is MAC") | ||
gradleoutput = subprocess.run(["./gradlew", "assembleDebug"], cwd=".") | ||
else: | ||
print("Detected platform is Linux") | ||
gradleoutput = subprocess.run(["./gradlew", "assembleDebug"], cwd=".") | ||
|
||
|
||
## COPYING APK TO CWD | ||
ApkPath = os.path.join( | ||
os.getcwd(), | ||
"classification", | ||
"build", | ||
"outputs", | ||
"apk", | ||
"debug", | ||
"classification-debug.apk", | ||
) | ||
print("APK Is copied at current Working Directory") | ||
shutil.copy(ApkPath, ".") | ||
|
||
|
||
install_perm = input("Do you want to install this apk in connected device") | ||
## INSTALLING AND RUNNING APK | ||
if install_perm.lower().startswith("y"): | ||
command_to_install = ["adb", "install", "classification-debug.apk"] | ||
subprocess.run(command_to_install, cwd=".") | ||
command_to_run = [ | ||
"adb", | ||
"shell", | ||
"am", | ||
"start", | ||
"-a", | ||
"com.example.ACTION_NAME", | ||
"-n", | ||
"com.qcom.imagesuperres/com.qcom.imagesuperres.QNNActivity", | ||
] | ||
subprocess.run(command_to_run, cwd=".") |
Oops, something went wrong.