日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術(shù)文章
文章詳情頁

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

瀏覽:157日期:2022-09-25 10:31:39

代碼鏈接:

https://github.com/watersink/enet-as-linux

本代碼可以在模擬器下進(jìn)行跑。

環(huán)境:

Android studio 3.6

Sdk:android10 api 29

Ndk:r15c

Ncnn:20200226

Opencv:Opencv3.4.1 android sdk

Linux下的代碼測試:

mkdir buildcd buildcmake ..make./enet

運行效果,

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

Android開始:

(1)新建工程,

New->New Project->選擇Native c++ ->工程名enet->c++11

(2)app/src/cpp下面增加opencv和ncnn的頭文件,include

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

(3)app/src/main下面增加ncnn 和opencv的靜態(tài)庫文件和動態(tài)庫文件,

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

(4)app/src/main下面增加模型文件assets

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

(5)修改布局文件,app/src/main/res/layout/ activity_main.xml

<?xml version='1.0' encoding='utf-8'?><RelativeLayout xmlns:android='http://schemas.android.com/apk/res/android' xmlns:app='http://schemas.android.com/apk/res-auto' xmlns:tools='http://schemas.android.com/tools' android:layout_width='match_parent' android:layout_height='match_parent' tools:context='.MainActivity'> <LinearLayout android: android:layout_alignParentBottom='true' android:layout_width='match_parent' android:layout_height='wrap_content' android:orientation='horizontal'> <Button android: android:layout_weight='1' android:layout_width='0dp' android:layout_height='wrap_content' android:text='選圖'/> <Button android: android:layout_weight='1' android:layout_width='0dp' android:layout_height='wrap_content' android:text='分割'/> </LinearLayout> <ImageView android: android:layout_width='match_parent' android:layout_height='match_parent' android:layout_above='@id/btn_ll' android:layout_alignParentTop='true' android:layout_marginTop='1dp' android:layout_marginBottom='-1dp' /></RelativeLayout>

(6) app/src/main/java/com/example/enet增加ENET類,

public class ENET { public native boolean Init(byte[] param, byte[] bin); public native float[] Process(Bitmap bitmap); // Used to load the ’native-lib’ library on application startup. static { System.loadLibrary('ENET'); }}

(7) app/src/main/cpp/enet-jni.cpp實現(xiàn)其jni方法,

extern 'C'JNIEXPORT jboolean JNICALLJava_com_example_enet_ENET_Init(JNIEnv *env, jobject thiz, jbyteArray param, jbyteArray bin) { // TODO: implement Init() ncnn::Mat ncnn_param; ncnn::Mat ncnn_bin; // init param { int len = env->GetArrayLength(param); ncnn_param.create(len, (size_t) 1u); env->GetByteArrayRegion(param, 0, len, (jbyte *) ncnn_param); } // init bin { int len = env->GetArrayLength(bin); ncnn_bin.create(len, (size_t) 1u); env->GetByteArrayRegion(bin, 0, len, (jbyte *) ncnn_bin); } ncnn_net = new ENET(ncnn_param,ncnn_bin); return JNI_TRUE;}extern 'C'JNIEXPORT jfloatArray JNICALLJava_com_example_enet_ENET_Process(JNIEnv *env, jobject thiz, jobject bitmap) { // TODO: implement Process() // 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); // 把像素轉(zhuǎn)換成data,并指定通道順序 // 因為圖像預(yù)處理每個網(wǎng)絡(luò)層輸入的數(shù)據(jù)格式不一樣一般為300*300 128*128等等所以這類需要一個resize的操作可以在cpp中寫,也可以是java讀入圖片時有個resize操作 //in = ncnn::Mat::from_pixels_resize((const unsigned char*)indata, ncnn::Mat::PIXEL_RGBA2RGB, width, height,300,300); in = ncnn::Mat::from_pixels(static_cast<const unsigned char *>(indata), ncnn::Mat::PIXEL_RGBA2BGR, width, height); // 下面一行為debug代碼 __android_log_print(ANDROID_LOG_DEBUG, 'ENetJniIn', 'enet_process_has_input1, in.w: %d; in.h: %d in.c:%d ', in.w, in.h,in.c); //AndroidBitmap_unlockPixels(env, bitmap); } { ncnn::Mat out = ncnn_net->process(in); __android_log_print(ANDROID_LOG_DEBUG, 'ENetJniIn', 'enet_process_has_output, in.w: %d; in.h: %d in.c:%d ', out.w, out.h,out.c); int output_wsize = out.w; int output_hsize = out.h; //輸出整理 float *output[output_wsize * output_hsize]; // float類型 for(int i = 0; i< out.h; i++) { for (int j = 0; j < out.w; j++) { output[i*output_wsize + j] = &out.row( i)[j]; } } //建立float數(shù)組 長度為 output_wsize * output_hsize,如果只是ouput_size相當(dāng)于只有一行的out的數(shù)據(jù)那就是一個object檢測數(shù)據(jù) jfloatArray jOutputData = env->NewFloatArray(output_wsize * output_hsize); if (jOutputData == nullptr) return nullptr; env->SetFloatArrayRegion(jOutputData, 0, output_wsize * output_hsize,reinterpret_cast<const jfloat *>(*output)); return jOutputData; }}

(8) app/src/main/java/com/example/enet中MainActivity做具體的調(diào)用實現(xiàn),

public class MainActivity extends AppCompatActivity { private ENET enet = new ENET(); //java接口實例化 下面直接利用java函數(shù)調(diào)用NDK c++函數(shù) private Bitmap yourSelectedImage = null; private static final int SELECT_IMAGE = 1; private static final String TAG = MainActivity.class.getName(); private ImageView show_image; private boolean load_result = false; private int[] ddims = {1, 3, 512, 288}; //這里的維度的值要和train model的input 一一對應(yīng) @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); try { initENet();//初始化模型 Log.e('MainActivity', 'initENet ok'); } catch (IOException e) { Log.e('MainActivity', 'initENet error'); } init_view();//檢測+view畫圖 } // initialize view private void init_view() { show_image = (ImageView) findViewById(R.id.show_image); Button use_photo = (Button) findViewById(R.id.use_photo); use_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { Intent i = new Intent(Intent.ACTION_PICK); i.setType('image/*'); startActivityForResult(i, SELECT_IMAGE); } }); Button detect_photo = (Button) findViewById(R.id.detect_photo); detect_photo.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View arg0) { if (yourSelectedImage == null) return; predict_image(yourSelectedImage); } }); } private void initENet() throws IOException { byte[] param = null; byte[] bin = null; { //用io流讀取二進(jìn)制文件,最后存入到byte[]數(shù)組中 InputStream assetsInputStream = getAssets().open('enet_512288.param.bin');// param: 網(wǎng)絡(luò)結(jié)構(gòu)文件 int available = assetsInputStream.available(); param = new byte[available]; int byteCode = assetsInputStream.read(param); assetsInputStream.close(); } { //用io流讀取二進(jìn)制文件,最后存入到byte上,轉(zhuǎn)換為int型 InputStream assetsInputStream = getAssets().open('enet_512288.bin');//bin: model文件 int available = assetsInputStream.available(); bin = new byte[available]; int byteCode = assetsInputStream.read(bin); assetsInputStream.close(); } load_result = enet.Init(param, bin);// 再將文件傳入java的NDK接口(c++ 代碼中的init接口 ) Log.d('load model', 'ENet_load_model_result:' + load_result); } @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); if (resultCode == RESULT_OK && null != data) { Uri selectedImage = data.getData(); try { if (requestCode == SELECT_IMAGE) { Bitmap bitmap = decodeUri(selectedImage); Bitmap rgba = bitmap.copy(Bitmap.Config.ARGB_8888, true); // resize to 512x288 yourSelectedImage = Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false); show_image.setImageBitmap(yourSelectedImage); } } catch (FileNotFoundException e) { Log.e('MainActivity', 'FileNotFoundException'); return; } } } private Bitmap decodeUri(Uri selectedImage) throws FileNotFoundException { // Decode image size BitmapFactory.Options o = new BitmapFactory.Options(); o.inJustDecodeBounds = true; BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o); // The new size we want to scale to final int REQUIRED_SIZE = 600; // Find the correct scale value. It should be the power of 2. int width_tmp = o.outWidth, height_tmp = o.outHeight; int scale = 1; while (true) { if (width_tmp / 2 < REQUIRED_SIZE || height_tmp / 2 < REQUIRED_SIZE) { break; } width_tmp /= 2; height_tmp /= 2; scale *= 2; } // Decode with inSampleSize BitmapFactory.Options o2 = new BitmapFactory.Options(); o2.inSampleSize = scale; return BitmapFactory.decodeStream(getContentResolver().openInputStream(selectedImage), null, o2); } // predict image private void predict_image(Bitmap bmp) { // picture to float array Bitmap rgba = bmp.copy(Bitmap.Config.ARGB_8888, true); // resize Bitmap input_bmp = Bitmap.createScaledBitmap(rgba, ddims[2], ddims[3], false); try { // Data format conversion takes too long // Log.d('inputData', Arrays.toString(inputData)); long start = System.currentTimeMillis(); // get predict result float[] result = enet.Process(input_bmp); // time end long end = System.currentTimeMillis(); Log.d(TAG, 'origin predict result:' + Arrays.toString(result)); long time = end - start; Log.d('result length', 'length of result: ' + String.valueOf(result.length)); // 畫布配置 Canvas canvas = new Canvas(input_bmp); //圖像上畫矩形 Paint paint = new Paint(); //continue to draw rect Log.d(TAG, 'result :' + result.length); Log.d(TAG, 'result :' + Arrays.toString(result)); for(int num = 0; num < result.length; num++){ // 畫框 int row =num%ddims[2]; int col = num/ddims[2]; if (result[num]==1){ paint.setColor(Color.RED); paint.setStyle(Paint.Style.STROKE);//不填充 canvas.drawCircle(row, col, 1, paint); } if (result[num]==2){ paint.setColor(Color.BLUE); paint.setStyle(Paint.Style.STROKE);//不填充 canvas.drawCircle(row, col, 1, paint); } if (result[num]==3){ paint.setColor(Color.GREEN); paint.setStyle(Paint.Style.STROKE);//不填充 canvas.drawCircle(row, col, 1, paint); } } show_image.setImageBitmap(input_bmp); } catch (Exception e) { e.printStackTrace(); } }}

(9) app/src/main/cpp下面修改CMakeLists

cmake_minimum_required(VERSION 3.4.1)include_directories(include)file(GLOB ENET_SRC *.h *.cpp)set(ENET_COMPILE_CODE ${ENET_SRC})add_library(libopencv_java3 SHARED IMPORTED)set_target_properties(libopencv_java3 PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libopencv_java3.so) add_library(libncnn STATIC IMPORTED )set_target_properties(libncnn PROPERTIES IMPORTED_LOCATION ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libncnn.a)add_library( # Sets the name of the library. ENET ## 為生成.so的文字最好直接和.c名字一樣,需要更改 # Sets the library as a shared library. SHARED # Provides a relative path to your source file(s). ${ENET_COMPILE_CODE})##cpp文件的namefind_library( # Sets the name of the path variable. log-lib # Specifies the name of the NDK library that # you want CMake to locate. log )target_link_libraries( # Specifies the target library. ENET libncnn libopencv_java3 jnigraphics android # Links the target library to the log library # included in the NDK. ${log-lib} )

(10) app/src/下面修改build.gradle,增加下面的設(shè)置,

externalNativeBuild { cmake { arguments '-DANDROID_TOOLCHAIN=clang' cFlags '-fopenmp -O2 -fvisibility=hidden -fomit-frame-pointer -fstrict-aliasing -ffunction-sections -fdata-sections -ffast-math ' cppFlags '-fopenmp -O2 -fvisibility=hidden -fvisibility-inlines-hidden -fomit-frame-pointer -fstrict-aliasing -ffunction-sections -fdata-sections -ffast-math ' arguments '-DANDROID_STL=c++_shared', '-DANDROID_CPP_FEATURES=rtti exceptions' cppFlags '' cppFlags '-std=c++11' cppFlags '-frtti' cppFlags '-fexceptions' } } ndk { abiFilters ’armeabi-v7a’// , ’arm64-v8a’ //,’x86’, ’x86_64’, ’armeabi’ stl 'gnustl_static' }

整體目錄結(jié)構(gòu):

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

最終效果:

基于Android studio3.6的JNI教程之ncnn之語義分割ENet

總結(jié)

到此這篇關(guān)于基于Android studio3.6的JNI教程之ncnn之語義分割ENet的文章就介紹到這了,更多相關(guān)android studio 語義分割enet內(nèi)容請搜索好吧啦網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持好吧啦網(wǎng)!

標(biāo)簽: Android
相關(guān)文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
综合国产视频| 91精品日本| 欧美影院精品| 婷婷亚洲成人| 丝袜美腿亚洲一区| 免费看日韩精品| 丝袜美腿一区二区三区| 亚洲精品美女91| 日本国产一区| 欧美日韩1区| 免费日韩av片| 中文字幕日本一区| 色综合五月天| 丝袜诱惑制服诱惑色一区在线观看| 欧美特黄a级高清免费大片a级| 久久蜜桃av| 黑丝一区二区三区| 热久久久久久久| 日本午夜精品一区二区三区电影 | 麻豆视频在线看| 免费一级欧美片在线观看网站| 国产精品对白| 亚洲精品欧美| 久久aⅴ国产紧身牛仔裤| 日韩视频在线一区二区三区| 日韩电影免费网址| 亚洲福利久久| 久久国产精品免费精品3p | 综合国产视频| 久久久久久夜| 国产三级一区| 精品午夜久久| 亚洲一级高清| 91精品美女| 欧美aa在线视频| 国产在视频一区二区三区吞精| 精品日韩视频| 99久久视频| 色爱综合网欧美| 在线视频观看日韩| 久久av一区| 国产亚洲字幕| 欧美天堂视频| 一区在线视频观看| 在线免费观看亚洲| 午夜av成人| 午夜日韩在线| 欧美精品影院| 日韩欧美一区二区三区免费观看| 亚洲精品中文字幕乱码| 亚洲一区二区网站| 日本va欧美va欧美va精品| 伊人久久国产| 日韩精品第二页| 亚洲深夜视频| 亚洲日本欧美| 日韩一区二区中文| 亚洲精品福利| 欧美成a人免费观看久久| 无码日韩精品一区二区免费| 亚洲午夜天堂| 欧美在线日韩| 午夜久久福利| 久久精品免费看| 久久av在线| 国产精品久久久久av蜜臀 | 日韩高清不卡在线| 麻豆视频在线观看免费网站黄| 欧美在线综合| 理论片午夜视频在线观看| 亚洲色图综合| 久久久久99| 国产精品毛片久久久| 欧美精品自拍| 亚洲免费福利| 久久不见久久见免费视频7| 亚洲激情不卡| 国产传媒av在线| 国产日韩精品视频一区二区三区| 成人看片网站| 国产精品极品在线观看| 天堂av在线一区| 成人日韩精品| 久久gogo国模啪啪裸体| 亚洲欧洲av| 亚洲国产不卡| 一区二区三区四区日本视频| 国产精品日本一区二区不卡视频 | 99久久婷婷这里只有精品| 国产成人精选| 国产欧美日韩一级| 国产精品色网| 亚洲91精品| 国产精品99久久精品| 日韩av午夜在线观看| 亚洲伊人精品酒店| 激情欧美日韩一区| 欧美一级鲁丝片| 久久久久观看| 国产精品欧美三级在线观看| 五月亚洲婷婷 | 日本а中文在线天堂| 国产精品密蕾丝视频下载| 免费不卡在线视频| 精品一区毛片| 91精品综合| 成人久久久久| 97视频热人人精品免费| 国产精品宾馆| 国产亚洲一区| 国产九一精品| 日本在线观看不卡视频| 亚洲尤物av| 99精品美女| 在线精品一区| 少妇精品久久久一区二区三区| 欧美成a人国产精品高清乱码在线观看片在线观看久 | 国产一区 二区| 日韩av影院| 欧美日韩在线精品一区二区三区激情综合| 视频一区视频二区在线观看| 亚洲深夜影院| 99精品在线观看| 四虎4545www国产精品| 日本欧美不卡| 91精品蜜臀一区二区三区在线| 蜜桃精品在线| 欧美福利专区| 欧美.日韩.国产.一区.二区| 亚洲五月婷婷| 亚洲精品99| 一区在线视频观看| 国产专区一区| 国产精品视区| 亚洲香蕉久久| 日韩高清电影免费| 国产三级精品三级在线观看国产| 国产亚洲欧美日韩精品一区二区三区 | 免费不卡在线视频| 首页欧美精品中文字幕| 另类激情亚洲| 中文在线日韩| 日韩av电影一区| 欧美成人aaa| 日韩影院二区| 激情综合网站| 日韩在线观看一区二区| 亚洲精品极品| 国产精品夜夜夜| 福利视频一区| 成人在线视频免费| 午夜av不卡| 日韩视频精品在线观看| 亚洲精品在线二区| 国产精品2区| 亚洲免费福利| 国产精品免费看| 日韩av不卡在线观看| 精品中文字幕一区二区三区| 午夜精品成人av| 亚洲一区国产一区| 欧美一区自拍| 亚洲综合在线电影| 丝袜a∨在线一区二区三区不卡| 欧美亚洲免费| 国产一区二区三区探花| 亚洲国产影院| 日本久久一区| 中文在线中文资源| 亚洲免费中文| 久久精品凹凸全集| 日韩大片免费观看| 午夜一级久久| 国产精品传媒麻豆hd| 日韩和的一区二在线| 久久国产66| 久久精品国产999大香线蕉| 伊人精品一区| 日韩精品视频在线看| 精品视频黄色| 香蕉精品久久| 午夜日韩影院| 91tv亚洲精品香蕉国产一区| 亚洲午夜久久| 桃色av一区二区| 91成人在线网站| 欧美日韩在线二区| 国产色99精品9i| 2023国产精品久久久精品双| 久久精品97| 国产视频一区在线观看一区免费| 国产精品视频一区二区三区四蜜臂| 亚洲午夜电影| 麻豆精品少妇| 免费一区二区视频| 国产成人精品三级高清久久91| 久久国产精品毛片| 国产+成+人+亚洲欧洲在线| 蜜臀国产一区二区三区在线播放| 成人国产精品一区二区免费麻豆|