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)境變量的配置和編譯是成功正確的了。
參考資料
- 《OpenCV Android 開發(fā)實(shí)戰(zhàn)》(賈志剛 著)
- 關(guān)于本書作者的GitHub項(xiàng)目
- 基于作者GitHub維護(hù)的APP