計(jì)算機(jī)視覺 OpenCV Android 環(huán)境搭建 及 實(shí)現(xiàn)測(cè)試案例(沒有你想象的那么麻煩噢)

OpenCV 環(huán)境搭建 及 實(shí)現(xiàn)測(cè)試案例瘾境,沒有你想象的那么麻煩噢喳篇,一篇文章帶你分分鐘搭好環(huán)境跑通實(shí)例迅矛。

OpenCV開發(fā)環(huán)境要求:

  • OpenCV Android SDK 3.3 版本
  • JDK8: 64位
  • Android Studio
  • Android SDK 與 NDK開發(fā)包
筆者本系列使用的環(huán)境
  • Android Studio 3.3
  • Android SDK 28
  • Android NDK r19




1. 軟件以及相關(guān)包的下載和安裝

  • OpenCV 3.3 的下載:直接從官網(wǎng)下載即可:入口在此型宝,點(diǎn)擊前往
    點(diǎn)擊紅框處即可下載壓縮包:


    所下載的OpenCV Android SDK 3.3 是一個(gè)安裝包臭挽,只需要解壓縮到自行想放置的磁盤位置即可捂襟;

  • SDK、NDK的下載以及Android Studio的相關(guān)下載操作和配置欢峰,可以參考筆者昨天剛剛發(fā)布的一篇博文葬荷;



2.環(huán)境搭建

2.1 新建一個(gè)Android項(xiàng)目涨共,可以在模擬器上跑出HelloWorld即可

(常規(guī)操作,這里相信Android開發(fā)的老司機(jī)們都不用筆者多說了吧)宠漩;

2.2導(dǎo)入OpenCV Android SDK 依賴項(xiàng)
  • 在Android Studio中举反,

  • 選擇【File】>>【New...】>>【Import Module...】,

  • 打開對(duì)話框之后扒吁,選擇剛剛解壓縮好的OpenCV Android SDK 目錄中的sdk\java照筑,

  • 模塊名稱會(huì)自動(dòng)顯示出當(dāng)前OpenCV的版本信息,如下如的Module name:
  • 接著點(diǎn)擊【Next】>>【Finish】瘦陈,完成導(dǎo)入;

    這里注意要把OpenCV庫下面的AndroidManifest文件中的這一行代碼注釋掉波俄,因?yàn)樾掳鍭S不允許這種寫法(不刪的話看報(bào)錯(cuò)就知道原因了):
  • 然后再選擇【File】>>【Project Structure...】晨逝,

  • 打開依賴項(xiàng)添加對(duì)話框,

  • 選擇最右側(cè)的【+】按鈕懦铺,把OpenCV庫添加進(jìn)來:
  • 完成添加之后點(diǎn)擊【OK】按鈕捉貌,結(jié)束;

2.3 復(fù)制本地依賴項(xiàng)OpenCV庫文件
  • 在【Projects】目錄結(jié)構(gòu)類型下冬念,選擇app下面的libs趁窃;
  • 然后把OpenCV Android SDK 目錄 native\libs下面的所有文件與文件夾全部復(fù)制到libs中去;
  • 最后刪除所有以 *.a結(jié)尾的文件(最終目錄如下)


2.4 修改Gradle 腳本與編譯
2.4.1 修改OpenCV庫的build.gradle:
apply plugin: 'com.android.library'
android {
    compileSdkVersion 28
    buildToolsVersion "28.0.3"

    defaultConfig {
        minSdkVersion 14
        targetSdkVersion 28
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

dependencies {
}
2.4.2 修改app目錄的build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 28
    defaultConfig {
        applicationId "com.lwp.myhhdaapplication"
        minSdkVersion 21
        targetSdkVersion 28
        versionCode 1
        versionName "1.0"
        testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    implementation fileTree(include: ['*.jar'], dir: 'libs')
    implementation fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
    implementation 'com.android.support:appcompat-v7:28.0.0'
    implementation 'com.android.support.constraint:constraint-layout:1.1.3'
    testImplementation 'junit:junit:4.12'
    androidTestImplementation 'com.android.support.test:runner:1.0.2'
    androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2'
    implementation project(':openCVLibrary330')
}

task nativeLibsToJar(type: Jar, description: 'create a jar archive of the native libs') {
    destinationDir file("$buildDir/native-libs")
    baseName 'native-libs'
    from fileTree(dir: 'libs', include: '**/*.so')
    into 'lib/'
}

tasks.withType(JavaCompile) {
    compileTask -> compileTask.dependsOn(nativeLibsToJar)
}
  • 最后修改完畢后急前,保存醒陆;
  • 【build】>>【clean project】,再【rebuild project】就完成了整個(gè)環(huán)境變量的配置與編譯裆针;


3. 實(shí)現(xiàn)測(cè)試案例

  • 首先刨摩,寫好布局(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">

    <Button
        android:id="@+id/process_btn"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="灰度"/>

    <ImageView
        android:id="@+id/sample_img"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:scaleType="fitCenter"
        android:src="@drawable/lena"
        android:layout_centerInParent="true"/>

</RelativeLayout>
  • 接著是MainActivity.java,編寫業(yè)務(wù)邏輯(大概功能見代碼中注釋):
package com.lwp.myhhdaapplication;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.Toast;

import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;

public class MainActivity extends AppCompatActivity implements View.OnClickListener{

    private String CV_TAG = "OpenCV";
    private Button processBtn;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        iniLoadOpenCV();//加載OpenCV的本地庫
        processBtn = (Button) findViewById(R.id.process_btn);//實(shí)例化按鈕并添加事件響應(yīng)
        processBtn.setOnClickListener(this);
    }

    //加載OpenCV的本地庫
    private void iniLoadOpenCV(){
        boolean success = OpenCVLoader.initDebug();
        if(success){
            Log.i(CV_TAG,"OpenCV Libraries loaded...");
        }else{
            Toast.makeText(this.getApplicationContext(), "WARNING: Could not load OpenCV Libraries!", Toast.LENGTH_LONG).show();
        }
    }

    //實(shí)現(xiàn)事件響應(yīng)
    @Override
    public void onClick(View v) {
        Bitmap bitmap = BitmapFactory.decodeResource(this.getResources(), R.drawable.lena);
        Mat src = new Mat();
        Mat dst = new Mat();
        Utils.bitmapToMat(bitmap, src);
        Imgproc.cvtColor(src,dst,Imgproc.COLOR_BGRA2GRAY);
        Utils.matToBitmap(dst,bitmap);
        ImageView iv = (ImageView)this.findViewById(R.id.sample_img);
        iv.setImageBitmap(bitmap);
        src.release();
        dst.release();
    }
}

  • 最后世吨,運(yùn)行程序澡刹,效果如圖:
  • 點(diǎn)擊灰度按鈕,圖片切換成灰度顯示:
  • 測(cè)試完成耘婚,如果可以完成至此罢浇,就可以驗(yàn)證到環(huán)境變量的配置和編譯是成功正確的了。


參考資料
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沐祷,一起剝皮案震驚了整個(gè)濱河市嚷闭,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌戈轿,老刑警劉巖凌受,帶你破解...
    沈念sama閱讀 219,270評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異思杯,居然都是意外死亡胜蛉,警方通過查閱死者的電腦和手機(jī)挠进,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,489評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來誊册,“玉大人领突,你說我怎么就攤上這事“盖樱” “怎么了君旦?”我有些...
    開封第一講書人閱讀 165,630評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)嘲碱。 經(jīng)常有香客問我金砍,道長(zhǎng),這世上最難降的妖魔是什么麦锯? 我笑而不...
    開封第一講書人閱讀 58,906評(píng)論 1 295
  • 正文 為了忘掉前任恕稠,我火速辦了婚禮,結(jié)果婚禮上扶欣,老公的妹妹穿的比我還像新娘鹅巍。我一直安慰自己,他們只是感情好料祠,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,928評(píng)論 6 392
  • 文/花漫 我一把揭開白布骆捧。 她就那樣靜靜地躺著,像睡著了一般髓绽。 火紅的嫁衣襯著肌膚如雪敛苇。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,718評(píng)論 1 305
  • 那天梧宫,我揣著相機(jī)與錄音接谨,去河邊找鬼。 笑死塘匣,一個(gè)胖子當(dāng)著我的面吹牛脓豪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播忌卤,決...
    沈念sama閱讀 40,442評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼扫夜,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了驰徊?” 一聲冷哼從身側(cè)響起笤闯,我...
    開封第一講書人閱讀 39,345評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎棍厂,沒想到半個(gè)月后颗味,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,802評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡牺弹,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,984評(píng)論 3 337
  • 正文 我和宋清朗相戀三年浦马,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了时呀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,117評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡晶默,死狀恐怖谨娜,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情磺陡,我是刑警寧澤趴梢,帶...
    沈念sama閱讀 35,810評(píng)論 5 346
  • 正文 年R本政府宣布,位于F島的核電站币他,受9級(jí)特大地震影響坞靶,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蝴悉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,462評(píng)論 3 331
  • 文/蒙蒙 一滩愁、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧辫封,春花似錦、人聲如沸廉丽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,011評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽正压。三九已至欣福,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間焦履,已是汗流浹背拓劝。 一陣腳步聲響...
    開封第一講書人閱讀 33,139評(píng)論 1 272
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留嘉裤,地道東北人郑临。 一個(gè)月前我還...
    沈念sama閱讀 48,377評(píng)論 3 373
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像屑宠,于是被迫代替她去往敵國和親厢洞。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,060評(píng)論 2 355

推薦閱讀更多精彩內(nèi)容