日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > Android >内容正文

Android

WINDOWS系统Eclipse+NDK+Android + OpenCv

發(fā)布時間:2023/12/1 Android 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WINDOWS系统Eclipse+NDK+Android + OpenCv 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

WINDOWS系統(tǒng)Eclipse+NDK+Android + OpenCv

參考文檔博客

1 NDK環(huán)境搭建

http://jingyan.baidu.com/article/5d6edee22d908799eadeec9f.html

2 官方文檔

Android.mk與Application.mk如何編寫,OpenCV庫如何調(diào)用

http://docs.opencv.org/trunk/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#dev-with-ocv-on-android

3 OpenCv測試代碼來源

http://www.verydemo.com/demo_c131_i131095.html

4 NDK OpenCv測試入門程序(有問題)

http://blog.csdn.net/pwh0996/article/details/8957764

5 NDK測試入門程序(有問題)

http://blog.csdn.net/redoffice/article/details/6654714

6 出現(xiàn)部分問題的解法

http://blog.csdn.net/houshunwei/article/details/17217695

?

目前Android平臺下調(diào)用OpenCv庫函數(shù)有兩種方式:

1使用封裝的OpenCV API開發(fā)android:這種方式調(diào)用Java的包中的類實現(xiàn)類似。

2 利用JNI接口通過NDK平臺調(diào)用OpenCV API函數(shù)(這種方式比較普遍)。

本文將實現(xiàn)這兩種方式的調(diào)用。

第一部分 準(zhǔn)備工作:

1.1本文所使用的軟件版本如下:

ADT版本:ADT-22.6.3 ,開發(fā)工具ADT(Android Development Tool),集成了最新的ADT和NDK插件以及Eclipse,還有一個最新版本SDK。解壓之后就可以用了,下載地址http://developer.android.com/tools/sdk/ndk/index.html

NDK: android-ndk-r10, NDK插件:用于開發(fā)Android NDK的插件,ADT版本在20以上,就能安裝NDK插件,另外NDK集成了CDT插件,NDK版本在r7以上之后就集成了Cygwin,而且還是十分精簡版。下載鏈接見:http://developer.android.com/tools/sdk/ndk/index.html

OpenCV:OpenCV-2.4.4-android-sdk,下載地址http://opencv.org/downloads.html

?

1.2 配置NDK的環(huán)境變量

1.2.1解壓NDK壓縮包,配置環(huán)境變量。

將解壓的地址寫入環(huán)境變量PATH中。在命令提示符下輸入ndk-build如果彈出如下的錯誤,而不是說ndk-build not found,就說明ndk環(huán)境已經(jīng)安裝成功了。特別提示一下,搜索引擎中會告訴一些早期的NDK版本的使用,是在命令提示符下輸入build/host- setup.sh;但是NDK經(jīng)過更新,這個文件已經(jīng)沒有了。只需要輸入ndk-build就可以了。

Android NDK: Could not find application project directory !???
Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.???
/home/braincol/workspace/android/android-ndk-r5/build/core/build-local.mk:85: *** Android NDK: Aborting??? .? Stop.

1.2.2 Eclipse配置NDK環(huán)境

打開Eclipse,點Window->Preferences->Android->NDK,設(shè)置NDK路徑,例如當(dāng)前的NDK版本是是E:\android-ndk-r10。

1.3 配置OpenCv

下載OpenCV-2.4.4-android-sdk解壓出來,可以看到文件下有apk文件,doc文檔,sample例子程序,以及OpenCV4Android-sdk。

其 中,OpenCV4Android-sdk目錄即是我們開發(fā)opencv所需要的類庫;samples目錄中存放著若干opencv應(yīng)用示例(包括人臉檢測等),可為我們進(jìn)行 android下的opencv開發(fā)提供參考;doc目錄為opencv類庫的使用說明及api文檔等;而apk目錄則存放著對應(yīng)于各內(nèi)核版本的。

?

1.3.1 安裝OpenCV_Manager

????OpenCV_2.4.3.2_Manager_2.4應(yīng)用安裝包。此應(yīng)用用來管理手機設(shè)備中的opencv類庫,在運行opencv應(yīng)用之前,必須確保手機中已經(jīng)安裝了OpenCV_2.4.4.4_Manager_2.6_*.apk,否則opencv應(yīng)用將會因為無法加載opencv類庫而無法運行。

可以根據(jù)自己的手機類型來安裝OpenCV_2.4.4.4_Manager.apk.

通過查詢自己的手機CPU信息

adb shell

cat /proc/cpuinfo

?

我的手機是arm v7 –neon 架構(gòu)的,Android版本為4.4.4選擇第3個,第四個是適用于低版本Android系統(tǒng)的手機。

安裝完畢后,可以測試OpenCV_2.4.4.4_Manager.apk.是否正確。

在samples文件架中找個例子安裝包,如example-15-puzzle.apk,安裝到手機測試這個拼圖游戲是否正常運行。

?

1.3.2 OpenCV4Android-sdk引入工作空間

(1) 將OpenCV4Android-sdk目錄copy至后面的Android工程的工作空間;

(2)打開eclipse,將OpenCV-SDK引入到工作空間中,如下圖所示:

?

第二部分 開始實戰(zhàn)---使用封裝的OpenCV API開發(fā)android(不通過jni接口)

?

1.1 創(chuàng)建工程

(1) 打開eclipse,創(chuàng)建android應(yīng)用工程API_OPENCV;

(2) 在手機的的SD卡根目錄/sdcard上新建一個目錄andimg ,放入圖像img1.jpg

(3) 在Package Explorer中選擇項目API_OPENCV,單擊右鍵在彈出菜單中選擇Properties,

然后在彈出的Properties窗口中左側(cè)選擇 Android,然后點擊右下方的Add按鈕,選擇OpenCV Library 2.4.4并點擊OK,

操作完成后,會將OpenCV類庫添加到API_OPENCV的Android Dependencies中,如下圖所示:

?

1.2 工程代碼:

?

(1)布局文件:main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"tools:context="${packageName}.${activityClass}" ><Buttonandroid:id="@+id/imagegray"android:layout_width="fill_parent"android:layout_height="wrap_content"android:text="圖像灰度化" /><ImageViewandroid:id="@+id/imageview"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_below="@+id/imagegray"android:layout_centerHorizontal="true"android:layout_marginTop="86dp" /></RelativeLayout>

?

?

(2) 在AndroidManifest.xml文件中加入

?

<!-- 在SDCard中創(chuàng)建與刪除文件權(quán)限 --><uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 往SDCard寫入數(shù)據(jù)權(quán)限 --><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

?

?

如圖所示


?(3) MainActivity.java

?

package com.example.api_opencv;import org.opencv.android.BaseLoaderCallback;import org.opencv.android.LoaderCallbackInterface;import org.opencv.android.OpenCVLoader;import org.opencv.android.Utils;import org.opencv.core.Mat;import org.opencv.imgproc.Imgproc;import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.os.Bundle;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;public class MainActivity extends Activity {private Button btngray;private ImageView imageview;private Bitmap bmp;//OpenCV類庫加載并初始化成功后的回調(diào)函數(shù),在此我們不進(jìn)行任何操作private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {@Overridepublic void onManagerConnected(int status) {switch (status) {case LoaderCallbackInterface.SUCCESS:{} break;default:{super.onManagerConnected(status);} break;}}};@SuppressLint("SdCardPath")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.setTitle("Android API OpenCV");btngray = (Button)findViewById(R.id.imagegray);imageview = (ImageView)this.findViewById(R.id.imageview);bmp=BitmapFactory.decodeFile("/sdcard/andimg/img1.jpg");imageview.setImageBitmap(bmp);btngray.setOnClickListener(new OnClickListener() { @Overridepublic void onClick(View v) {Mat rgbMat = new Mat();Mat grayMat = new Mat();//獲取lena彩色圖像所對應(yīng)的像素數(shù)據(jù) Utils.bitmapToMat(bmp, rgbMat);//將彩色圖像數(shù)據(jù)轉(zhuǎn)換為灰度圖像數(shù)據(jù)并存儲到grayMat中 Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);//創(chuàng)建一個灰度圖像 Bitmap grayBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Config.RGB_565);//將矩陣grayMat轉(zhuǎn)換為灰度圖像 Utils.matToBitmap(grayMat, grayBmp);imageview.setImageBitmap(grayBmp);}});}@Overridepublic void onResume(){//通過OpenCV引擎服務(wù)加載并初始化OpenCV類庫,所謂OpenCV引擎服務(wù)即是//OpenCV_2.4.4_Manager_2.4_*.apk程序包,存在于OpenCV安裝包的apk目錄中super.onResume();OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, this, mOpenCVCallBack);}}

?


1.3 運行結(jié)果

第三部分 開始實戰(zhàn)--- 利用JNI接口通過NDK平臺調(diào)用OpenCV API函數(shù)

  • 新建一個Android工程 NDK_OPENCV(后面將會看到這種命名方式不是很好)

    默認(rèn)使用MainActivitiy,包名com.example.ndk_opencv

    ?

  • 構(gòu)建Android的Java層代碼

    ?

  • (1)布局文件:main.xml

    ?

    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" tools:context="${packageName}.${activityClass}" > <Button android:id="@+id/imagegray" android:layout_width="fill_parent" android:layout_height="wrap_content" android:text="圖像灰度化" /><ImageView android:id="@+id/imageview" android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_below="@+id/imagegray" android:layout_centerHorizontal="true" android:layout_marginTop="86dp" /> </RelativeLayout>

    ?

    ?

    ?

    ?

    (2) 在AndroidManifest.xml文件中加入

    ?

    <!-- 在SDCard中創(chuàng)建與刪除文件權(quán)限 --><uses-permissionandroid:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/><!-- 往SDCard寫入數(shù)據(jù)權(quán)限 --><uses-permissionandroid:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

    ?

    ?

    ?(3) MainActivity.java

    ?

    package com.example.ndk_opencv;import android.annotation.SuppressLint;import android.app.Activity;import android.graphics.Bitmap;import android.graphics.Bitmap.Config;import android.graphics.BitmapFactory;import android.os.Bundle;import android.view.View;import android.view.View.OnClickListener;import android.widget.Button;import android.widget.ImageView;@SuppressLint("SdCardPath")public class MainActivity extends Activity {private Button btngray;private ImageView imageview;private Bitmap bmp;@SuppressLint("SdCardPath")@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);this.setTitle("Android NDK OpenCV");btngray = (Button)findViewById(R.id.imagegray);//btnProc.setOnClickListener(this); imageview = (ImageView)this.findViewById(R.id.imageview);bmp=BitmapFactory.decodeFile("/sdcard/andimg/img1.jpg");imageview.setImageBitmap(bmp);//點擊按鈕,調(diào)用Opencv接口實現(xiàn)SD卡中的圖片灰度化 btngray.setOnClickListener(new OnClickListener() { @Overridepublic void onClick(View v) {bmp=BitmapFactory.decodeFile(stringNDKOPENCV());imageview.setImageBitmap(bmp);}});}//通過jni接口實現(xiàn)的本地函數(shù)public native String stringNDKOPENCV();static {System.loadLibrary("NDK_OPENCV");}}

    ?

    3.2 配置工程的NDK編譯環(huán)境

    ?

    3.2.1在工程上右鍵點擊Android Tools->Add Native Support...,然后給我們的.so文件取個名字,例如: NDK_OPENCV(默認(rèn)為工程名字)

    這時候工程就會多一個jni的文件夾,jni下有Android.mk和NDK_OPENCV.cpp文件。

    3.2.2工程右鍵,點Properties->C/C++ Build的Building Settings中去掉Use default build command,然后輸入${NDKROOT}/ndk-build.cmd

    3.2.3在C/C++ Build中點擊Environment,點Add...添加環(huán)境變量NDKROOT,值為NDK的根目錄E:\project\Android\adt-bundle-windows-x86-20140321\android-ndk-r10

    3.3 編寫NDK_OPENCV.cpp文件

    3.3.1生成.h文件

    在編寫NDK_OPENCV.cpp文件前,需要利用javah這個工具生成相應(yīng)的.h文件,然后根據(jù)這個.h文件編寫相應(yīng)的C/C++代碼。用eclipse編譯該工程,生成相應(yīng)的.class文件,這步必須在下一步之前完成,因為生成.h文件需要用到相應(yīng)的.class文件。暫時不考慮報錯信息。

    進(jìn)入到剛才建立的NDK_OPENCV工程目錄中,在工程目錄下執(zhí)行:?

    Javah -classpath bin\classes -d jni com.example.ndk_opencv.MainActivity

    這里-classpath表示類的路徑;-d jni表示生成的.h文件存放的目錄com.example.ndk_opencv.MainActivity則是完整的類名。現(xiàn)在可以在jni目錄下看到多了一個.h文件:com_example_ndk_opencv_MainActivity.h;

    打開后,可以看到.h的內(nèi)容:

    /* DO NOT EDIT THIS FILE - it is machine generated */#include <jni.h>/* Header for class com_example_ndk_opencv_MainActivity */#ifndef _Included_com_example_ndk_opencv_MainActivity#define _Included_com_example_ndk_opencv_MainActivity#ifdef __cplusplusextern "C" {#endif/** Class: com_example_ndk_opencv_MainActivity* Method: stringNDKOPENCV* Signature: ()Ljava/lang/String;*/JNIEXPORT jstring JNICALL Java_com_example_ndk_1opencv_MainActivity_stringNDKOPENCV(JNIEnv *, jobject);#ifdef __cplusplus}#endif#endif

    ?

    代碼解釋:

  • JNI接口的命名規(guī)范是:Java_ + 調(diào)用該方法的包名(包名的點用_代替) + _ + 調(diào)用該接口的類名 + _ + 方法名。函數(shù)名比較長但是完全按照:java_pacakege_class_mathod 形式來命名。也就是說:MainActivity.java中stringNDKOPENCV () 方法對應(yīng)于 C/C++中的 Java_com_example_ndk_1opencv_MainActivity_stringNDKOPENCV () 方法。
  • 對于實例方法, JNIEXPORT 和 JNICALL 是jni的宏,在android的jni中不需要,當(dāng)然寫上去也不會有錯。注意下其中的注釋:Signature: ()Ljava/lang/String表示函數(shù)的參數(shù)為空,這里為空是指除了JNIEnv *, jobject 這兩個參數(shù)之外沒有其他參數(shù),JNIEnv*, jobject是所有jni函數(shù)必有的兩個參數(shù),分別表示jni環(huán)境和對應(yīng)的java類(或?qū)ο?#xff09;本身,Ljava/lang/String表示函數(shù)的返回值是java的String對象。
  • ndk_1opencv 代碼中的紅色標(biāo)記處多了個1,這個1應(yīng)該表示ndk_opencv為一個整體而非繼承結(jié)構(gòu),因此不建議包名出現(xiàn)空格,以免出錯。
  • 3.3.2 編寫NDK_OPENCV.cpp

    #include <jni.h>#include <string.h>#include <opencv2/core/core.hpp>#include <opencv2/features2d/features2d.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include <opencv2/calib3d/calib3d.hpp>#include <opencv2/imgproc/imgproc_c.h>extern "C" jstringJava_com_example_ndk_1opencv_MainActivity_stringNDKOPENCV( JNIEnv* env,jobject thiz ){//return env->NewStringUTF("/sdcard/andimg/img2.jpg");const char* file="/sdcard/andimg/img1.jpg";IplImage* object = cvLoadImage(file,CV_LOAD_IMAGE_GRAYSCALE);std::string filePath="/sdcard/andimg/img1_result.jpg";jstring filePath1=env->NewStringUTF(filePath.c_str());const char * resultpath=env->GetStringUTFChars(filePath1, 0);cvSaveImage(resultpath,object);//env->ReleaseStringUTFChars(path, file); env->ReleaseStringUTFChars(filePath1, resultpath);return filePath1;}

    ?

    代碼解釋:這段代碼首先讀取了SD卡中的一張圖像,接著調(diào)用env->GetStringUTFChars,以灰度形式讀取圖像并保存在SD卡中,最后返回灰度圖像的路徑。

    3.4利用NDK平臺編譯C++語言函數(shù)成.so文件

    3.4.1首先需要編寫Android.mk文件

    LOCAL_PATH := $(call my-dir)

    include$(CLEAR_VARS)

    # OpenCV

    OPENCV_CAMERA_MODULES:=on

    OPENCV_INSTALL_MODULES:=on

    OPENCV_LIB_TYPE:=STATIC

    include E:\project\JavaWork\JavaExistWork\sdk\native\jni\OpenCV.mk

    LOCAL_MODULE := NDK_OPENCV

    LOCAL_SRC_FILES := NDK_OPENCV.cpp

    include$(BUILD_SHARED_LIBRARY)

    ?

    3.4.2同時建立Application.mk文件

    APP_STL := gnustl_static

    APP_CPPFLAGS := -frtti -fexceptions

    APP_ABI := armeabi-v7a

    APP_PLATFORM := android-9

    ?

    4測試運行

    ????如果在Eclipse下面打開NDK_OPEC.cpp文件會出現(xiàn)很多錯誤,需要將錯誤刪除掉,否則無法編譯。

    "Eclipse可能報一堆的錯誤提示 由于eclipse的語法檢查,當(dāng)你打開一個源碼,尤其是引入外面開發(fā)完成的項目,因為源碼不是在工程中管理的,大部分情況會報一堆的錯誤提示,而你是明 確這些問題實際上是不存在的,那么就可以這樣子做了,設(shè)置項目屬性,把eclipse多管的這些閑事給免了它的職,如下圖,保存后,你會發(fā)現(xiàn)你的 problems窗口下非常清爽了:"

    解決方法之一:需要將錯誤刪除掉,否則無法編譯。

    解決方法之二:打開工程屬性,選擇C/C++ General 中的Code Analysis ,接著選擇Useproject setting 去掉Syntax and Semantic……,這是Eclipse在檢測一些不符合java中的符號報錯,其實代碼沒有錯的。

    ?

    ?

    運行結(jié)果

    轉(zhuǎn)載于:https://www.cnblogs.com/adong7639/p/3925347.html

    總結(jié)

    以上是生活随笔為你收集整理的WINDOWS系统Eclipse+NDK+Android + OpenCv的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。