Skip to content

Commit 3faa1b8

Browse files
Merge pull request #2321 from HydrogenSulfate/add_shitu_android_demo2
Add shitu android demo2
2 parents d2a3740 + b965d49 commit 3faa1b8

File tree

89 files changed

+5235
-1
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

89 files changed

+5235
-1
lines changed

deploy/shitu_android_demo/app/app.iml

Lines changed: 183 additions & 0 deletions
Large diffs are not rendered by default.
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import java.security.MessageDigest
2+
3+
apply plugin: 'com.android.application'
4+
5+
android {
6+
compileSdkVersion 30
7+
defaultConfig {
8+
applicationId "com.baidu.paddle.lite.demo.pp_shitu"
9+
minSdkVersion 15
10+
targetSdkVersion 30
11+
versionCode 1
12+
versionName "1.0"
13+
testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
14+
externalNativeBuild {
15+
cmake {
16+
arguments '-DANDROID_PLATFORM=android-23', '-DANDROID_STL=c++_shared', "-DANDROID_TOOLCHAIN="
17+
abiFilters 'arm64-v8a'
18+
cppFlags "-std=c++11"
19+
}
20+
}
21+
}
22+
buildTypes {
23+
release {
24+
minifyEnabled false
25+
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
26+
}
27+
}
28+
externalNativeBuild {
29+
cmake {
30+
path "src/main/cpp/CMakeLists.txt"
31+
version "3.18.1"
32+
}
33+
}
34+
}
35+
36+
dependencies {
37+
implementation fileTree(include: ['*.jar'], dir: 'libs')
38+
implementation 'com.android.support:appcompat-v7:28.0.0'
39+
implementation 'com.android.support.constraint:constraint-layout:1.1.3'
40+
implementation 'com.android.support:design:28.0.0'
41+
testImplementation 'junit:junit:4.12'
42+
androidTestImplementation 'com.android.support.test:runner:1.0.2'
43+
androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
44+
}
45+
tasks.withType(JavaCompile) {
46+
options.encoding = "UTF-8"
47+
}
48+
def archives = [
49+
[
50+
'src' : 'https://paddlelite-demo.bj.bcebos.com/libs/android/paddle_lite_libs_v2_10_gpu.tar.gz',
51+
'dest': 'PaddleLite'
52+
],
53+
[
54+
'src' : 'https://paddlelite-demo.bj.bcebos.com/libs/android/opencv-4.2.0-android-sdk.tar.gz',
55+
'dest': 'OpenCV'
56+
],
57+
[
58+
'src' : 'https://paddlelite-demo.bj.bcebos.com/demo/PP_shitu/models/ppshitu_lite_models_v1.0.tar.gz',
59+
'dest' : 'src/main/assets/models'
60+
]
61+
]
62+
63+
task downloadAndExtractArchives(type: DefaultTask) {
64+
doFirst {
65+
println "Downloading and extracting archives including libs and models"
66+
}
67+
doLast {
68+
// Prepare cache folder for archives
69+
String cachePath = "cache"
70+
if (!file("${cachePath}").exists()) {
71+
mkdir "${cachePath}"
72+
}
73+
archives.eachWithIndex { archive, index ->
74+
MessageDigest messageDigest = MessageDigest.getInstance('MD5')
75+
messageDigest.update(archive.src.bytes)
76+
String cacheName = new BigInteger(1, messageDigest.digest()).toString(32)
77+
// Download the target archive if not exists
78+
boolean copyFiles = !file("${archive.dest}").exists()
79+
if (!file("${cachePath}/${cacheName}.tar.gz").exists()) {
80+
ant.get(src: archive.src, dest: file("${cachePath}/${cacheName}.tar.gz"))
81+
copyFiles = true; // force to copy files from the latest archive files
82+
}
83+
// Extract the target archive if its dest path does not exists
84+
if (copyFiles) {
85+
copy {
86+
from tarTree("${cachePath}/${cacheName}.tar.gz")
87+
into "${archive.dest}"
88+
}
89+
}
90+
}
91+
}
92+
}
93+
preBuild.dependsOn downloadAndExtractArchives
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
# Add project specific ProGuard rules here.
2+
# You can control the set of applied configuration files using the
3+
# proguardFiles setting in build.gradle.
4+
#
5+
# For more details, see
6+
# http://developer.android.com/guide/developing/tools/proguard.html
7+
8+
# If your project uses WebView with JS, uncomment the following
9+
# and specify the fully qualified class name to the JavaScript interface
10+
# class:
11+
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
12+
# public *;
13+
#}
14+
15+
# Uncomment this to preserve the line number information for
16+
# debugging stack traces.
17+
#-keepattributes SourceFile,LineNumberTable
18+
19+
# If you keep the line number information, uncomment this to
20+
# hide the original source file name.
21+
#-renamesourcefileattribute SourceFile
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
package com.baidu.paddle.lite.demo.pp_shitu;
2+
3+
import android.content.Context;
4+
import android.support.test.InstrumentationRegistry;
5+
import android.support.test.runner.AndroidJUnit4;
6+
7+
import org.junit.Test;
8+
import org.junit.runner.RunWith;
9+
10+
import static org.junit.Assert.*;
11+
12+
/**
13+
* Instrumented test, which will execute on an Android device.
14+
*
15+
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
16+
*/
17+
@RunWith(AndroidJUnit4.class)
18+
public class ExampleInstrumentedTest {
19+
@Test
20+
public void useAppContext() {
21+
// Context of the app under test.
22+
Context appContext = InstrumentationRegistry.getTargetContext();
23+
24+
assertEquals("com.baidu.paddle.lite.demo", appContext.getPackageName());
25+
}
26+
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?xml version="1.0" encoding="utf-8"?>
2+
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
3+
xmlns:tools="http://schemas.android.com/tools"
4+
package="com.baidu.paddle.lite.demo.pp_shitu">
5+
6+
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"
7+
tools:ignore="ScopedStorage" />
8+
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
9+
<uses-permission android:name="android.permission.CAMERA"/>
10+
<uses-feature android:name="android.hardware.camera" />
11+
<uses-feature android:name="android.hardware.camera.autofocus" android:required="false"/>
12+
13+
<application
14+
android:allowBackup="true"
15+
android:icon="@mipmap/ic_launcher"
16+
android:label="@string/app_name"
17+
android:roundIcon="@mipmap/ic_launcher_round"
18+
android:supportsRtl="true"
19+
android:theme="@style/AppTheme">
20+
<activity android:name="com.baidu.paddle.lite.demo.pp_shitu.MainActivity"
21+
android:exported="true">
22+
<intent-filter>
23+
<action android:name="android.intent.action.MAIN"/>
24+
25+
<category android:name="android.intent.category.LAUNCHER"/>
26+
</intent-filter>
27+
</activity>
28+
<activity
29+
android:name="com.baidu.paddle.lite.demo.pp_shitu.SettingsActivity"
30+
android:label="Settings">
31+
</activity>
32+
</application>
33+
34+
</manifest>
347 KB
Loading
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
put `*.index` and `*.txt` here. such as `original.index` and `original.txt`
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
put `*.nb` inference model file there. such as `general_PPLCNetV2_base_quant_v1.0_lite.nb` and `mainbody_PPLCNet_x2_5_640_quant_v1.0_lite.nb`
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# For more information about using CMake with Android Studio, read the
2+
# documentation: https://d.android.com/studio/projects/add-native-code.html
3+
4+
# Sets the minimum version of CMake required to build the native library.
5+
#project(ShituDemo)
6+
7+
cmake_minimum_required(VERSION 3.4.1)
8+
9+
# Creates and names a library, sets it as either STATIC or SHARED, and provides
10+
# the relative paths to its source code. You can define multiple libraries, and
11+
# CMake builds them for you. Gradle automatically packages shared libraries with
12+
# your APK.
13+
14+
set(PaddleLite_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../PaddleLite")
15+
include_directories(${PaddleLite_DIR}/cxx/include)
16+
17+
set(OpenCV_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../OpenCV/sdk/native/jni")
18+
find_package(OpenCV REQUIRED)
19+
message(STATUS "OpenCV libraries: ${OpenCV_LIBS}")
20+
include_directories(${OpenCV_INCLUDE_DIRS})
21+
22+
#set(PaddleLite_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../PaddleLite")
23+
24+
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/../../../PaddleLite/src/main/cpp/include/faiss)
25+
set(target faiss)
26+
27+
set(CMAKE_CXX_FLAGS
28+
"${CMAKE_CXX_FLAGS} -ffast-math -Ofast -Os -DNDEBUG -fexceptions -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables"
29+
)
30+
set(CMAKE_CXX_FLAGS
31+
"${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -fdata-sections -ffunction-sections"
32+
)
33+
set(CMAKE_SHARED_LINKER_FLAGS
34+
"${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,-z,nocopyreloc")
35+
36+
add_library(
37+
# Sets the name of the library.
38+
Native
39+
# Sets the library as a shared library.
40+
SHARED
41+
# Provides a relative path to your source file(s).
42+
Native.cc Pipeline.cc Utils.cc ObjectDetector.cc FeatureExtractor.cc VectorSearch.cc)
43+
44+
find_library(
45+
# Sets the name of the path variable.
46+
log-lib
47+
# Specifies the name of the NDK library that you want CMake to locate.
48+
log)
49+
50+
add_library(
51+
# Sets the name of the library.
52+
paddle_light_api_shared
53+
# Sets the library as a shared library.
54+
SHARED
55+
# Provides a relative path to your source file(s).
56+
IMPORTED)
57+
58+
add_library(
59+
# Sets the name of the library.
60+
faiss
61+
STATIC
62+
IMPORTED)
63+
64+
set_target_properties(
65+
# Specifies the target library.
66+
paddle_light_api_shared
67+
# Specifies the parameter you want to define.
68+
PROPERTIES
69+
IMPORTED_LOCATION
70+
${PaddleLite_DIR}/cxx/libs/${ANDROID_ABI}/libpaddle_light_api_shared.so
71+
# Provides the path to the library you want to import.
72+
)
73+
74+
# if there libfaiss.a not exist, will download it automatically
75+
IF(NOT ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/main/jniLibs/arm64-v8a/libfaiss.a)
76+
message(STATUS "Downloading ${OCI_LIB_ZIP_NAME} to ${CMAKE_CURRENT_SOURCE_DIR}/../../../src/main/jniLibs/arm64-v8a/")
77+
FILE(DOWNLOAD https://paddle-imagenet-models-name.bj.bcebos.com/demos/lib/libfaiss.a
78+
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/main/jniLibs/arm64-v8a/libfaiss.a
79+
TIMEOUT ${DOWNLOAD_OCI_LIB_TIMEOUT}
80+
STATUS ERR
81+
SHOW_PROGRESS)
82+
ENDIF()
83+
84+
set_target_properties(
85+
faiss
86+
PROPERTIES
87+
IMPORTED_LOCATION
88+
${CMAKE_CURRENT_SOURCE_DIR}/../../../src/main/jniLibs/arm64-v8a/libfaiss.a
89+
)
90+
91+
# Specifies libraries CMake should link to your target library. You can link
92+
# multiple libraries, such as libraries you define in this build script,
93+
# prebuilt third-party libraries, or system libraries.
94+
95+
target_link_libraries(
96+
# Specifies the target library.
97+
Native
98+
paddle_light_api_shared
99+
jnigraphics
100+
${OpenCV_LIBS}
101+
GLESv2
102+
EGL
103+
${log-lib}
104+
faiss
105+
)
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
15+
#include "FeatureExtractor.h" // NOLINT
16+
#include <utility> // NOLINT
17+
18+
void FeatureExtract::RunRecModel(const cv::Mat &img, double &cost_time,
19+
std::vector<float> &feature) {
20+
// Read img
21+
cv::Mat img_fp;
22+
ResizeImage(img, img_fp);
23+
NormalizeImage(&img_fp, this->mean_, this->std_, this->scale_);
24+
std::vector<float> input(1 * 3 * img_fp.rows * img_fp.cols, 0.0f);
25+
Permute(&img_fp, input.data());
26+
auto pre_cost0 = GetCurrentUS();
27+
28+
// Prepare input data from image
29+
std::unique_ptr<Tensor> input_tensor(
30+
std::move(this->predictor_->GetInput(0)));
31+
input_tensor->Resize({1, 3, this->size, this->size});
32+
auto *data0 = input_tensor->mutable_data<float>();
33+
34+
for (int i = 0; i < input.size(); ++i) {
35+
data0[i] = input[i];
36+
}
37+
auto start = std::chrono::system_clock::now();
38+
// Run predictor
39+
this->predictor_->Run();
40+
41+
// Get output and post process
42+
std::unique_ptr<const Tensor> output_tensor(
43+
std::move(this->predictor_->GetOutput(0)));
44+
auto end = std::chrono::system_clock::now();
45+
auto duration =
46+
std::chrono::duration_cast<std::chrono::microseconds>(end - start);
47+
cost_time = double(duration.count()) *
48+
std::chrono::microseconds::period::num /
49+
std::chrono::microseconds::period::den;
50+
51+
// do postprocess
52+
int output_size = 1;
53+
for (auto dim : output_tensor->shape()) {
54+
output_size *= dim;
55+
}
56+
feature.resize(output_size);
57+
output_tensor->CopyToCpu(feature.data());
58+
59+
// postprocess include sqrt or binarize.
60+
FeatureNorm(feature);
61+
}
62+
63+
void FeatureExtract::FeatureNorm(std::vector<float> &feature) {
64+
float feature_sqrt = std::sqrt(std::inner_product(
65+
feature.begin(), feature.end(), feature.begin(), 0.0f));
66+
for (int i = 0; i < feature.size(); ++i) {
67+
feature[i] /= feature_sqrt;
68+
}
69+
}
70+
71+
void FeatureExtract::Permute(const cv::Mat *im, float *data) {
72+
int rh = im->rows;
73+
int rw = im->cols;
74+
int rc = im->channels();
75+
for (int i = 0; i < rc; ++i) {
76+
cv::extractChannel(*im, cv::Mat(rh, rw, CV_32FC1, data + i * rh * rw), i);
77+
}
78+
}
79+
80+
void FeatureExtract::ResizeImage(const cv::Mat &img, cv::Mat &resize_img) {
81+
cv::resize(img, resize_img, cv::Size(this->size, this->size));
82+
}
83+
84+
void FeatureExtract::NormalizeImage(cv::Mat *im, const std::vector<float> &mean,
85+
const std::vector<float> &std,
86+
float scale) {
87+
(*im).convertTo(*im, CV_32FC3, scale);
88+
for (int h = 0; h < im->rows; h++) {
89+
for (int w = 0; w < im->cols; w++) {
90+
im->at<cv::Vec3f>(h, w)[0] =
91+
(im->at<cv::Vec3f>(h, w)[0] - mean[0]) / std[0];
92+
im->at<cv::Vec3f>(h, w)[1] =
93+
(im->at<cv::Vec3f>(h, w)[1] - mean[1]) / std[1];
94+
im->at<cv::Vec3f>(h, w)[2] =
95+
(im->at<cv::Vec3f>(h, w)[2] - mean[2]) / std[2];
96+
}
97+
}
98+
}

0 commit comments

Comments
 (0)