Add java apis and demos (#563)

* add java classifier detector

* add segmentor

* fix lint

* add ImageRestorer java apis and demo

* remove useless count parameter for Segmentor and Restorer, add PoseDetector

* add RotatedDetection java api and demo

* add Ocr java demo and apis

* remove mmrotate ncnn java api and demo

* fix lint

* sync java api folder after rebase to master

* fix include

* remove record

* fix java apis dir path in cmake

* add java demo readme

* fix lint mdformat

* add test javaapi ci

* fix lint

* fix flake8

* fix test javaapi ci

* refactor readme.md

* fix install opencv for ci

* fix install opencv : add permission

* add all codebases and mmcv install

* add torch

* install mmdeploy

* fix image path

* fix picture path

* fix import ncnn

* fix import ncnn

* add submodule of pybind

* fix pybind submodule

* change download to git clone for submodule

* fix ncnn dir

* fix README error

* simplify the github ci

* fix ci

* fix yapf

* add JNI as required

* fix Capitalize

* fix Capitalize

* fix copyright

* ignore .class changed

* add OpenJDK installation docs

* install target of javaapi

* simplify ci

* add jar

* fix ci

* fix ci

* fix test java command

* debugging what failed

* debugging what failed

* debugging what failed

* add java version info

* install openjdk

* add java env var

* fix export

* fix export

* fix export

* fix export

* fix picture path

* fix picture path

* fix file name

* fix file name

* fix README

* remove java_api strategy

* fix python version

* format task name

* move args position

* extract common utils code

* show image class result

* add detector result

* segmentation result format

* add ImageRestorer result

* add PoseDetection java result format

* fix ci

* stage ocr

* add visualize

* move utils

* fix lint

* fix ocr bugs

* fix ci demo

* fix java classpath for ci

* fix popd

* fix ocr demo text garbled

* fix ci

* fix ci

* fix ci

* fix path of utils ci
This commit is contained in:
hanrui1sensetime 2022-06-29 11:02:08 +08:00 committed by GitHub
parent 5fce1e8f8d
commit 051e1577a3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1903 additions and 0 deletions

84
.github/scripts/test_java_demo.py vendored Normal file
View File

@ -0,0 +1,84 @@
# Copyright (c) OpenMMLab. All rights reserved.
import os
# list of dict: task name and deploy configs.
PARAMS = [
{
'task':
'ImageClassification',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/resnet.tar' # noqa: E501
]
},
{
'task':
'ObjectDetection',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/mobilessd.tar' # noqa: E501
]
},
{
'task':
'ImageSegmentation',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/fcn.tar' # noqa: E501
]
},
{
'task':
'ImageRestorer',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/srcnn.tar' # noqa: E501
]
},
{
'task':
'Ocr',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/dbnet.tar', # noqa: E501
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/crnn.tar' # noqa: E501
]
},
{
'task':
'PoseDetection',
'configs': [
'https://media.githubusercontent.com/media/hanrui1sensetime/mmdeploy-javaapi-testdata/master/litehrnet.tar' # noqa: E501
]
}
]
def main():
"""test java apis and demos.
Run all java demos for test.
"""
for params in PARAMS:
task = params['task']
configs = params['configs']
java_demo_cmd = [
'java', '-cp', 'csrc/mmdeploy/apis/java:demo/java',
'demo/java/' + task + '.java', 'cpu'
]
for config in configs:
model_url = config
os.system('wget {} && tar xvf {}'.format(model_url,
model_url.split('/')[-1]))
model_dir = model_url.split('/')[-1].split('.')[0]
java_demo_cmd.append(model_dir)
java_demo_cmd.append('/home/runner/work/mmdeploy/mmdeploy/demo' +
'/resources/human-pose.jpg')
java_demo_cmd_str = ' '.join(java_demo_cmd)
os.system('export JAVA_HOME=/home/runner/work/mmdeploy/mmdeploy/' +
'jdk-18 && export PATH=${JAVA_HOME}/bin:${PATH} && java' +
' --version && export LD_LIBRARY_PATH=/home/runner/work/' +
'mmdeploy/mmdeploy/build/lib:${LD_LIBRARY_PATH} && ' +
java_demo_cmd_str)
if __name__ == '__main__':
main()

72
.github/workflows/java_api.yml vendored Normal file
View File

@ -0,0 +1,72 @@
name: java_api
on:
push:
paths-ignore:
- "tools/**"
pull_request:
paths-ignore:
- "tools/**"
- "docs/**"
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true
jobs:
test_java_api:
runs-on: ubuntu-18.04
steps:
- name: Checkout repository
uses: actions/checkout@v3
with:
submodules: 'recursive'
- name: Set up Python 3.7
uses: actions/setup-python@v2
with:
python-version: 3.7
- name: Install unittest dependencies
run: |
pip install cmake onnx
- name: update
run: sudo apt update
- name: Install OpenJDK
run: |
wget https://download.java.net/java/GA/jdk18/43f95e8614114aeaa8e8a5fcf20a682d/36/GPL/openjdk-18_linux-x64_bin.tar.gz
tar xvf openjdk-18_linux-x64_bin.tar.gz
- name: gcc-multilib
run: sudo apt install gcc-multilib g++-multilib wget libprotobuf-dev protobuf-compiler
- name: Install onnxruntime
run: |
wget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz
tar -zxvf onnxruntime-linux-x64-1.8.1.tgz
pushd onnxruntime-linux-x64-1.8.1
export ONNXRUNTIME_DIR=${PWD}
export LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH
popd
- name: Install opencv
run: |
sudo apt-get install libopencv-dev
- name: Build java class
run: |
pushd csrc/mmdeploy/apis/java
javac mmdeploy/*.java
popd
pushd demo/java
javac -classpath ../../csrc/mmdeploy/apis/java/ Utils.java
popd
- name: Install mmdeploy with onnxruntime backend and java api
run: |
mkdir -p build && pushd build
export LD_LIBRARY_PATH=/home/runner/work/mmdeploy/mmdeploy/ncnn/install/lib/:$LD_LIBRARY_PATH
cmake -DMMDEPLOY_BUILD_SDK=ON -DMMDEPLOY_BUILD_SDK_JAVA_API=ON -DMMDEPLOY_TARGET_BACKENDS=ort -DMMDEPLOY_CODEBASES=all -DONNXRUNTIME_DIR=~/work/mmdeploy/mmdeploy/onnxruntime-linux-x64-1.8.1 ..
make install
popd
- name: Test javademo
run: |
export JAVA_HOME=${PWD}/jdk-18
export PATH=${JAVA_HOME}/bin:${PATH}
export LD_LIBRARY_PATH=/build/lib:${LD_LIBRARY_PATH}
java --version
python3 .github/scripts/test_java_demo.py

3
.gitignore vendored
View File

@ -7,6 +7,9 @@ __pycache__/
*.so
onnx2ncnn
# Java classes
*.class
# Distribution / packaging
.Python
build/

View File

@ -25,6 +25,7 @@ option(MMDEPLOY_BUILD_TEST "build unittests" OFF)
option(MMDEPLOY_BUILD_SDK_PYTHON_API "build SDK Python API" OFF)
option(MMDEPLOY_BUILD_SDK_CXX_API "build SDK C++ API" OFF)
option(MMDEPLOY_BUILD_SDK_CSHARP_API "build SDK C# API support" OFF)
option(MMDEPLOY_BUILD_SDK_JAVA_API "build SDK JAVA API" OFF)
option(MMDEPLOY_SPDLOG_EXTERNAL "use external spdlog" OFF)
option(MMDEPLOY_ZIP_MODEL "support SDK model in zip format" OFF)
set(MMDEPLOY_TARGET_DEVICES "cpu" CACHE STRING "target devices to support")
@ -92,6 +93,10 @@ if (MMDEPLOY_BUILD_SDK)
add_subdirectory(csrc/mmdeploy/apis/python)
endif ()
if (MMDEPLOY_BUILD_SDK_JAVA_API)
add_subdirectory(csrc/mmdeploy/apis/java)
endif ()
# export MMDeploy package
install(EXPORT MMDeployTargets
FILE MMDeployTargets.cmake

View File

@ -0,0 +1,23 @@
project(mmdeploy_java_package)
find_package(Java REQUIRED)
include(UseJava)
add_subdirectory(native)
add_jar(${PROJECT_NAME} SOURCES
mmdeploy/DataType.java
mmdeploy/Mat.java
mmdeploy/InstanceMask.java
mmdeploy/PixelFormat.java
mmdeploy/PointF.java
mmdeploy/Rect.java
mmdeploy/Classifier.java
mmdeploy/Detector.java
mmdeploy/Segmentor.java
mmdeploy/TextDetector.java
mmdeploy/TextRecognizer.java
mmdeploy/Restorer.java
mmdeploy/PoseDetector.java
OUTPUT_NAME mmdeploy
OUTPUT_DIR ${CMAKE_LIBRARY_OUTPUT_DIRECTORY})

View File

@ -0,0 +1,48 @@
# Build Java API
## From Source
### Requirements
- OpenJDK >= 10
**Step 1.** Download OpenJDK. Using OpenJDK-18 as example:
```bash
wget https://download.java.net/java/GA/jdk18/43f95e8614114aeaa8e8a5fcf20a682d/36/GPL/openjdk-18_linux-x64_bin.tar.gz
tar xvf openjdk-18_linux-x64_bin.tar.gz
```
**Step 2.** Setting environment variables:
```bash
export JAVA_HOME=${PWD}/jdk-18
export PATH=${JAVA_HOME}/bin:${PATH}
```
**Step 3.** Switch default Java version:
```bash
sudo update-alternatives --config java
sudo update-alternatives --config javac
```
You should select the version you will use.
### Installation
For using Java apis, you should build Java class and C++ SDK.
**Step 1.** Build Java class.
Build Java `.class` files.
```bash
cd csrc/mmdeploy/apis/java
javac mmdeploy/*.java
cd ../../../..
```
**Step 2.** Build SDK.
Build MMDeploy SDK. Please follow this [tutorial](../../../../docs/en/01-how-to-build/linux-x86_64.md)/[教程](../../../../docs/zh_cn/01-how-to-build/linux-x86_64.md) to build SDK. Remember to set the MMDEPLOY_BUILD_SDK_JAVA_API option to ON.

View File

@ -0,0 +1,54 @@
package mmdeploy;
public class Classifier {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public int label_id;
public float score;
public Result(int label_id, float score) {
this.label_id = label_id;
this.score = score;
}
}
public Classifier(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
int[] counts = new int[images.length];
Result[] results = apply(handle, images, counts);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[counts[i]];
if (counts[i] >= 0) {
System.arraycopy(results, offset, row, 0, counts[i]);
}
offset += counts[i];
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
int[] counts = new int[1];
Mat[] images = new Mat[]{image};
return apply(handle, images, counts);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images, int[] count);
}

View File

@ -0,0 +1,13 @@
package mmdeploy;
public enum DataType {
FLOAT(0),
HALF(1),
INT8(2),
INT32(3);
final int value;
DataType(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,58 @@
package mmdeploy;
public class Detector {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public int label_id;
public float score;
public Rect bbox;
public InstanceMask mask;
public Result(int label_id, float score, Rect bbox, InstanceMask mask) {
this.label_id = label_id;
this.score = score;
this.bbox = bbox;
this.mask = mask;
}
}
public Detector(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
int[] counts = new int[images.length];
Result[] results = apply(handle, images, counts);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[counts[i]];
if (counts[i] >= 0) {
System.arraycopy(results, offset, row, 0, counts[i]);
}
offset += counts[i];
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
int[] counts = new int[1];
Mat[] images = new Mat[]{image};
return apply(handle, images, counts);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images, int[] count);
}

View File

@ -0,0 +1,12 @@
package mmdeploy;
public class InstanceMask {
public int[] shape;
public char[] data;
public InstanceMask(int height, int width, char[] data) {
shape = new int[]{height, width};
this.data = data;
}
}

View File

@ -0,0 +1,17 @@
package mmdeploy;
public class Mat {
public int[] shape;
public int format;
public int type;
public byte[] data;
public Mat(int height, int width, int channel,
PixelFormat format, DataType type, byte[] data) {
shape = new int[]{height, width, channel};
this.format = format.value;
this.type = type.value;
this.data = data;
}
}

View File

@ -0,0 +1,15 @@
package mmdeploy;
public enum PixelFormat {
BGR(0),
RGB(1),
GRAYSCALE(2),
NV12(3),
NV21(4),
BGRA(5);
final int value;
PixelFormat(int value) {
this.value = value;
}
}

View File

@ -0,0 +1,12 @@
package mmdeploy;
public class PointF {
public float x;
public float y;
public PointF(float x, float y) {
this.x = x;
this.y = y;
}
}

View File

@ -0,0 +1,50 @@
package mmdeploy;
public class PoseDetector {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public PointF[] point;
public float[] score;
public Result(PointF[] point, float [] score) {
this.point = point;
this.score = score;
}
}
public PoseDetector(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
Result[] results = apply(handle, images);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[1];
System.arraycopy(results, offset, row, 0, 1);
offset += 1;
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
Mat[] images = new Mat[]{image};
return apply(handle, images);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images);
}

View File

@ -0,0 +1,16 @@
package mmdeploy;
public class Rect {
public float left;
public float top;
public float right;
public float bottom;
public Rect(float left, float top, float right, float bottom) {
this.left = left;
this.top = top;
this.right = right;
this.bottom = bottom;
}
}

View File

@ -0,0 +1,48 @@
package mmdeploy;
public class Restorer {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public Mat res;
public Result(Mat res) {
this.res = res;
}
}
public Restorer(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
Result[] results = apply(handle, images);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[1];
System.arraycopy(results, offset, row, 0, 1);
offset += 1;
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
Mat[] images = new Mat[]{image};
return apply(handle, images);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images);
}

View File

@ -0,0 +1,54 @@
package mmdeploy;
public class Segmentor {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public int height;
public int width;
public int classes;
public int[] mask;
public Result(int height, int width, int classes, int [] mask) {
this.height = height;
this.width = width;
this.classes = classes;
this.mask = mask;
}
}
public Segmentor(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
Result[] results = apply(handle, images);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[1];
System.arraycopy(results, offset, row, 0, 1);
offset += 1;
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
Mat[] images = new Mat[]{image};
return apply(handle, images);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images);
}

View File

@ -0,0 +1,54 @@
package mmdeploy;
public class TextDetector {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public PointF[] bbox;
public float score;
public Result(PointF[] bbox, float score) {
this.bbox = bbox;
this.score = score;
}
}
public TextDetector(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
int[] counts = new int[images.length];
Result[] results = apply(handle, images, counts);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[counts[i]];
if (counts[i] >= 0) {
System.arraycopy(results, offset, row, 0, counts[i]);
}
offset += counts[i];
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
int[] counts = new int[1];
Mat[] images = new Mat[]{image};
return apply(handle, images, counts);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images, int[] count);
}

View File

@ -0,0 +1,57 @@
package mmdeploy;
public class TextRecognizer {
static {
System.loadLibrary("mmdeploy_java");
}
private final long handle;
public static class Result {
public byte [] text;
public float [] score;
public Result(byte [] text, float [] score) {
this.text = text;
this.score = score;
}
}
public TextRecognizer(String modelPath, String deviceName, int deviceId) {
handle = create(modelPath, deviceName, deviceId);
}
public Result[][] apply(Mat[] images) {
Result[] results = apply(handle, images);
Result[][] rets = new Result[images.length][];
int offset = 0;
for (int i = 0; i < images.length; ++i) {
Result[] row = new Result[1];
System.arraycopy(results, offset, row, 0, 1);
offset += 1;
rets[i] = row;
}
return rets;
}
public Result[] apply(Mat image) {
Mat[] images = new Mat[]{image};
return apply(handle, images);
}
public Result[] applyBbox(Mat image, TextDetector.Result[] bbox, int[] bbox_count) {
Mat[] images = new Mat[]{image};
return applyBbox(handle, images, bbox, bbox_count);
}
public void release() {
destroy(handle);
}
private native long create(String modelPath, String deviceName, int deviceId);
private native void destroy(long handle);
private native Result[] apply(long handle, Mat[] images);
private native Result[] applyBbox(long handle, Mat[] images, TextDetector.Result[] bbox, int[] bbox_count);
}

View File

@ -0,0 +1,23 @@
# Copyright (c) OpenMMLab. All rights reserved.
project(mmdeploy_java)
find_package(JNI REQUIRED)
mmdeploy_add_library(${PROJECT_NAME} SHARED EXCLUDE
mmdeploy_Classifier.cpp
mmdeploy_Detector.cpp
mmdeploy_Segmentor.cpp
mmdeploy_Restorer.cpp
mmdeploy_PoseDetector.cpp
mmdeploy_TextDetector.cpp
mmdeploy_TextRecognizer.cpp)
target_include_directories(${PROJECT_NAME} PRIVATE
${JNI_INCLUDE_DIRS})
mmdeploy_load_static(${PROJECT_NAME} MMDeployStaticModules)
mmdeploy_load_dynamic(${PROJECT_NAME} MMDeployDynamicModules)
target_link_libraries(${PROJECT_NAME} PRIVATE
${JNI_LIBRARIES} MMDeployLibs)
install(TARGETS ${PROJECT_NAME}
DESTINATION lib)

View File

@ -0,0 +1,54 @@
#ifndef MMDEPLOY_CSRC_APIS_JAVA_NATIVE_COMMON_H_
#define MMDEPLOY_CSRC_APIS_JAVA_NATIVE_COMMON_H_
#include <jni.h>
#include <vector>
#include "mmdeploy/apis/c/common.h"
#include "mmdeploy/core/logger.h"
#include "mmdeploy/core/utils/formatter.h"
template <typename F>
static auto With(JNIEnv *env, jobjectArray imgs, F f) noexcept {
auto mat_clazz = env->FindClass("mmdeploy/Mat");
auto shape_field = env->GetFieldID(mat_clazz, "shape", "[I");
auto format_field = env->GetFieldID(mat_clazz, "format", "I");
auto type_field = env->GetFieldID(mat_clazz, "type", "I");
auto data_field = env->GetFieldID(mat_clazz, "data", "[B");
auto num = env->GetArrayLength(imgs);
std::vector<mm_mat_t> mats;
std::vector<jbyteArray> datum;
mats.reserve(num);
datum.reserve(num);
for (int i = 0; i < num; ++i) {
auto obj = env->GetObjectArrayElement(imgs, i);
auto shape_obj = env->GetObjectField(obj, shape_field);
auto shape = env->GetIntArrayElements((jintArray)shape_obj, nullptr);
auto format = env->GetIntField(obj, format_field);
auto type = env->GetIntField(obj, type_field);
auto &mat = mats.emplace_back();
mat.height = shape[0];
mat.width = shape[1];
mat.channel = shape[2];
env->ReleaseIntArrayElements((jintArray)shape_obj, shape, JNI_ABORT);
mat.format = (mm_pixel_format_t)format;
mat.type = (mm_data_type_t)type;
auto data_obj = env->GetObjectField(obj, data_field);
mat.data = (uint8_t *)env->GetByteArrayElements((jbyteArray)data_obj, nullptr);
datum.push_back((jbyteArray)data_obj);
}
auto ret = f(mats.data(), mats.size()); // ! f must not throw
for (int i = 0; i < num; ++i) {
env->ReleaseByteArrayElements(datum[i], (jbyte *)mats[i].data, JNI_ABORT);
}
return ret;
}
#endif // MMDEPLOY_CSRC_APIS_JAVA_NATIVE_COMMON_H_

View File

@ -0,0 +1,57 @@
#include "mmdeploy_Classifier.h"
#include <numeric>
#include "mmdeploy/apis/c/classifier.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_Classifier_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t classifier{};
auto ec =
mmdeploy_classifier_create_by_path(model_path, device_name, (int)device_id, &classifier);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create classifier, code = {}", ec);
}
return (jlong)classifier;
}
void Java_mmdeploy_Classifier_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_Classifier_destroy");
mmdeploy_classifier_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_Classifier_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images, jintArray counts) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_class_t *results{};
int *result_count{};
auto ec = mmdeploy_classifier_apply((mm_handle_t)handle, imgs, size, &results, &result_count);
if (ec) {
MMDEPLOY_ERROR("failed to apply classifier, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/Classifier$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "(IF)V");
auto total = std::accumulate(result_count, result_count + size, 0);
auto array = env->NewObjectArray(total, result_cls, nullptr);
for (int i = 0; i < total; ++i) {
auto res = env->NewObject(result_cls, result_ctor, (jint)results[i].label_id,
(jfloat)results[i].score);
env->SetObjectArrayElement(array, i, res);
}
auto counts_array = env->GetIntArrayElements(counts, nullptr);
for (int i = 0; i < size; ++i) {
counts_array[i] = result_count[i];
}
env->ReleaseIntArrayElements(counts, counts_array, 0);
mmdeploy_classifier_release_result(results, result_count, size);
return array;
});
}

View File

@ -0,0 +1,35 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_Classifier */
#ifndef _Included_mmdeploy_Classifier
#define _Included_mmdeploy_Classifier
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_Classifier
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_Classifier_create(JNIEnv *, jobject, jstring, jstring, jint);
/*
* Class: mmdeploy_Classifier
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_Classifier_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_Classifier
* Method: apply
* Signature: (J[Lmmdeploy/Mat;[I)[Lmmdeploy/Classifier/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_Classifier_apply(JNIEnv *, jobject, jlong,
jobjectArray, jintArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,81 @@
#include "mmdeploy_Detector.h"
#include <numeric>
#include "mmdeploy/apis/c/detector.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_Detector_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t detector{};
auto ec = mmdeploy_detector_create_by_path(model_path, device_name, (int)device_id, &detector);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create detector, code = {}", ec);
}
return (jlong)detector;
}
void Java_mmdeploy_Detector_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_Detector_destroy"); // maybe use info?
mmdeploy_detector_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_Detector_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images, jintArray counts) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_detect_t *results{};
int *result_count{};
auto ec = mmdeploy_detector_apply((mm_handle_t)handle, imgs, size, &results, &result_count);
if (ec) {
MMDEPLOY_ERROR("failed to apply detector, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/Detector$Result");
auto result_ctor =
env->GetMethodID(result_cls, "<init>", "(IFLmmdeploy/Rect;Lmmdeploy/InstanceMask;)V");
auto total = std::accumulate(result_count, result_count + size, 0);
auto array = env->NewObjectArray(total, result_cls, nullptr);
auto rect_cls = env->FindClass("mmdeploy/Rect");
auto rect_ctor = env->GetMethodID(rect_cls, "<init>", "(FFFF)V");
auto instance_mask_cls = env->FindClass("mmdeploy/InstanceMask");
auto instance_mask_ctor = env->GetMethodID(instance_mask_cls, "<init>", "(II[C)V");
for (int i = 0; i < total; ++i) {
auto rect = env->NewObject(rect_cls, rect_ctor, (jfloat)results[i].bbox.left,
(jfloat)results[i].bbox.top, (jfloat)results[i].bbox.right,
(jfloat)results[i].bbox.bottom);
int width, height;
char *data;
jcharArray jmask;
if (results[i].mask == nullptr) {
width = 0;
height = 0;
data = nullptr;
jmask = env->NewCharArray(0);
} else {
width = results[i].mask->width;
height = results[i].mask->height;
data = results[i].mask->data;
jmask = env->NewCharArray(width * height);
env->SetCharArrayRegion(jmask, 0, width * height, (const jchar *)data);
}
auto instance_mask =
env->NewObject(instance_mask_cls, instance_mask_ctor, (jint)height, (jint)width, jmask);
auto res = env->NewObject(result_cls, result_ctor, (jint)results[i].label_id,
(jfloat)results[i].score, rect, instance_mask);
env->SetObjectArrayElement(array, i, res);
}
auto counts_array = env->GetIntArrayElements(counts, nullptr);
for (int i = 0; i < size; ++i) {
counts_array[i] = result_count[i];
}
env->ReleaseIntArrayElements(counts, counts_array, 0);
mmdeploy_detector_release_result(results, result_count, size);
return array;
});
}

View File

@ -0,0 +1,35 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_Detector */
#ifndef _Included_mmdeploy_Detector
#define _Included_mmdeploy_Detector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_Detector
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_Detector_create(JNIEnv *, jobject, jstring, jstring, jint);
/*
* Class: mmdeploy_Detector
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_Detector_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_Detector
* Method: apply
* Signature: (J[Lmmdeploy/Mat;[I)[Lmmdeploy/Detector/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_Detector_apply(JNIEnv *, jobject, jlong, jobjectArray,
jintArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,58 @@
#include "mmdeploy_PoseDetector.h"
#include <numeric>
#include "mmdeploy/apis/c/pose_detector.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_PoseDetector_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t pose_estimator{};
auto ec = mmdeploy_pose_detector_create_by_path(model_path, device_name, (int)device_id,
&pose_estimator);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create pose estimator, code = {}", ec);
}
return (jlong)pose_estimator;
}
void Java_mmdeploy_PoseDetector_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_PoseDetector_destroy");
mmdeploy_pose_detector_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_PoseDetector_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_pose_detect_t *results{};
auto ec = mmdeploy_pose_detector_apply((mm_handle_t)handle, imgs, size, &results);
if (ec) {
MMDEPLOY_ERROR("failed to apply pose estimator, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/PoseDetector$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "([Lmmdeploy/PointF;[F)V");
auto array = env->NewObjectArray(size, result_cls, nullptr);
auto pointf_cls = env->FindClass("mmdeploy/PointF");
auto pointf_ctor = env->GetMethodID(pointf_cls, "<init>", "(FF)V");
for (int i = 0; i < size; ++i) {
auto keypoint_array = env->NewObjectArray(results[i].length, pointf_cls, nullptr);
for (int j = 0; j < results[i].length; ++j) {
auto keypointj = env->NewObject(pointf_cls, pointf_ctor, (jfloat)results[i].point[j].x,
(jfloat)results[i].point[j].y);
env->SetObjectArrayElement(keypoint_array, j, keypointj);
}
auto score_array = env->NewFloatArray(results[i].length);
env->SetFloatArrayRegion(score_array, 0, results[i].length, (jfloat *)results[i].score);
auto res = env->NewObject(result_cls, result_ctor, keypoint_array, score_array);
env->SetObjectArrayElement(array, i, res);
}
mmdeploy_pose_detector_release_result(results, size);
return array;
});
}

View File

@ -0,0 +1,36 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_PoseDetector */
#ifndef _Included_mmdeploy_PoseDetector
#define _Included_mmdeploy_PoseDetector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_PoseDetector
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_PoseDetector_create(JNIEnv *, jobject, jstring, jstring,
jint);
/*
* Class: mmdeploy_PoseDetector
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_PoseDetector_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_PoseDetector
* Method: apply
* Signature: (J[Lmmdeploy/Mat;)[Lmmdeploy/PoseDetector/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_PoseDetector_apply(JNIEnv *, jobject, jlong,
jobjectArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,71 @@
#include "mmdeploy_Restorer.h"
#include <numeric>
#include "mmdeploy/apis/c/restorer.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_Restorer_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t restorer{};
auto ec = mmdeploy_restorer_create_by_path(model_path, device_name, (int)device_id, &restorer);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create restorer, code = {}", ec);
}
return (jlong)restorer;
}
void Java_mmdeploy_Restorer_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_Restorer_destroy");
mmdeploy_restorer_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_Restorer_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_mat_t *results{};
auto ec = mmdeploy_restorer_apply((mm_handle_t)handle, imgs, size, &results);
if (ec) {
MMDEPLOY_ERROR("failed to apply restorer, code = {}", ec);
}
const char *java_enum_format[] = {"BGR", "RGB", "GRAYSCALE", "NV12", "NV21", "BGRA"};
const char *java_enum_type[] = {"FLOAT", "HALF", "INT8", "INT32"};
auto result_cls = env->FindClass("mmdeploy/Restorer$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "(Lmmdeploy/Mat;)V");
auto array = env->NewObjectArray(size, result_cls, nullptr);
auto mat_cls = env->FindClass("mmdeploy/Mat");
auto mat_ctor =
env->GetMethodID(mat_cls, "<init>", "(IIILmmdeploy/PixelFormat;Lmmdeploy/DataType;[B)V");
auto format_cls = env->FindClass("mmdeploy/PixelFormat");
auto type_cls = env->FindClass("mmdeploy/DataType");
mm_mat_t *current_result = results;
for (int i = 0; i < size; ++i) {
auto test_format = current_result->format;
auto jdata = env->NewByteArray(current_result->width * current_result->height *
current_result->channel);
env->SetByteArrayRegion(
jdata, 0, current_result->width * current_result->height * current_result->channel,
(const jbyte *)(current_result->data));
jfieldID format_id = env->GetStaticFieldID(
format_cls, java_enum_format[current_result->format], "Lmmdeploy/PixelFormat;");
jobject format = env->GetStaticObjectField(format_cls, format_id);
jfieldID type_id = env->GetStaticFieldID(type_cls, java_enum_type[current_result->type],
"Lmmdeploy/DataType;");
jobject type = env->GetStaticObjectField(type_cls, type_id);
auto result_mat = env->NewObject(mat_cls, mat_ctor, (jint)(current_result->height),
(jint)(current_result->width),
(jint)(current_result->channel), format, type, jdata);
auto res = env->NewObject(result_cls, result_ctor, result_mat);
env->SetObjectArrayElement(array, i, res);
current_result++;
}
mmdeploy_restorer_release_result(results, size);
return array;
});
}

View File

@ -0,0 +1,34 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_Restorer */
#ifndef _Included_mmdeploy_Restorer
#define _Included_mmdeploy_Restorer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_Restorer
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_Restorer_create(JNIEnv *, jobject, jstring, jstring, jint);
/*
* Class: mmdeploy_Restorer
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_Restorer_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_Restorer
* Method: apply
* Signature: (J[Lmmdeploy/Mat;)[Lmmdeploy/Restorer/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_Restorer_apply(JNIEnv *, jobject, jlong, jobjectArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,52 @@
#include "mmdeploy_Segmentor.h"
#include <numeric>
#include "mmdeploy/apis/c/segmentor.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_Segmentor_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t segmentor{};
auto ec = mmdeploy_segmentor_create_by_path(model_path, device_name, (int)device_id, &segmentor);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create segmentor, code = {}", ec);
}
return (jlong)segmentor;
}
void Java_mmdeploy_Segmentor_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_Segmentor_destroy");
mmdeploy_segmentor_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_Segmentor_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_segment_t *results{};
auto ec = mmdeploy_segmentor_apply((mm_handle_t)handle, imgs, size, &results);
if (ec) {
MMDEPLOY_ERROR("failed to apply segmentor, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/Segmentor$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "(III[I)V");
auto array = env->NewObjectArray(size, result_cls, nullptr);
for (int i = 0; i < size; ++i) {
int *mask = results[i].mask;
jintArray jmask = env->NewIntArray(results[i].height * results[i].width);
env->SetIntArrayRegion(jmask, 0, results[i].width * results[i].height, (const jint *)mask);
auto res = env->NewObject(result_cls, result_ctor, (jint)results[i].height,
(jint)results[i].width, (jint)results[i].classes, jmask);
env->SetObjectArrayElement(array, i, res);
}
mmdeploy_segmentor_release_result(results, size);
return array;
});
}

View File

@ -0,0 +1,35 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_Segmentor */
#ifndef _Included_mmdeploy_Segmentor
#define _Included_mmdeploy_Segmentor
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_Segmentor
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_Segmentor_create(JNIEnv *, jobject, jstring, jstring, jint);
/*
* Class: mmdeploy_Segmentor
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_Segmentor_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_Segmentor
* Method: apply
* Signature: (J[Lmmdeploy/Mat;)[Lmmdeploy/Segmentor/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_Segmentor_apply(JNIEnv *, jobject, jlong,
jobjectArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,64 @@
#include "mmdeploy_TextDetector.h"
#include <numeric>
#include "mmdeploy/apis/c/text_detector.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_TextDetector_create(JNIEnv *env, jobject, jstring modelPath, jstring deviceName,
jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t text_detector{};
auto ec = mmdeploy_text_detector_create_by_path(model_path, device_name, (int)device_id,
&text_detector);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create text_detector, code = {}", ec);
}
return (jlong)text_detector;
}
void Java_mmdeploy_TextDetector_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_TextDetector_destroy");
mmdeploy_text_detector_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_TextDetector_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images, jintArray counts) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_text_detect_t *results{};
int *result_count{};
auto ec =
mmdeploy_text_detector_apply((mm_handle_t)handle, imgs, size, &results, &result_count);
if (ec) {
MMDEPLOY_ERROR("failed to apply detector, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/TextDetector$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "([Lmmdeploy/PointF;F)V");
auto total = std::accumulate(result_count, result_count + size, 0);
auto array = env->NewObjectArray(total, result_cls, nullptr);
auto point_cls = env->FindClass("mmdeploy/PointF");
auto point_ctor = env->GetMethodID(point_cls, "<init>", "(FF)V");
for (int i = 0; i < total; ++i) {
jobjectArray bbox = env->NewObjectArray(4, point_cls, nullptr);
for (int j = 0; j < 4; ++j) {
auto point = env->NewObject(point_cls, point_ctor, (jfloat)results[i].bbox[j].x,
(jfloat)results[i].bbox[j].y);
env->SetObjectArrayElement(bbox, j, point);
}
auto res = env->NewObject(result_cls, result_ctor, bbox, (jfloat)results[i].score);
env->SetObjectArrayElement(array, i, res);
}
auto counts_array = env->GetIntArrayElements(counts, nullptr);
for (int i = 0; i < size; ++i) {
counts_array[i] = result_count[i];
}
env->ReleaseIntArrayElements(counts, counts_array, 0);
mmdeploy_text_detector_release_result(results, result_count, size);
return array;
});
}

View File

@ -0,0 +1,36 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_TextDetector */
#ifndef _Included_mmdeploy_TextDetector
#define _Included_mmdeploy_TextDetector
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_TextDetector
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_TextDetector_create(JNIEnv *, jobject, jstring, jstring,
jint);
/*
* Class: mmdeploy_TextDetector
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_TextDetector_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_TextDetector
* Method: apply
* Signature: (J[Lmmdeploy/Mat;[I)[Lmmdeploy/TextDetector/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_TextDetector_apply(JNIEnv *, jobject, jlong,
jobjectArray, jintArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,102 @@
#include "mmdeploy_TextRecognizer.h"
#include <numeric>
#include "mmdeploy/apis/c/text_recognizer.h"
#include "mmdeploy/apis/java/native/common.h"
#include "mmdeploy/core/logger.h"
jlong Java_mmdeploy_TextRecognizer_create(JNIEnv *env, jobject, jstring modelPath,
jstring deviceName, jint device_id) {
auto model_path = env->GetStringUTFChars(modelPath, nullptr);
auto device_name = env->GetStringUTFChars(deviceName, nullptr);
mm_handle_t text_recognizer{};
auto ec = mmdeploy_text_recognizer_create_by_path(model_path, device_name, (int)device_id,
&text_recognizer);
env->ReleaseStringUTFChars(modelPath, model_path);
env->ReleaseStringUTFChars(deviceName, device_name);
if (ec) {
MMDEPLOY_ERROR("failed to create text recognizer, code = {}", ec);
}
return (jlong)text_recognizer;
}
void Java_mmdeploy_TextRecognizer_destroy(JNIEnv *, jobject, jlong handle) {
MMDEPLOY_INFO("Java_mmdeploy_TextRecognizer_destroy"); // maybe use info?
mmdeploy_text_recognizer_destroy((mm_handle_t)handle);
}
jobjectArray Java_mmdeploy_TextRecognizer_apply(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_text_recognize_t *results{};
auto ec = mmdeploy_text_recognizer_apply((mm_handle_t)handle, imgs, size, &results);
if (ec) {
MMDEPLOY_ERROR("failed to apply text recognizer, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/TextRecognizer$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "([C[F)V");
auto array = env->NewObjectArray(size, result_cls, nullptr);
for (int i = 0; i < size; ++i) {
auto text = env->NewCharArray(results[i].length);
auto score = env->NewFloatArray(results[i].length);
env->SetCharArrayRegion(text, 0, results[i].length, (jchar *)results[i].text);
env->SetFloatArrayRegion(score, 0, results[i].length, (jfloat *)results[i].score);
auto res = env->NewObject(result_cls, result_ctor, text, score);
env->SetObjectArrayElement(array, i, res);
}
mmdeploy_text_recognizer_release_result(results, size);
return array;
});
}
jobjectArray Java_mmdeploy_TextRecognizer_applyBbox(JNIEnv *env, jobject thiz, jlong handle,
jobjectArray images, jobjectArray bboxes,
jintArray bbox_count) {
return With(env, images, [&](const mm_mat_t imgs[], int size) {
mm_text_recognize_t *recog_results{};
mm_text_detect_t *det_results = new mm_text_detect_t[env->GetArrayLength(bboxes)];
int *det_result_count = new int[env->GetArrayLength(bbox_count)];
auto bbox_cls = env->FindClass("mmdeploy/TextDetector$Result");
auto pointf_cls = env->FindClass("mmdeploy/PointF");
auto bbox_id = env->GetFieldID(bbox_cls, "bbox", "[Lmmdeploy/PointF;");
auto score_id = env->GetFieldID(bbox_cls, "score", "F");
auto x_id = env->GetFieldID(pointf_cls, "x", "F");
auto y_id = env->GetFieldID(pointf_cls, "y", "F");
env->GetIntArrayRegion(bbox_count, 0, env->GetArrayLength(bbox_count), det_result_count);
int total_bboxes = env->GetArrayLength(bboxes);
for (int i = 0; i < total_bboxes; ++i) {
auto bboxi = env->GetObjectArrayElement(bboxes, i);
auto point_array = (jobjectArray)env->GetObjectField(bboxi, bbox_id);
for (int j = 0; j < 4; ++j) {
auto pointj = env->GetObjectArrayElement(point_array, j);
det_results[i].bbox[j].x = (float)env->GetFloatField(pointj, x_id);
det_results[i].bbox[j].y = (float)env->GetFloatField(pointj, y_id);
det_results[i].score = (float)env->GetFloatField(bboxi, score_id);
}
}
auto ec = mmdeploy_text_recognizer_apply_bbox((mm_handle_t)handle, imgs, size,
(const mm_text_detect_t *)det_results,
det_result_count, &recog_results);
if (ec) {
MMDEPLOY_ERROR("failed to apply bbox for text recognizer, code = {}", ec);
}
auto result_cls = env->FindClass("mmdeploy/TextRecognizer$Result");
auto result_ctor = env->GetMethodID(result_cls, "<init>", "([B[F)V");
auto array = env->NewObjectArray(total_bboxes, result_cls, nullptr);
for (int i = 0; i < total_bboxes; ++i) {
auto text = env->NewByteArray(recog_results[i].length);
auto score = env->NewFloatArray(recog_results[i].length);
env->SetByteArrayRegion(text, 0, recog_results[i].length, (jbyte *)recog_results[i].text);
env->SetFloatArrayRegion(score, 0, recog_results[i].length, (jfloat *)recog_results[i].score);
auto res = env->NewObject(result_cls, result_ctor, text, score);
env->SetObjectArrayElement(array, i, res);
}
mmdeploy_text_recognizer_release_result(recog_results, size);
mmdeploy_text_detector_release_result(det_results, det_result_count, 1);
return array;
});
}

View File

@ -0,0 +1,45 @@
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class mmdeploy_TextRecognizer */
#ifndef _Included_mmdeploy_TextRecognizer
#define _Included_mmdeploy_TextRecognizer
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: mmdeploy_TextRecognizer
* Method: create
* Signature: (Ljava/lang/String;Ljava/lang/String;I)J
*/
JNIEXPORT jlong JNICALL Java_mmdeploy_TextRecognizer_create(JNIEnv *, jobject, jstring, jstring,
jint);
/*
* Class: mmdeploy_TextRecognizer
* Method: destroy
* Signature: (J)V
*/
JNIEXPORT void JNICALL Java_mmdeploy_TextRecognizer_destroy(JNIEnv *, jobject, jlong);
/*
* Class: mmdeploy_TextRecognizer
* Method: apply
* Signature: (J[Lmmdeploy/Mat;)[Lmmdeploy/TextRecognizer/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_TextRecognizer_apply(JNIEnv *, jobject, jlong,
jobjectArray);
/*
* Class: mmdeploy_TextRecognizer
* Method: applyBbox
* Signature: (J[Lmmdeploy/Mat;[Lmmdeploy/TextDetector/Result;[I)[Lmmdeploy/TextRecognizer/Result;
*/
JNIEXPORT jobjectArray JNICALL Java_mmdeploy_TextRecognizer_applyBbox(JNIEnv *, jobject, jlong,
jobjectArray, jobjectArray,
jintArray);
#ifdef __cplusplus
}
#endif
#endif

View File

@ -0,0 +1,48 @@
import mmdeploy.Classifier;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class ImageClassification {
public static void main(String[] args) {
// Parse arguments
if (args.length != 3) {
System.out.println("usage:\njava ImageClassification deviceName modelPath imagePath");
return;
}
String deviceName = args[0];
String modelPath = args[1];
String imagePath = args[2];
// create classifier
Classifier classifier = null;
try {
classifier = new Classifier(modelPath, deviceName, 0);
// load image
Mat img = Utils.loadImage(imagePath);
// apply classifier
Classifier.Result[] result = classifier.apply(img);
// print results
for (Classifier.Result value : result) {
System.out.printf("label: %d, score: %.4f\n", value.label_id, value.score);
}
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release classifier
if (classifier != null) {
classifier.release();
}
}
}
}

View File

@ -0,0 +1,48 @@
import mmdeploy.Restorer;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class ImageRestorer {
public static void main(String[] args) {
// Parse arguments
if (args.length != 3) {
System.out.println("usage:\njava ImageRestorer deviceName modelPath imagePath");
return;
}
String deviceName = args[0];
String modelPath = args[1];
String imagePath = args[2];
// create restorer
Restorer restorer = null;
try {
restorer = new Restorer(modelPath, deviceName, 0);
// load image
Mat img = Utils.loadImage(imagePath);
// apply restorer
Restorer.Result[] result = restorer.apply(img);
// print results
for (Restorer.Result value : result) {
System.out.printf("Restore image height=%d, width=%d\n", value.res.shape[0], value.res.shape[1]);
}
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release restorer
if (restorer != null) {
restorer.release();
}
}
}
}

View File

@ -0,0 +1,48 @@
import mmdeploy.Segmentor;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class ImageSegmentation {
public static void main(String[] args) {
// Parse arguments
if (args.length != 3) {
System.out.println("usage:\njava ImageSegmentation deviceName modelPath imagePath");
return;
}
String deviceName = args[0];
String modelPath = args[1];
String imagePath = args[2];
// create segmentor
Segmentor segmentor = null;
try {
segmentor = new Segmentor(modelPath, deviceName, 0);
// load image
Mat img = Utils.loadImage(imagePath);
// apply segmentor
Segmentor.Result[] result = segmentor.apply(img);
// print results
for (Segmentor.Result value : result) {
System.out.printf("mask height=%d, width=%d\n", value.height, value.width);
}
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release segmentor
if (segmentor != null) {
segmentor.release();
}
}
}
}

View File

@ -0,0 +1,68 @@
import mmdeploy.Detector;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.awt.Graphics;
import java.io.File;
import java.io.IOException;
public class ObjectDetection {
public static void main(String[] args) {
// Parse arguments
if (args.length != 3) {
System.out.println("usage:\njava ObjectDetection deviceName modelPath imagePath");
return;
}
String deviceName = args[0];
String modelPath = args[1];
String imagePath = args[2];
// create detector
Detector detector = null;
try {
detector = new Detector(modelPath, deviceName, 0);
// load image
BufferedImage srcImg = ImageIO.read(new File(imagePath));
Mat img = Utils.bufferedImage2Mat(srcImg);
// apply detector
Detector.Result[] result = detector.apply(img);
// print results
Graphics ghandle = srcImg.createGraphics();
for (int i = 0; i < result.length; i++) {
Detector.Result value = result[i];
System.out.printf("box %d, left=%.2f, top=%.2f, right=%.2f, bottom=%.2f, label=%d, score=%.4f\n",
i, value.bbox.left, value.bbox.top, value.bbox.right, value.bbox.bottom, value.label_id, value.score);
if ((value.bbox.right - value.bbox.left) < 1 || (value.bbox.bottom - value.bbox.top) < 1) {
continue;
}
// skip detections less than specified score threshold
if (value.score < 0.3) {
continue;
}
if (value.mask != null) {
System.out.printf("mask %d, height=%d, width=%d\n", i, value.mask.shape[0], value.mask.shape[1]);
}
ghandle.setColor(new Color(0, 255, 0));
ghandle.drawRect((int)value.bbox.left, (int)value.bbox.top, (int)value.bbox.right - (int)value.bbox.left + 1, (int)value.bbox.bottom - (int)value.bbox.top + 1);
}
ghandle.dispose();
ImageIO.write(srcImg, "png", new File("output_detection.png"));
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release detector
if (detector != null) {
detector.release();
}
}
}
}

60
demo/java/Ocr.java Normal file
View File

@ -0,0 +1,60 @@
import mmdeploy.TextDetector;
import mmdeploy.TextRecognizer;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class Ocr {
public static void main(String[] args) {
// Parse arguments
if (args.length != 4) {
System.out.println("usage:\njava TextDetection deviceName detModelPath recModelPath imagePath");
return;
}
String deviceName = args[0];
String detModelPath = args[1];
String recModelPath = args[2];
String imagePath = args[3];
// create text detector and recognizer
TextDetector text_detector = null;
TextRecognizer text_recognizer = null;
try {
text_detector = new TextDetector(detModelPath, deviceName, 0);
text_recognizer = new TextRecognizer(recModelPath, deviceName, 0);
// load image
Mat img = Utils.loadImage(imagePath);
// apply text detector
TextDetector.Result[] detResult = text_detector.apply(img);
int [] detResultCount = {detResult.length};
TextRecognizer.Result[] recResult = text_recognizer.applyBbox(img, detResult, detResultCount);
// print results
for (int i = 0; i < detResultCount[0]; ++i) {
System.out.printf("box[%d]: %s\n", i, new String(recResult[i].text));
for (int j = 0; j < 4; ++j) {
System.out.printf("x: %.2f, y: %.2f, ", detResult[i].bbox[j].x, detResult[i].bbox[j].y);
}
System.out.printf("\n");
}
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release text detector and recognizer
if (text_recognizer != null) {
text_recognizer.release();
}
if (text_detector != null) {
text_detector.release();
}
}
}
}

View File

@ -0,0 +1,50 @@
import mmdeploy.PoseDetector;
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class PoseDetection {
public static void main(String[] args) {
// Parse arguments
if (args.length != 3) {
System.out.println("usage:\njava PoseDetection deviceName modelPath imagePath");
return;
}
String deviceName = args[0];
String modelPath = args[1];
String imagePath = args[2];
// create pose estimator
PoseDetector pose_estimator = null;
try {
pose_estimator = new PoseDetector(modelPath, deviceName, 0);
// load image
Mat img = Utils.loadImage(imagePath);
// apply pose estimator
PoseDetector.Result[] result = pose_estimator.apply(img);
// print results
for (PoseDetector.Result value : result) {
for (int i = 0; i < value.point.length; i++) {
System.out.printf("point %d, x: %d, y: %d\n", i, (int)value.point[i].x, (int)value.point[i].y);
}
}
} catch (Exception e) {
System.out.println("exception: " + e.getMessage());
} finally {
// release pose estimator
if (pose_estimator != null) {
pose_estimator.release();
}
}
}
}

22
demo/java/README.md Normal file
View File

@ -0,0 +1,22 @@
# Usage
**step 1.** Compile Utils with Java APIs.
```
cd demo/java
javac --class-path ../../csrc/mmdeploy/apis/java/ Utils.java
cd ../..
```
**step 2.** Run the demo in the console.
Use **ImageClassification** as example.
First, you should set your model path and image path to `${MODEL_PATH}` and `${IMAGE_PATH}`. And then follow the bash codes.
```bash
export TASK=ImageClassification
export LD_LIBRARY_PATH=${PWD}/build/lib:${LD_LIBRARY_PATH}
cd demo/java
java -cp ../../csrc/mmdeploy/apis/java:./ ${TASK}.java cpu ${MODEL_PATH} ${IMAGE_PATH}
```

21
demo/java/Utils.java Normal file
View File

@ -0,0 +1,21 @@
import mmdeploy.PixelFormat;
import mmdeploy.DataType;
import mmdeploy.Mat;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.io.IOException;
public class Utils {
public static Mat loadImage(String path) throws IOException {
BufferedImage img = ImageIO.read(new File(path));
return bufferedImage2Mat(img);
}
public static Mat bufferedImage2Mat(BufferedImage img) {
byte[] data = ((DataBufferByte) img.getData().getDataBuffer()).getData();
return new Mat(img.getHeight(), img.getWidth(), img.getColorModel().getNumComponents(),
PixelFormat.BGR, DataType.INT8, data);
}
}

View File

@ -120,6 +120,12 @@ make install
<td>OFF</td>
<td>switch to build MMDeploy SDK python package</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_SDK_JAVA_API</td>
<td>{ON, OFF}</td>
<td>OFF</td>
<td>switch to build MMDeploy SDK Java API</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_TEST</td>
<td>{ON, OFF}</td>
@ -167,6 +173,7 @@ MMDeploy provides a recipe as shown below for building SDK with ncnn as inferenc
mkdir -p build && cd build
cmake .. \
-DMMDEPLOY_BUILD_SDK=ON \
-DMMDEPLOY_BUILD_SDK_JAVA_API=ON \
-DOpenCV_DIR=${OPENCV_ANDROID_SDK_DIR}/sdk/native/jni/abi-arm64-v8a \
-Dncnn_DIR=${NCNN_DIR}/build/install/lib/cmake/ncnn \
-DMMDEPLOY_TARGET_BACKENDS=ncnn \

View File

@ -284,6 +284,11 @@ export MMDEPLOY_DIR=$(pwd)
<td>OFF</td>
<td>switch to build MMDeploy SDK python package</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_SDK_JAVA_API</td>
<td>{ON, OFF}</td>
<td>switch to build MMDeploy SDK Java API</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_TEST</td>
<td>{ON, OFF}</td>

View File

@ -114,6 +114,12 @@ make install
<td>OFF</td>
<td>MMDeploy SDK 编译开关</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_SDK_JAVA_API</td>
<td>{ON, OFF}</td>
<td>OFF</td>
<td>MMDeploy SDK Java API的编译开关</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_TEST</td>
<td>{ON, OFF}</td>
@ -161,6 +167,7 @@ make install
mkdir -p build && cd build
cmake .. \
-DMMDEPLOY_BUILD_SDK=ON \
-DMMDEPLOY_BUILD_SDK_JAVA_API=ON \
-DOpenCV_DIR=${OPENCV_ANDROID_SDK_DIR}/sdk/native/jni/abi-arm64-v8a \
-Dncnn_DIR=${NCNN_DIR}/build/install/lib/cmake/ncnn \
-DMMDEPLOY_TARGET_BACKENDS=ncnn \

View File

@ -280,6 +280,12 @@ export MMDEPLOY_DIR=$(pwd)
<td>OFF</td>
<td>MMDeploy SDK python package的编译开关</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_SDK_JAVA_API</td>
<td>{ON, OFF}</td>
<td>OFF</td>
<td>MMDeploy SDK Java API的编译开关</td>
</tr>
<tr>
<td>MMDEPLOY_BUILD_TEST</td>
<td>{ON, OFF}</td>