【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; 
    }
}
  • 效果
    苏青岩
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章