mirror of
https://github.com/PaddlePaddle/FastDeploy.git
synced 2025-10-07 09:31:35 +08:00
[Android] Add PicoDet android jni demo (#405)
* [Android] Add picodet android jni demo * [Android] Add picodet android jni demo * [CMake] exclude jni files from examples exe srcs
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
# For more information about using CMake with Android Studio, read the
|
||||
# documentation: https://d.android.com/studio/projects/add-native-code.html
|
||||
|
||||
# Sets the minimum version of CMake required to build the native library.
|
||||
cmake_minimum_required(VERSION 3.10.2)
|
||||
|
||||
# Declares and names the project.
|
||||
project("fastdeploy_jni")
|
||||
|
||||
# Creates and names a library, sets it as either STATIC
|
||||
# or SHARED, and provides the relative paths to its source code.
|
||||
# You can define multiple libraries, and CMake builds them for you.
|
||||
# Gradle automatically packages shared libraries with your APK.
|
||||
|
||||
set(FastDeploy_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/fastdeploy-android-0.4.0-shared")
|
||||
|
||||
find_package(FastDeploy REQUIRED)
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR})
|
||||
include_directories(${FastDeploy_INCLUDE_DIRS})
|
||||
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -ffast-math -Ofast -Os -DNDEBUG -fno-exceptions -fomit-frame-pointer -fno-asynchronous-unwind-tables -fno-unwind-tables")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -fvisibility-inlines-hidden -fdata-sections -ffunction-sections")
|
||||
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--gc-sections -Wl,-z,nocopyreloc")
|
||||
|
||||
add_library(
|
||||
fastdeploy_jni
|
||||
SHARED
|
||||
utils_jni.cc
|
||||
bitmap_jni.cc
|
||||
vision/results_jni.cc
|
||||
vision/visualize_jni.cc
|
||||
vision/detection/picodet_jni.cc
|
||||
vision/classification/paddleclas_model_jni.cc)
|
||||
|
||||
# Searches for a specified prebuilt library and stores the path as a
|
||||
# variable. Because CMake includes system libraries in the search path by
|
||||
# default, you only need to specify the name of the public NDK library
|
||||
# you want to add. CMake verifies that the library exists before
|
||||
# completing its build.
|
||||
|
||||
find_library( # Sets the name of the path variable.
|
||||
log-lib
|
||||
# Specifies the name of the NDK library that
|
||||
# you want CMake to locate.
|
||||
log)
|
||||
|
||||
# Specifies libraries CMake should link to your target library. You can link
|
||||
# multiple libraries, such as libraries you define in this build script,
|
||||
# prebuilt third-party libraries, or system libraries.
|
||||
|
||||
target_link_libraries(
|
||||
# Specifies the target library.
|
||||
fastdeploy_jni
|
||||
jnigraphics
|
||||
${FASTDEPLOY_LIBS}
|
||||
GLESv2
|
||||
EGL
|
||||
${log-lib}
|
||||
)
|
@@ -0,0 +1,100 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#include "bitmap_jni.h" // NOLINT
|
||||
|
||||
#include <android/bitmap.h> // NOLINT
|
||||
|
||||
#include "utils_jni.h" // NOLINT
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace jni {
|
||||
|
||||
jboolean ARGB888Bitmap2RGBA(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
cv::Mat *c_rgba) {
|
||||
// Convert the android bitmap(ARGB8888) to the OpenCV RGBA image. Actually,
|
||||
// the data layout of ARGB8888 is R, G, B, A, it's the same as CV RGBA image,
|
||||
// so it is unnecessary to do the conversion of color format, check
|
||||
// https://developer.android.com/reference/android/graphics/Bitmap.Config#ARGB_8888
|
||||
// to get the more details about Bitmap.Config.ARGB8888
|
||||
AndroidBitmapInfo j_bitmap_info;
|
||||
if (AndroidBitmap_getInfo(env, j_argb8888_bitmap, &j_bitmap_info) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_getInfo() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
if (j_bitmap_info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
|
||||
LOGE("Only Bitmap.Config.ARGB8888 color format is supported!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
void *j_bitmap_pixels;
|
||||
if (AndroidBitmap_lockPixels(env, j_argb8888_bitmap, &j_bitmap_pixels) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_lockPixels() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
cv::Mat j_bitmap_im(static_cast<int>(j_bitmap_info.height),
|
||||
static_cast<int>(j_bitmap_info.width), CV_8UC4,
|
||||
j_bitmap_pixels);
|
||||
j_bitmap_im.copyTo(*(c_rgba));
|
||||
if (AndroidBitmap_unlockPixels(env, j_argb8888_bitmap) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_unlockPixels() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jboolean ARGB888Bitmap2BGR(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
cv::Mat *c_bgr) {
|
||||
cv::Mat c_rgba;
|
||||
if (!ARGB888Bitmap2RGBA(env, j_argb8888_bitmap, &c_rgba)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
cv::cvtColor(c_rgba, *(c_bgr), cv::COLOR_RGBA2BGR);
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jboolean RGBA2ARGB888Bitmap(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
const cv::Mat &c_rgba) {
|
||||
AndroidBitmapInfo j_bitmap_info;
|
||||
if (AndroidBitmap_getInfo(env, j_argb8888_bitmap, &j_bitmap_info) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_getInfo() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
void *j_bitmap_pixels;
|
||||
if (AndroidBitmap_lockPixels(env, j_argb8888_bitmap, &j_bitmap_pixels) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_lockPixels() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
cv::Mat j_bitmap_im(static_cast<int>(j_bitmap_info.height),
|
||||
static_cast<int>(j_bitmap_info.width), CV_8UC4,
|
||||
j_bitmap_pixels);
|
||||
c_rgba.copyTo(j_bitmap_im);
|
||||
if (AndroidBitmap_unlockPixels(env, j_argb8888_bitmap) < 0) {
|
||||
LOGE("Invoke AndroidBitmap_unlockPixels() failed!");
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
jboolean BGR2ARGB888Bitmap(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
const cv::Mat &c_bgr) {
|
||||
if (c_bgr.empty()) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
cv::Mat c_rgba;
|
||||
cv::cvtColor(c_bgr, c_rgba, cv::COLOR_BGR2RGBA);
|
||||
return RGBA2ARGB888Bitmap(env, j_argb8888_bitmap, c_rgba);
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,39 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jni.h> // NOLINT
|
||||
|
||||
#include "fastdeploy/vision.h" // NOLINT
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace jni {
|
||||
|
||||
// Convert the android bitmap(ARGB8888) to the OpenCV RGBA image. Actually,
|
||||
// the data layout of ARGB8888 is R, G, B, A, it's the same as CV RGBA image,
|
||||
// so it is unnecessary to do the conversion of color format, check
|
||||
// https://developer.android.com/reference/android/graphics/Bitmap.Config#ARGB_8888
|
||||
// to get the more details about Bitmap.Config.ARGB8888
|
||||
jboolean ARGB888Bitmap2RGBA(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
cv::Mat *c_rgba);
|
||||
jboolean RGBA2ARGB888Bitmap(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
const cv::Mat &c_rgba);
|
||||
jboolean ARGB888Bitmap2BGR(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
cv::Mat *c_bgr);
|
||||
jboolean BGR2ARGB888Bitmap(JNIEnv *env, jobject j_argb8888_bitmap,
|
||||
const cv::Mat &c_bgr);
|
||||
|
||||
} // namespace jni
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,140 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <jni.h> // NOLINT
|
||||
|
||||
#include <string> // NOLINT
|
||||
#include <vector> // NOLINT
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace jni {
|
||||
|
||||
template <typename OutputType, typename InputType>
|
||||
OutputType ConvertTo(JNIEnv *env, InputType input);
|
||||
|
||||
template <typename OutputType, typename InputType>
|
||||
OutputType ConvertTo(JNIEnv *env, const InputType *input, int64_t len);
|
||||
|
||||
/// jstring -> std::string
|
||||
template <>
|
||||
inline std::string ConvertTo(JNIEnv *env, jstring jstr) {
|
||||
// In java, a unicode char will be encoded using 2 bytes (utf16).
|
||||
// so jstring will contain characters utf16. std::string in c++ is
|
||||
// essentially a string of bytes, not characters, so if we want to
|
||||
// pass jstring from JNI to c++, we have convert utf16 to bytes.
|
||||
if (!jstr) {
|
||||
return "";
|
||||
}
|
||||
const jclass jstring_clazz = env->GetObjectClass(jstr);
|
||||
const jmethodID getBytesID =
|
||||
env->GetMethodID(jstring_clazz, "getBytes", "(Ljava/lang/String;)[B");
|
||||
const jbyteArray jstring_bytes = (jbyteArray)env->CallObjectMethod(
|
||||
jstr, getBytesID, env->NewStringUTF("UTF-8"));
|
||||
|
||||
size_t length = static_cast<size_t>(env->GetArrayLength(jstring_bytes));
|
||||
jbyte *jstring_bytes_ptr = env->GetByteArrayElements(jstring_bytes, NULL);
|
||||
|
||||
std::string res =
|
||||
std::string(reinterpret_cast<char *>(jstring_bytes_ptr), length);
|
||||
env->ReleaseByteArrayElements(jstring_bytes, jstring_bytes_ptr, JNI_ABORT);
|
||||
|
||||
env->DeleteLocalRef(jstring_bytes);
|
||||
env->DeleteLocalRef(jstring_clazz);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// std::string -> jstring
|
||||
template <>
|
||||
inline jstring ConvertTo(JNIEnv *env, std::string str) {
|
||||
auto *cstr_data_ptr = str.c_str();
|
||||
jclass jstring_clazz = env->FindClass("java/lang/String");
|
||||
jmethodID initID =
|
||||
env->GetMethodID(jstring_clazz, "<init>", "([BLjava/lang/String;)V");
|
||||
|
||||
jbyteArray jstring_bytes = env->NewByteArray(strlen(cstr_data_ptr));
|
||||
env->SetByteArrayRegion(jstring_bytes, 0, strlen(cstr_data_ptr),
|
||||
reinterpret_cast<const jbyte *>(cstr_data_ptr));
|
||||
|
||||
jstring jstring_encoding = env->NewStringUTF("UTF-8");
|
||||
jstring res = (jstring)(env->NewObject(jstring_clazz, initID, jstring_bytes,
|
||||
jstring_encoding));
|
||||
|
||||
env->DeleteLocalRef(jstring_clazz);
|
||||
env->DeleteLocalRef(jstring_bytes);
|
||||
env->DeleteLocalRef(jstring_encoding);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/// jlongArray -> std::vector<int64_t>
|
||||
template <>
|
||||
inline std::vector<int64_t> ConvertTo(JNIEnv *env, jlongArray jdata) {
|
||||
int jdata_size = env->GetArrayLength(jdata);
|
||||
jlong *jdata_ptr = env->GetLongArrayElements(jdata, nullptr);
|
||||
std::vector<int64_t> res(jdata_ptr, jdata_ptr + jdata_size);
|
||||
env->ReleaseLongArrayElements(jdata, jdata_ptr, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// jfloatArray -> std::vector<float>
|
||||
template <>
|
||||
inline std::vector<float> ConvertTo(JNIEnv *env, jfloatArray jdata) {
|
||||
int jdata_size = env->GetArrayLength(jdata);
|
||||
jfloat *jdata_ptr = env->GetFloatArrayElements(jdata, nullptr);
|
||||
std::vector<float> res(jdata_ptr, jdata_ptr + jdata_size);
|
||||
env->ReleaseFloatArrayElements(jdata, jdata_ptr, 0);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// std::vector<int64_t> -> jlongArray
|
||||
template <>
|
||||
inline jlongArray ConvertTo(JNIEnv *env, const std::vector<int64_t> &cvec) {
|
||||
jlongArray res = env->NewLongArray(cvec.size());
|
||||
jlong *jbuf = new jlong[cvec.size()];
|
||||
for (size_t i = 0; i < cvec.size(); ++i) {
|
||||
jbuf[i] = (jlong)cvec[i];
|
||||
}
|
||||
env->SetLongArrayRegion(res, 0, cvec.size(), jbuf);
|
||||
delete[] jbuf;
|
||||
return res;
|
||||
}
|
||||
|
||||
/// cxx float buffer -> jfloatArray
|
||||
template <>
|
||||
inline jfloatArray ConvertTo(JNIEnv *env, const float *cbuf, int64_t len) {
|
||||
jfloatArray res = env->NewFloatArray(len);
|
||||
env->SetFloatArrayRegion(res, 0, len, cbuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// cxx int buffer -> jintArray
|
||||
template <>
|
||||
inline jintArray ConvertTo(JNIEnv *env, const int *cbuf, int64_t len) {
|
||||
jintArray res = env->NewIntArray(len);
|
||||
env->SetIntArrayRegion(res, 0, len, cbuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
/// cxx int8_t buffer -> jbyteArray
|
||||
template <>
|
||||
inline jbyteArray ConvertTo(JNIEnv *env, const int8_t *cbuf, int64_t len) {
|
||||
jbyteArray res = env->NewByteArray(len);
|
||||
env->SetByteArrayRegion(res, 0, len, cbuf);
|
||||
return res;
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,18 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#pragma once
|
||||
#include "bitmap_jni.h" // NOLINT
|
||||
#include "convert_jni.h" // NOLINT
|
||||
#include "utils_jni.h" // NOLINT
|
@@ -0,0 +1,82 @@
|
||||
//
|
||||
// Created by qiuyanjun on 2022/10/19.
|
||||
//
|
||||
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#include "utils_jni.h"
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace jni {
|
||||
|
||||
// Assets Loader Utils.
|
||||
bool AssetsLoaderUtils::detection_labels_loaded_ = false;
|
||||
bool AssetsLoaderUtils::classification_labels_loaded_ = false;
|
||||
std::vector<std::string> AssetsLoaderUtils::detection_labels_ = {};
|
||||
std::vector<std::string> AssetsLoaderUtils::classification_labels_ = {};
|
||||
|
||||
bool AssetsLoaderUtils::IsDetectionLabelsLoaded() {
|
||||
return detection_labels_loaded_;
|
||||
}
|
||||
|
||||
bool AssetsLoaderUtils::IsClassificationLabelsLoaded() {
|
||||
return classification_labels_loaded_;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AssetsLoaderUtils::GetDetectionLabels() {
|
||||
return detection_labels_;
|
||||
}
|
||||
|
||||
const std::vector<std::string>& AssetsLoaderUtils::GetClassificationLabels() {
|
||||
return classification_labels_;
|
||||
}
|
||||
|
||||
void AssetsLoaderUtils::LoadClassificationLabels(const std::string& path,
|
||||
bool force_reload) {
|
||||
if (force_reload || (!classification_labels_loaded_)) {
|
||||
classification_labels_loaded_ =
|
||||
LoadLabelsFromTxt(path, &classification_labels_);
|
||||
}
|
||||
}
|
||||
|
||||
void AssetsLoaderUtils::LoadDetectionLabels(const std::string& path,
|
||||
bool force_reload) {
|
||||
if (force_reload || (!detection_labels_loaded_)) {
|
||||
detection_labels_loaded_ = LoadLabelsFromTxt(path, &detection_labels_);
|
||||
}
|
||||
}
|
||||
|
||||
bool AssetsLoaderUtils::LoadLabelsFromTxt(const std::string& txt_path,
|
||||
std::vector<std::string>* labels) {
|
||||
labels->clear();
|
||||
std::ifstream file;
|
||||
file.open(txt_path);
|
||||
if (!file.is_open()) {
|
||||
return false;
|
||||
}
|
||||
while (file) {
|
||||
std::string line;
|
||||
std::getline(file, line);
|
||||
if (!line.empty() && line != "\n") {
|
||||
labels->push_back(line);
|
||||
}
|
||||
}
|
||||
file.clear();
|
||||
file.close();
|
||||
return labels->size() > 0;
|
||||
}
|
||||
|
||||
} // namespace jni
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,80 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifdef __ANDROID__
|
||||
#include <android/log.h> // NOLINT
|
||||
#endif
|
||||
#include <fstream> // NOLINT
|
||||
#include <string> // NOLINT
|
||||
#include <vector> // NOLINT
|
||||
|
||||
#define TAG "[FastDeploy][JNI]"
|
||||
#ifdef __ANDROID__
|
||||
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG, TAG, __VA_ARGS__)
|
||||
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO, TAG, __VA_ARGS__)
|
||||
#define LOGW(...) __android_log_print(ANDROID_LOG_WARN, TAG, __VA_ARGS__)
|
||||
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR, TAG, __VA_ARGS__)
|
||||
#define LOGF(...) __android_log_print(ANDROID_LOG_FATAL, TAG, __VA_ARGS__)
|
||||
#else
|
||||
#define LOGD(...) \
|
||||
{}
|
||||
#define LOGI(...) \
|
||||
{}
|
||||
#define LOGW(...) \
|
||||
{}
|
||||
#define LOGE(...) \
|
||||
{}
|
||||
#define LOGF(...) \
|
||||
{}
|
||||
#endif
|
||||
|
||||
namespace fastdeploy {
|
||||
namespace jni {
|
||||
|
||||
inline int64_t GetCurrentTime() {
|
||||
struct timeval time;
|
||||
gettimeofday(&time, NULL);
|
||||
return 1000000LL * (int64_t)time.tv_sec + (int64_t)time.tv_usec;
|
||||
}
|
||||
|
||||
inline double GetElapsedTime(int64_t time) {
|
||||
return (GetCurrentTime() - time) / 1000.0f;
|
||||
}
|
||||
|
||||
class AssetsLoaderUtils {
|
||||
public:
|
||||
static bool detection_labels_loaded_;
|
||||
static bool classification_labels_loaded_;
|
||||
static std::vector<std::string> detection_labels_;
|
||||
static std::vector<std::string> classification_labels_;
|
||||
|
||||
public:
|
||||
static bool IsDetectionLabelsLoaded();
|
||||
static bool IsClassificationLabelsLoaded();
|
||||
static const std::vector<std::string>& GetDetectionLabels();
|
||||
static const std::vector<std::string>& GetClassificationLabels();
|
||||
static void LoadClassificationLabels(const std::string& path,
|
||||
bool force_reload = false);
|
||||
static void LoadDetectionLabels(const std::string& path,
|
||||
bool force_reload = false);
|
||||
|
||||
private:
|
||||
static bool LoadLabelsFromTxt(const std::string& txt_path,
|
||||
std::vector<std::string>* labels);
|
||||
};
|
||||
|
||||
} // namespace jni
|
||||
} // namespace fastdeploy
|
@@ -0,0 +1,148 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#include <jni.h> // NOLINT
|
||||
|
||||
#include "fastdeploy_jni.h" // NOLINT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_classification_PaddleClasModel_bindNative(
|
||||
JNIEnv *env, jclass clazz, jstring model_file, jstring params_file,
|
||||
jstring config_file, jint cpu_num_thread, jboolean enable_lite_fp16,
|
||||
jint lite_power_mode, jstring lite_optimized_model_dir,
|
||||
jboolean enable_record_time_of_runtime, jstring label_file) {
|
||||
std::string c_model_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, model_file);
|
||||
std::string c_params_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, params_file);
|
||||
std::string c_config_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, config_file);
|
||||
std::string c_label_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, label_file);
|
||||
std::string c_lite_optimized_model_dir =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, lite_optimized_model_dir);
|
||||
auto c_cpu_num_thread = static_cast<int>(cpu_num_thread);
|
||||
auto c_enable_lite_fp16 = static_cast<bool>(enable_lite_fp16);
|
||||
auto c_lite_power_mode =
|
||||
static_cast<fastdeploy::LitePowerMode>(lite_power_mode);
|
||||
fastdeploy::RuntimeOption c_option;
|
||||
c_option.UseCpu();
|
||||
c_option.UseLiteBackend();
|
||||
c_option.SetCpuThreadNum(c_cpu_num_thread);
|
||||
c_option.SetLitePowerMode(c_lite_power_mode);
|
||||
c_option.SetLiteOptimizedModelDir(c_lite_optimized_model_dir);
|
||||
if (c_enable_lite_fp16) {
|
||||
c_option.EnableLiteFP16();
|
||||
}
|
||||
auto c_model_ptr = new fastdeploy::vision::classification::PaddleClasModel(
|
||||
c_model_file, c_params_file, c_config_file, c_option);
|
||||
// Enable record Runtime time costs.
|
||||
if (enable_record_time_of_runtime) {
|
||||
c_model_ptr->EnableRecordTimeOfRuntime();
|
||||
}
|
||||
// Load classification labels if label path is not empty.
|
||||
if ((!fastdeploy::jni::AssetsLoaderUtils::IsClassificationLabelsLoaded()) &&
|
||||
(!c_label_file.empty())) {
|
||||
fastdeploy::jni::AssetsLoaderUtils::LoadClassificationLabels(c_label_file);
|
||||
}
|
||||
// WARN: need to release manually in Java !
|
||||
return reinterpret_cast<jlong>(c_model_ptr); // native model context
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_classification_PaddleClasModel_predictNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_model_context,
|
||||
jobject argb8888_bitmap, jboolean saved, jstring saved_image_path,
|
||||
jfloat score_threshold, jboolean rendering) {
|
||||
if (native_model_context == 0) {
|
||||
return 0;
|
||||
}
|
||||
cv::Mat c_bgr;
|
||||
auto t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!fastdeploy::jni::ARGB888Bitmap2BGR(env, argb8888_bitmap, &c_bgr)) {
|
||||
return 0;
|
||||
}
|
||||
LOGD("Read from bitmap costs %f ms", fastdeploy::jni::GetElapsedTime(t));
|
||||
auto c_model_ptr =
|
||||
reinterpret_cast<fastdeploy::vision::classification::PaddleClasModel *>(
|
||||
native_model_context);
|
||||
auto c_result_ptr = new fastdeploy::vision::ClassifyResult();
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!c_model_ptr->Predict(&c_bgr, c_result_ptr, 100)) {
|
||||
delete c_result_ptr;
|
||||
return 0;
|
||||
}
|
||||
LOGD("Predict from native costs %f ms", fastdeploy::jni::GetElapsedTime(t));
|
||||
if (c_model_ptr->EnabledRecordTimeOfRuntime()) {
|
||||
auto info_of_runtime = c_model_ptr->PrintStatisInfoOfRuntime();
|
||||
LOGD("Avg runtime costs %f ms", info_of_runtime["avg_time"] * 1000.0f);
|
||||
}
|
||||
if (!c_result_ptr->scores.empty() && rendering) {
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
cv::Mat c_vis_im;
|
||||
if (fastdeploy::jni::AssetsLoaderUtils::IsClassificationLabelsLoaded()) {
|
||||
c_vis_im = fastdeploy::vision::VisClassification(
|
||||
c_bgr, *(c_result_ptr),
|
||||
fastdeploy::jni::AssetsLoaderUtils::GetClassificationLabels(), 5,
|
||||
score_threshold, 1.0f);
|
||||
} else {
|
||||
c_vis_im = fastdeploy::vision::VisClassification(
|
||||
c_bgr, *(c_result_ptr), 5, score_threshold, 1.0f);
|
||||
}
|
||||
LOGD("Visualize from native costs %f ms",
|
||||
fastdeploy::jni::GetElapsedTime(t));
|
||||
// Rendering to bitmap
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!fastdeploy::jni::BGR2ARGB888Bitmap(env, argb8888_bitmap, c_vis_im)) {
|
||||
delete c_result_ptr;
|
||||
return 0;
|
||||
}
|
||||
LOGD("Write to bitmap from native costs %f ms",
|
||||
fastdeploy::jni::GetElapsedTime(t));
|
||||
std::string c_saved_image_path =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, saved_image_path);
|
||||
if (!c_saved_image_path.empty() && saved) {
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
cv::imwrite(c_saved_image_path, c_bgr);
|
||||
LOGD("Save image from native costs %f ms, path: %s",
|
||||
fastdeploy::jni::GetElapsedTime(t), c_saved_image_path.c_str());
|
||||
}
|
||||
}
|
||||
// WARN: need to release it manually in Java !
|
||||
return reinterpret_cast<jlong>(c_result_ptr); // native result context
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_classification_PaddleClasModel_releaseNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_model_context) {
|
||||
auto c_model_ptr =
|
||||
reinterpret_cast<fastdeploy::vision::classification::PaddleClasModel *>(
|
||||
native_model_context);
|
||||
if (c_model_ptr->EnabledRecordTimeOfRuntime()) {
|
||||
auto info_of_runtime = c_model_ptr->PrintStatisInfoOfRuntime();
|
||||
LOGD("[End] Avg runtime costs %f ms",
|
||||
info_of_runtime["avg_time"] * 1000.0f);
|
||||
}
|
||||
delete c_model_ptr;
|
||||
LOGD("[End] Release PaddleClasModel in native !");
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,149 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#include <jni.h> // NOLINT
|
||||
|
||||
#include "fastdeploy_jni.h" // NOLINT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_detection_PicoDet_bindNative(
|
||||
JNIEnv *env, jclass clazz, jstring model_file, jstring params_file,
|
||||
jstring config_file, jint cpu_num_thread, jboolean enable_lite_fp16,
|
||||
jint lite_power_mode, jstring lite_optimized_model_dir,
|
||||
jboolean enable_record_time_of_runtime, jstring label_file) {
|
||||
std::string c_model_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, model_file);
|
||||
std::string c_params_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, params_file);
|
||||
std::string c_config_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, config_file);
|
||||
std::string c_label_file =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, label_file);
|
||||
std::string c_lite_optimized_model_dir =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, lite_optimized_model_dir);
|
||||
auto c_cpu_num_thread = static_cast<int>(cpu_num_thread);
|
||||
auto c_enable_lite_fp16 = static_cast<bool>(enable_lite_fp16);
|
||||
auto c_lite_power_mode =
|
||||
static_cast<fastdeploy::LitePowerMode>(lite_power_mode);
|
||||
fastdeploy::RuntimeOption c_option;
|
||||
c_option.UseCpu();
|
||||
c_option.UseLiteBackend();
|
||||
c_option.SetCpuThreadNum(c_cpu_num_thread);
|
||||
c_option.SetLitePowerMode(c_lite_power_mode);
|
||||
c_option.SetLiteOptimizedModelDir(c_lite_optimized_model_dir);
|
||||
if (c_enable_lite_fp16) {
|
||||
c_option.EnableLiteFP16();
|
||||
}
|
||||
auto c_model_ptr = new fastdeploy::vision::detection::PicoDet(
|
||||
c_model_file, c_params_file, c_config_file, c_option);
|
||||
// Enable record Runtime time costs.
|
||||
if (enable_record_time_of_runtime) {
|
||||
c_model_ptr->EnableRecordTimeOfRuntime();
|
||||
}
|
||||
// Load detection labels if label path is not empty.
|
||||
if ((!fastdeploy::jni::AssetsLoaderUtils::IsDetectionLabelsLoaded()) &&
|
||||
(!c_label_file.empty())) {
|
||||
fastdeploy::jni::AssetsLoaderUtils::LoadDetectionLabels(c_label_file);
|
||||
}
|
||||
// WARN: need to release manually in Java !
|
||||
return reinterpret_cast<jlong>(c_model_ptr); // native model context
|
||||
}
|
||||
|
||||
JNIEXPORT jlong JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_detection_PicoDet_predictNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_model_context,
|
||||
jobject argb8888_bitmap, jboolean saved, jstring saved_image_path,
|
||||
jfloat score_threshold, jboolean rendering) {
|
||||
if (native_model_context == 0) {
|
||||
return 0;
|
||||
}
|
||||
cv::Mat c_bgr;
|
||||
auto t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!fastdeploy::jni::ARGB888Bitmap2BGR(env, argb8888_bitmap, &c_bgr)) {
|
||||
return 0;
|
||||
}
|
||||
LOGD("Read from bitmap costs %f ms", fastdeploy::jni::GetElapsedTime(t));
|
||||
auto c_model_ptr = reinterpret_cast<fastdeploy::vision::detection::PicoDet *>(
|
||||
native_model_context);
|
||||
auto c_result_ptr = new fastdeploy::vision::DetectionResult();
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!c_model_ptr->Predict(&c_bgr, c_result_ptr)) {
|
||||
delete c_result_ptr;
|
||||
return 0;
|
||||
}
|
||||
LOGD("Predict from native costs %f ms", fastdeploy::jni::GetElapsedTime(t));
|
||||
if (c_model_ptr->EnabledRecordTimeOfRuntime()) {
|
||||
auto info_of_runtime = c_model_ptr->PrintStatisInfoOfRuntime();
|
||||
LOGD("Avg runtime costs %f ms", info_of_runtime["avg_time"] * 1000.0f);
|
||||
}
|
||||
if (!c_result_ptr->boxes.empty() && rendering) {
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
cv::Mat c_vis_im;
|
||||
if (fastdeploy::jni::AssetsLoaderUtils::IsDetectionLabelsLoaded()) {
|
||||
c_vis_im = fastdeploy::vision::VisDetection(
|
||||
c_bgr, *(c_result_ptr),
|
||||
fastdeploy::jni::AssetsLoaderUtils::GetDetectionLabels(),
|
||||
score_threshold, 2, 1.0f);
|
||||
} else {
|
||||
c_vis_im = fastdeploy::vision::VisDetection(c_bgr, *(c_result_ptr),
|
||||
score_threshold, 2, 1.0f);
|
||||
}
|
||||
LOGD("Visualize from native costs %f ms",
|
||||
fastdeploy::jni::GetElapsedTime(t));
|
||||
// Rendering to bitmap
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
if (!fastdeploy::jni::BGR2ARGB888Bitmap(env, argb8888_bitmap, c_vis_im)) {
|
||||
delete c_result_ptr;
|
||||
return 0;
|
||||
}
|
||||
LOGD("Write to bitmap from native costs %f ms",
|
||||
fastdeploy::jni::GetElapsedTime(t));
|
||||
std::string c_saved_image_path =
|
||||
fastdeploy::jni::ConvertTo<std::string>(env, saved_image_path);
|
||||
if (!c_saved_image_path.empty() && saved) {
|
||||
t = fastdeploy::jni::GetCurrentTime();
|
||||
cv::imwrite(c_saved_image_path, c_vis_im);
|
||||
LOGD("Save image from native costs %f ms, path: %s",
|
||||
fastdeploy::jni::GetElapsedTime(t), c_saved_image_path.c_str());
|
||||
}
|
||||
}
|
||||
// WARN: need to release it manually in Java !
|
||||
return reinterpret_cast<jlong>(c_result_ptr); // native result context
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_detection_PicoDet_releaseNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_model_context) {
|
||||
if (native_model_context == 0) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
auto c_model_ptr = reinterpret_cast<fastdeploy::vision::detection::PicoDet *>(
|
||||
native_model_context);
|
||||
if (c_model_ptr->EnabledRecordTimeOfRuntime()) {
|
||||
auto info_of_runtime = c_model_ptr->PrintStatisInfoOfRuntime();
|
||||
LOGD("[End] Avg runtime costs %f ms",
|
||||
info_of_runtime["avg_time"] * 1000.0f);
|
||||
}
|
||||
delete c_model_ptr;
|
||||
LOGD("[End] Release PicoDet in native !");
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,132 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
|
||||
#include <android/bitmap.h> // NOLINT
|
||||
#include <jni.h> // NOLINT
|
||||
|
||||
#include "fastdeploy/vision.h" // NOLINT
|
||||
#include "fastdeploy_jni.h" // NOLINT
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/// Native DetectionResult for vision::DetectionResult.
|
||||
JNIEXPORT jint JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_DetectionResult_copyBoxesNumFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::DetectionResult *>(
|
||||
native_result_context);
|
||||
return static_cast<jint>(c_result_ptr->boxes.size());
|
||||
}
|
||||
|
||||
JNIEXPORT jfloatArray JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_DetectionResult_copyBoxesFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::DetectionResult *>(
|
||||
native_result_context);
|
||||
if (c_result_ptr->boxes.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto len = static_cast<int64_t>(c_result_ptr->boxes.size());
|
||||
float buffer[len * 4];
|
||||
const auto &boxes = c_result_ptr->boxes;
|
||||
for (int64_t i = 0; i < len; ++i) {
|
||||
std::memcpy((buffer + i * 4), (boxes.at(i).data()), 4 * sizeof(float));
|
||||
}
|
||||
return fastdeploy::jni::ConvertTo<jfloatArray>(env, buffer, len * 4);
|
||||
}
|
||||
|
||||
JNIEXPORT jfloatArray JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_DetectionResult_copyScoresFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::DetectionResult *>(
|
||||
native_result_context);
|
||||
if (c_result_ptr->scores.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto len = static_cast<int64_t>(c_result_ptr->scores.size());
|
||||
const float *buffer = static_cast<float *>(c_result_ptr->scores.data());
|
||||
return fastdeploy::jni::ConvertTo<jfloatArray>(env, buffer, len);
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_DetectionResult_copyLabelIdsFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::DetectionResult *>(
|
||||
native_result_context);
|
||||
if (c_result_ptr->label_ids.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto len = static_cast<int64_t>(c_result_ptr->label_ids.size());
|
||||
const int *buffer = static_cast<int *>(c_result_ptr->label_ids.data());
|
||||
return fastdeploy::jni::ConvertTo<jintArray>(env, buffer, len);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_DetectionResult_releaseNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
if (native_result_context == 0) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::DetectionResult *>(
|
||||
native_result_context);
|
||||
delete c_result_ptr;
|
||||
LOGD("Release DetectionResult in native !");
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
/// Native ClassifyResult for vision::ClassifyResult.
|
||||
JNIEXPORT jfloatArray JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_ClassifyResult_copyScoresFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::ClassifyResult *>(
|
||||
native_result_context);
|
||||
if (c_result_ptr->scores.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto len = static_cast<int64_t>(c_result_ptr->scores.size());
|
||||
const float *buffer = static_cast<float *>(c_result_ptr->scores.data());
|
||||
return fastdeploy::jni::ConvertTo<jfloatArray>(env, buffer, len);
|
||||
}
|
||||
|
||||
JNIEXPORT jintArray JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_ClassifyResult_copyLabelIdsFromNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::ClassifyResult *>(
|
||||
native_result_context);
|
||||
if (c_result_ptr->label_ids.empty()) {
|
||||
return {};
|
||||
}
|
||||
const auto len = static_cast<int64_t>(c_result_ptr->label_ids.size());
|
||||
const int *buffer = static_cast<int *>(c_result_ptr->label_ids.data());
|
||||
return fastdeploy::jni::ConvertTo<jintArray>(env, buffer, len);
|
||||
}
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_ClassifyResult_releaseNative(
|
||||
JNIEnv *env, jclass clazz, jlong native_result_context) {
|
||||
if (native_result_context == 0) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
auto c_result_ptr = reinterpret_cast<fastdeploy::vision::ClassifyResult *>(
|
||||
native_result_context);
|
||||
delete c_result_ptr;
|
||||
LOGD("Release ClassifyResult in native !");
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
@@ -0,0 +1,92 @@
|
||||
// Copyright (c) 2022 PaddlePaddle Authors. All Rights Reserved.
|
||||
//
|
||||
// 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
|
||||
//
|
||||
// http://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.
|
||||
#include <jni.h>
|
||||
|
||||
#include "fastdeploy_jni.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
JNIEXPORT jboolean JNICALL
|
||||
Java_com_baidu_paddle_fastdeploy_vision_Visualize_visDetectionNative(
|
||||
JNIEnv *env, jclass clazz, jobject argb8888_bitmap, jobjectArray boxes,
|
||||
jfloatArray scores, jintArray label_ids, jfloat score_threshold,
|
||||
jint line_size, jfloat font_size, jobjectArray labels) {
|
||||
// Draw DetectionResult to ARGB8888 Bitmap
|
||||
int len = env->GetArrayLength(boxes);
|
||||
if ((len == 0) || (len != env->GetArrayLength(scores)) ||
|
||||
(len != env->GetArrayLength(label_ids))) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
fastdeploy::vision::DetectionResult c_result;
|
||||
c_result.Resize(len);
|
||||
bool check_validation = true;
|
||||
for (int i = 0; i < len; ++i) {
|
||||
auto j_box =
|
||||
reinterpret_cast<jfloatArray>(env->GetObjectArrayElement(boxes, i));
|
||||
if (env->GetArrayLength(j_box) == 4) {
|
||||
jfloat *j_box_ptr = env->GetFloatArrayElements(j_box, nullptr);
|
||||
std::memcpy(c_result.boxes[i].data(), j_box_ptr, 4 * sizeof(float));
|
||||
env->ReleaseFloatArrayElements(j_box, j_box_ptr, 0);
|
||||
} else {
|
||||
check_validation = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!check_validation) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
jfloat *j_scores_ptr = env->GetFloatArrayElements(scores, nullptr);
|
||||
std::memcpy(c_result.scores.data(), j_scores_ptr, len * sizeof(float));
|
||||
env->ReleaseFloatArrayElements(scores, j_scores_ptr, 0);
|
||||
jint *j_label_ids_ptr = env->GetIntArrayElements(label_ids, nullptr);
|
||||
std::memcpy(c_result.label_ids.data(), j_label_ids_ptr, len * sizeof(int));
|
||||
env->ReleaseIntArrayElements(label_ids, j_label_ids_ptr, 0);
|
||||
|
||||
// Get labels from Java
|
||||
std::vector<std::string> c_labels;
|
||||
int label_len = env->GetArrayLength(labels);
|
||||
if (label_len > 0) {
|
||||
c_labels.reserve(label_len);
|
||||
for (int i = 0; i < label_len; ++i) {
|
||||
auto j_str =
|
||||
reinterpret_cast<jstring>(env->GetObjectArrayElement(labels, i));
|
||||
c_labels.push_back(fastdeploy::jni::ConvertTo<std::string>(env, j_str));
|
||||
}
|
||||
}
|
||||
|
||||
cv::Mat c_bgr;
|
||||
// From ARGB Bitmap to BGR
|
||||
if (!fastdeploy::jni::ARGB888Bitmap2BGR(env, argb8888_bitmap, &c_bgr)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
cv::Mat c_vis_im;
|
||||
if (!c_labels.empty()) {
|
||||
c_vis_im = fastdeploy::vision::VisDetection(
|
||||
c_bgr, c_result, c_labels, score_threshold, line_size, font_size);
|
||||
} else {
|
||||
c_vis_im = fastdeploy::vision::VisDetection(
|
||||
c_bgr, c_result, score_threshold, line_size, font_size);
|
||||
}
|
||||
// Rendering to bitmap
|
||||
if (!fastdeploy::jni::BGR2ARGB888Bitmap(env, argb8888_bitmap, c_vis_im)) {
|
||||
return JNI_FALSE;
|
||||
}
|
||||
return JNI_TRUE;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
Reference in New Issue
Block a user