The Beautiful Future
jnu structure return 본문
//
// Created by USER on 2019-05-14.
//
#include <android/log.h>
#include <jni.h>
#include <string>
#include <vector>
// crf
#include "libCRF/densecrf.h"
#define JNI_METHOD(NAME) Java_com_example_skysegandroid_SkySegInterface_##NAME
#define LOG_TAG "debug_sky"
#define LOGD(...) __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)
static ncnn::UnlockedPoolAllocator g_blob_pool_allocator;
static ncnn::PoolAllocator g_workspace_pool_allocator;
static ncnn::Mat ncnn_param;
static ncnn::Mat ncnn_bin;
static ncnn::Net net_sky_seg;
static CCrfParams paramCrf;
static DenseCRF2D crf(473, 473, 2);
extern "C" {
JNIEXPORT jstring JNICALL JNI_METHOD(Test)(JNIEnv *env, jobject obj, jstring str){
const char *name = env->GetStringUTFChars(str, NULL);
char msg[60] = "Hello ";
jstring result;
strcat(msg, name);
env->ReleaseStringUTFChars(str, name);
puts(msg);
result = env->NewStringUTF(msg);
return result;
}
JNIEXPORT jboolean JNICALL JNI_METHOD(Init)(JNIEnv *env, jobject obj, jbyteArray param, jbyteArray bin)
{
// int param
{
int len = env->GetArrayLength(param);
ncnn_param.create(len, (size_t) 1u);
env->GetByteArrayRegion(param, 0, len, (jbyte *) ncnn_param);
int ret = net_sky_seg.load_param((const unsigned char *) ncnn_param);
//LOGD("load_param %d %d", ret, len);
}
// init bin
{
int len = env->GetArrayLength(bin);
ncnn_bin.create(len, (size_t) 1u);
env->GetByteArrayRegion(bin, 0, len, (jbyte *) ncnn_bin);
int ret = net_sky_seg.load_model((const unsigned char *)ncnn_bin);
//LOGD("load_model %d %d", ret, len);
}
ncnn::Option opt;
opt.lightmode = true;
opt.num_threads = 4;
opt.blob_allocator = &g_blob_pool_allocator;
opt.workspace_allocator = &g_workspace_pool_allocator;
ncnn::set_default_option(opt);
return JNI_TRUE;
}
// public native String Detect(Bitmap bitmap);
JNIEXPORT jobject JNICALL JNI_METHOD(Predict)(JNIEnv* env, jobject obj, jobject bitmap)
{
// ncnn from bitmap
ncnn::Mat in;
AndroidBitmapInfo info;
AndroidBitmap_getInfo(env, bitmap, &info);
int width = info.width;
int height = info.height;
if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888)
return NULL;
void* indata;
AndroidBitmap_lockPixels(env, bitmap, &indata);
in = ncnn::Mat::from_pixels_resize((const unsigned char*)indata, ncnn::Mat::PIXEL_RGBA2RGB, width, height, 256, 256);
AndroidBitmap_unlockPixels(env, bitmap);
const unsigned char* pdata = (const unsigned char*)indata;
// LOGD("bmp, w: %d h: %d", width, height);
// LOGD("in, w: %d h: %d c: %d", in.w, in.h, in.c);
// ncnn_net
//const float mean_vals[3] = {127.5f, 127.5f, 127.5f};
//const float scale[3] = {0.007843f, 0.007843f, 0.007843f};
//in.substract_mean_normalize(mean_vals, scale);
ncnn::Extractor ex = net_sky_seg.create_extractor();
ex.input(seg_ncnn_SkyTrainDilatedResPspNet_iter_155520::LAYER_data, in);
ncnn::Mat out;
ex.extract(seg_ncnn_SkyTrainDilatedResPspNet_iter_155520::BLOB_prediction_intp, out);
int output_wsize = out.w;
int output_hsize = out.h;
int output_csize = out.c;
// LOGD("out w: %d", out.w);
// LOGD("out h: %d", out.h);
// LOGD("out c: %d", out.c);
// LOGD("out data: %p", (int*)out.data);
// resize image
ncnn::Mat resize_img;
resize_img = ncnn::Mat::from_pixels_resize((const unsigned char*)indata, ncnn::Mat::PIXEL_RGBA2RGB, width, height, output_wsize, output_hsize);
unsigned char* pucImgResize = (unsigned char*)resize_img.data;
// crf
float* prob = crf.inferCRF((const float*)out.data, pucImgResize, paramCrf);
float* pOut = (float*)out.data;
float* pfProb = (float*)prob;
LOGD("conf: %f %f %f", pOut[40], pOut[300], pOut[550]);
LOGD("prob: %f %f %f", pfProb[40], pfProb[300], pfProb[550]);
// classify
jbyte* pjbyPrediect = new jbyte[output_hsize*output_wsize];
int nCSout = output_wsize*output_hsize;
if (output_csize == 2) {
for (int i = 0; i < nCSout; ++i) {
if (pfProb[0] < pfProb[1]) {
pjbyPrediect[i] = 1;
}
pfProb += 2;
}
}
// else {
// float* pfProb = (float*)prob.get();
// for (int i = 0; i < nCSout; ++i) {
// if ((pfProb[0] < pfProb[1]) && (pfProb[2] < pfProb[1])) {
// pjbyPrediect[i] = 255;
// }
// pfProb += 3;
// }
// }
// float* pfProb0 = (float*)out.data;
// float* pfProb1 = pfProb0 + nCSout;
// for (int i = 0; i < nCSout; ++i) {
// if (pfProb0[0] < pfProb1[0]) {
// pjbyPrediect[i] = 0x01;
// }
// pfProb0++;
// pfProb1++;
// }
// jbyte* tmpP = pjbyPrediect;
// for( int i = 0; i < 400; i += 15){
//
// int idx = i*473;
// LOGD("%02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", tmpP[idx+10], tmpP[idx+50], tmpP[idx+100], tmpP[idx+150], tmpP[idx+200], tmpP[idx+250], tmpP[idx+300], tmpP[idx+350], tmpP[idx+400], tmpP[idx+450]);
// }
// copy result
jbyteArray byArrayPredict = env->NewByteArray(output_hsize*output_wsize);
env->SetByteArrayRegion(byArrayPredict, 0, output_hsize*output_wsize, pjbyPrediect);
delete[] pjbyPrediect;
jclass clsSkySegData = env->FindClass("com/example/skysegandroid/SkySegData");
jmethodID constructorSkySegData = env->GetMethodID(clsSkySegData, "<init>", "()V");
jobject objSkySegData = env->NewObject(clsSkySegData, constructorSkySegData, "");
jfieldID field_H = env->GetFieldID(clsSkySegData, "mH", "I");
jfieldID field_W = env->GetFieldID(clsSkySegData, "mW", "I");
jfieldID field_C = env->GetFieldID(clsSkySegData, "mC", "I");
jfieldID field_Format = env->GetFieldID(clsSkySegData, "mFormat", "I");
jfieldID field_Data = env->GetFieldID(clsSkySegData, "mData", "[B");
env->SetIntField(objSkySegData, field_H, output_hsize);
env->SetIntField(objSkySegData, field_W, output_wsize);
env->SetIntField(objSkySegData, field_C, 1);
env->SetIntField(objSkySegData, field_Format, 0);
env->SetObjectField(objSkySegData, field_Data, byArrayPredict);
return objSkySegData;
}
} //extern "C" {
'Android' 카테고리의 다른 글
camera (0) | 2019.10.02 |
---|---|
BottomSheet (0) | 2019.07.16 |
Android OpenCL (0) | 2017.10.17 |
ubuntu 16.04에 설치하기 (0) | 2017.06.14 |
자이로센서 (0) | 2017.04.18 |