【AndroidStudio NDK之使用OpenCV——第一節】使用AndroidStudio搭建OpenCV的NDK開發環境

一、OpenCV介紹

  OpenCV是一個基於開源的跨平臺計算機視覺庫,實現了許多圖像處理和計算機視覺方面的通用算法,是計算機視覺領域最有力的研究工具之一。
  
OpenCV應用領域:人機互動 物體識別 圖像分割 人臉識別 動作識別 運動跟蹤 機器人 運動分析 機器視覺 結構分析 汽車安全駕駛 自動駕駛。。。

二、OpenCV模塊介紹

1.core,核心功能模塊,主要包含如下的內容:
  OpenCV基本數據結構(Basic Structures);
  基本的C語言數據結構和操作(Basic C Structures and Operations);
  動態數據結構(DynamicStructures);
  數組操作相關函數(Operations on Arrays);
  繪圖功能(Drawing Functions);
  XML和YAML語法的支持(XML/YAML Persistence);
  XML和YAML語法的支持的C語言接口(XML/YAML Persistence (C API));
  聚類(Clustering);
  輔助功能與系統函數和宏(Utility and System Functions and Macros);
  與OpenGL的互操作(OpenGL interoperability);
  
2.imgproc,是Image Processing的簡寫。圖像處理模塊,主要包含以下內容:
  線性和非線性的圖像濾波(Image Filtering);
  圖像的幾何變換(Geometric ImageTransformations);
  圖像的其他變換(Miscellaneous Image Transformations);
  直方圖(Histograms);
  結構分析和形狀描述(Structural Analysis and Shape Descriptors);
  運動分析和目標跟蹤(Motion Analysis and Object Tracking);
  特徵檢測(Feature Detection);
  目標檢測(Object Detection);
3. highgui,是High-level GUI and Media I/O的簡寫。高層用戶界面模塊和媒體輸入/輸出模塊,主要包含以下內容:
  用戶界面(User Interface);
  圖片和視頻的讀寫(Reading and Writing Images and Video);
  QT新功能(Qt New Functions);
4. features2d,是2D Features Framework的簡寫。二維特徵框架模塊,主要包含以下內容:
  人臉識別
  VR和AR
  特徵的檢測和描述(Feature Detection and Description);
  特徵檢測器的通用接口(Common Interfaces of Feature Detectors);
  描述符提取器的通用接口(Common Interfaces of Descriptor Extractors);
  描述符匹配器的通用接口(Common Interfaces of Descriptor Matchers);
  通用描述符匹配器通用接口(Common Interfaces of Generic Descriptor Matchers);
  關鍵點和匹配結果的繪製功能(Drawing Function of Keypoints and Matches);
  目標分類(Object Categorization);
5.flann,Clustering and Search in Multi-Dimensional Spaces,多維空間聚類和搜索模塊,主要包含以下內容:

  快速近視最近鄰搜索(Fast Approximate Nearest Neighbor Search);
  聚類(Clustering);
6. video,是Video Analysis的簡寫。視頻分析模塊,主要包含以下內容:
   運動分析和目標跟蹤(Motion Analysis and Object Tracking),視頻相關的,上面提到的是圖片相關的;
7. calib3d ,是Camera Calibration and 3D
  Reconstruction的簡寫。這個模塊主要是相機校準和三維重建相關的內容,包括基本的多視角幾何算法、單個立體攝像頭標定、物體姿態估計、立體相似性算法,3D信息的重建等。

三、OpenCV-android-SDK目錄結構
   apk   = ==》OpenCV manager針對各個架構的cup的manager安裝包
   samples ===》 android平臺下的案例源碼和安裝包(java調用方式的)
   sdk   = ==》 sdk文件夾

四、環境搭建(正文)
  1.搭建AndroidStudio的NDK環境,創建NDK項目;
  2.下載OpenCV(點擊下載)
  3.找到app的build.gradle添加下面兩句話:
蘇青巖
爲了方便大家copy,就特意寫出來了

cmake {
                //-std=c++14 加入C++14支持
                cppFlags "-std=c++14 -frtti -fexceptions"
                //指定要ndk需要兼容的架構
                //注意:如果全部都適配的話,包很大,
                //    這樣兼容那些用戶數極少的cpu就很不划算,
                //    所以可以選擇適配了armeabi-v7a這一個
                //   (我這裏全部配置了apk真的很大 大概有80.7 MB)
 abiFilters 'arm64-v8a','armeabi','armeabi-v7a','mips','mips64','x86','x86_64'
 }
================================================================    
 sourceSets{
        main {
            //jni庫的調用會到這個目錄裏面找so文件
 jniLibs.srcDirs = 
 ['E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/libs']
        }
    }

4.配置CMakeLists.txt文件(直接複製,把路徑修改成自己的就成)

#聲明CMake的版本要求
cmake_minimum_required(VERSION 3.4.1)
#該變量爲真時會創建完整版本的Makefile
set(CMAKE_VERBOSE_MAKEFILE on)
#定義變量ocvlibs使後面的命令可以使用定位具體的庫文件
set(ocvlibs 
"E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/libs")

#調用頭文件的具體路徑
include_directories
(E:/OpenCV/opencv-3.4.3-android-sdk/OpenCV-android-sdk/sdk/native/jni/include)
#生成動態庫openvc-lib
add_library(openvc-lib SHARED IMPORTED )
#設置輸出的名稱,設置動態庫的版本和API版本
set_target_properties(openvc-lib
                      PROPERTIES
                      IMPORTED_LOCATION
					  "${ocvlibs}/${ANDROID_ABI}/openvc-lib.so")
					  
add_library(native-lib SHARED src/main/cpp/native-lib.cpp )
find_library(log-lib log )
target_link_libraries(native-lib openvc-lib android log ${log-lib})

5.檢驗是否成功(如果頭文件導入成功 就表示環境搭建沒啥問題!)
在這裏插入圖片描述
五、案例
  既然環境搭建成功,相信很多人會迫不及待的想要去嘗試一下,這裏給大家做了一個簡單的 “ 圖片灰度處理 ” 案例:

  • 佈局(請自行腦補,謝謝!)
  • MainActivity.java
    static {
        System.loadLibrary("native-lib");
    }  
    public native int[] getGrayImage(int pixels[], int width, int height);
    private ImageView imageView;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        findViewById(R.id.button).setOnClickListener(this);
        imageView = findViewById(R.id.imageView);
        //獲取位圖
        bitmap = 
        BitmapFactory.decodeResource(this.getResources() , R.mipmap.mei);
        imageView.setImageBitmap(bitmap);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.button:
                int w = bitmap.getWidth();
                int h = bitmap.getHeight();
                int pixels[] = new int[w*h];
                int count = 0;
                for(int i = 0 ; i < h ; i++)
                    for (int j = 0 ; j < w ; j++)
                        pixels[count++] = bitmap.getPixel(j , i);
                int p[] = getGrayImage(pixels , w , h);
                imageView.setImageBitmap(
                Bitmap.createBitmap(p , w , h , Bitmap.Config.ARGB_8888));
                break;
        }
    }
  • native-lib.cpp
#include <jni.h> 
#include <opencv2/opencv.hpp>

extern "C" {
   JNIEXPORT jintArray JNICALL
   Java_com_qingyan_opecv_101_MainActivity_getGrayImage
   (JNIEnv *env, jobject instance, jintArray _pixels, jint width, jint height) 
    {
        jint *pixels = env->GetIntArrayElements(_pixels , NULL);
        if(pixels==NULL){
            return NULL;
        }
        cv::Mat imgData(height , width , CV_8UC4 , pixels);

        uchar *ptr = imgData.ptr(0);

        for (int i = 0; i < width * height; i++) {
            int grayScale = (int) (ptr[4 * i + 2] * 0.299 
            + ptr[4 * i + 1] * 0.587  + ptr[4 * i + 0] * 0.114);
            ptr[4 * i + 1] = (uchar) grayScale;
            ptr[4 * i + 2] = (uchar) grayScale;
            ptr[4 * i + 0] = (uchar) grayScale;
        } 
        int size = width * height;
        jintArray result = env->NewIntArray(size);
        env->SetIntArrayRegion(result, 0, size, pixels);
        env->ReleaseIntArrayElements(_pixels, pixels, 0);
        return result; 
    }
}
  • 效果
    蘇青巖
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章