美文网首页小技巧Android开发Android开发
Android studio 3.0配置OpenCV初探

Android studio 3.0配置OpenCV初探

作者: Silence潇湘夜雨 | 来源:发表于2018-03-02 17:01 被阅读1112次

    前言

    之前一直想对OpenCV进行学习和使用,一直没有实践。这次痛下决心,一定要搞定。经过两天的折腾,遇到各种bug终于搞定了,希望能帮助到初学者,如果里面有那些写的不对的地方,还希望各位看官指正。

    简介

    • 准备条件
    • Android Studio NDK环境搭建
    • Android Studio OpenCV使用
    • 常见问题

    准备条件

    NDK环境搭建

       首先,在Android Studio中打开File->setting->Android SDK->SDK Tools
    选择CMake和NDK然后点击Apply等待下载完成即可。
    
    Android Studio Ndk配置.png
    • 首先

         OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以
       运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且
       高效——由一系列 C 函数和少量 C++ 类,同时提供了Python、Ruby、
       MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。
       OpenCV用C++语言编写,它的主要接口也是C++语言,但是依然保留了大量的C语言接口。
       该库也有大量的Python、Java and MATLAB/OCTAVE(版本2.5)的接口。
       这些语言的API接口函数可以通过在线文档获得。如今也提供对于C#、Ch、Ruby的支持。
      
    • 其次

          在Android Studio中新建Project,选中Include c++ support,之后一直默认选择,
      在C++版本选中c++11,然后finish完成创建,如下图所示。
      
    Android Studio创建工程.png
    • 然后

         导入OpenCV中的Java库,这个库是OpenCV-android-sdk --->sdk--->java,选择java之后直接导入。
      之后点击Android Studio中的Project Structure,或者直接按ctrl+alt+shift+s打开库依赖面板,
      选择moudle Dependency,选择OpenCVLibrary330添加即可,如下图所示。
      
    Android Studio 依赖项目.png
    • 再次

      在AS中打开CMakeLists.txt设置OpenCV的路径(此路径为你本地的路径)
      # ##################### OpenCV 环境 
      
      #设置OpenCV-android-sdk路径
      set( OpenCV_DIR E:/Source/OpenCV-android-sdk/sdk/native/jni )
      
      find_package(OpenCV REQUIRED )
      if(OpenCV_FOUND)
      include_directories(${OpenCV_INCLUDE_DIRS})
      message(STATUS "OpenCV library status:")
      message(STATUS "    version: ${OpenCV_VERSION}")
      message(STATUS "    libraries: ${OpenCV_LIBS}")
      message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
      else(OpenCV_FOUND)
      message(FATAL_ERROR "OpenCV library not found")
      endif(OpenCV_FOUND)
      

    注意: 上面的set( OpenCV_DIR E:/Source/OpenCV-android-sdk/sdk/native/jni)把此路径换成你本地的路径。

    • 最后

          将OpenCV-android-sdk下面的sdk-->native-->libs下面的文件复制到AS中libs路径下。
       然后在app 的build.gradle的android下添加如下代码:
      
        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)
       }
      
        最后还需要在dependencies添加 
       implementation fileTree(dir: "$buildDir/native-libs", include: 'native-libs.jar')
      

    提示 :到这里OpenCV的环境已经配置完了,下面我们来写一个简单的DEMO验证一下。

    简单DEMO验证

    注意 :本demo只是简单验证,6.0的运行时权限等等没有进行配置。

    • 新建MainActivity

      public class MainActivity extends AppCompatActivity implements 
       View.OnClickListener { 
        //最大
         private double max_size = 1024;
        //回调
         private int PICK_IMAGE_REQUEST = 1;
        //原图、处理后的图片
         private ImageView mImgOriginal, mImgDeals;
        //原始Bitmap、处理后的Bitmap
        private Bitmap mOriginalBitmap,mDealBitmap;
       //选择图片、处理
        private Button mBtnChoose, mBtnDeals;
        @Override
       protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        onLoadOpenCVLibrary();
        initView();
       }
      
      /**
       * 初始化
       */
       private void initView() {
      mImgDeals = findViewById(R.id.img_deals);
      mImgOriginal = findViewById(R.id.img_original);
      mBtnChoose = findViewById(R.id.btn_choose);
      mBtnDeals = findViewById(R.id.btn_deals);
      
      mBtnDeals.setOnClickListener(this);
      mBtnChoose.setOnClickListener(this);
      
       }
      
      
       @Override
      public void onClick(View view) {
      switch (view.getId()) {
          case R.id.btn_choose: {//选择
              selectImage();
              break;
          }
          case R.id.btn_deals: {//处理
              convertGray();
              break;
          }
      }
      }
      
        @Override
       protected void onActivityResult(int requestCode, int resultCode, Intent data) {
      super.onActivityResult(requestCode, resultCode, data);
      if (requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null
              && data.getData() != null) {
          Uri uri = data.getData();
          try {
              Log.e("image-tag", "start to decode selected image now...");
              InputStream input = getContentResolver().openInputStream(uri);
              BitmapFactory.Options options = new BitmapFactory.Options();
              options.inJustDecodeBounds = true;
              BitmapFactory.decodeStream(input, null, options);
              int raw_width = options.outWidth;
              int raw_height = options.outHeight;
              int max = Math.max(raw_width, raw_height);
              int newWidth = raw_width;
              int newHeight = raw_height;
              int inSampleSize = 1;
              if (max > max_size) {
                  newWidth = raw_width / 2;
                  newHeight = raw_height / 2;
                  while ((newWidth / inSampleSize) > max_size || (newHeight / inSampleSize) > max_size) {
                      inSampleSize *= 2;
                  }
              }
      
              options.inSampleSize = inSampleSize;
              options.inJustDecodeBounds = false;
              options.inPreferredConfig = Bitmap.Config.ARGB_8888;
              mOriginalBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri),
                      null, options);
              mDealBitmap = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri),
                      null, options);
              mImgOriginal.setImageBitmap(mOriginalBitmap);
      
          } catch (Exception e) {
              e.printStackTrace();
          }
      }
      
      }
      
      /**
       * OpenCV库静态加载并初始化
       */
       private void onLoadOpenCVLibrary() {
        boolean load = OpenCVLoader.initDebug();
        if (load) {
          Log.e("CV", "Open CV Libraries loaded...");
         }
       }
      
       /**
        * 选择图片
        */
      private void selectImage() {
      Intent intent = new Intent();
      intent.setType("image/*");
      intent.setAction(Intent.ACTION_GET_CONTENT);
      startActivityForResult(Intent.createChooser(intent, "选择图像"), PICK_IMAGE_REQUEST);
       }
      
      /**
       * 转换
       */
       private void convertGray(){
      Mat src = new Mat();
      Mat temp = new Mat();
      Mat dst = new Mat();
      Utils.bitmapToMat(mDealBitmap, src);
      Imgproc.cvtColor(src, temp, Imgproc.COLOR_BGRA2BGR);
      Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
      Utils.matToBitmap(dst, mDealBitmap);
      mImgDeals.setImageBitmap(mDealBitmap);
       }
       }
      
    • 新建资源文件

      <?xml version="1.0" encoding="utf-8"?>
      <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
      android:layout_width="match_parent"
      android:layout_height="match_parent"
      android:orientation="vertical">
      
      <LinearLayout
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:orientation="horizontal">
      
        <Button
            android:id="@+id/btn_choose"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="@string/btn_choose"
            android:textSize="16sp" />
      
        <Button
            android:id="@+id/btn_deals"
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:layout_margin="10dp"
            android:text="@string/btn_deals"
            android:textSize="16sp" />
      
      </LinearLayout>
      
      <ImageView
        android:id="@+id/img_original"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:layout_margin="16dp"
        android:scaleType="fitCenter"
        android:src="@mipmap/ic_launcher" />
      
      <ImageView
        android:id="@+id/img_deals"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:layout_gravity="center"
        android:layout_margin="16dp"
        android:scaleType="fitCenter"
        android:src="@mipmap/ic_launcher" />
      </LinearLayout>
      
    • 资源文件的效果如下图所示


      AS资源文件.png
    • 最终运行的效果如下图所示


      AS效果图.png

    感言

    相关文章

      网友评论

      • lzt橘子:楼主,请问,你这种方式,第一次运行,需要在手机安装OpenCVManager么?
        lzt橘子:@Silence潇湘夜雨 好的。
        Silence潇湘夜雨:@lzt橘子 不需要啊
      • 在覸青春:跑出来了,还是遇到一些坑
        Silence潇湘夜雨:@在覸青春 哪些坑?
      • Wings6:你就说一条咸鱼~~~咸鱼 咸鱼~~
      • 三余无梦生05:Error:(250, 0) The imported target "libcpufeatures" references the file
        <a href="openFile:C:\Users\Administrator\Desktop\native\jni\abi-x86_64\OpenCVModules.cmake">Open File</a>
        为啥我安装你的方式会报这样的错误
        三余无梦生05:@Silence潇湘夜雨 谢谢,我把目录换成不是桌面就可以了。。。。。。
        三余无梦生05:@Silence潇湘夜雨 是桌面,但没有中文哦
        Silence潇湘夜雨:@三余无梦生05 你这是放在桌面上的?有中文没有?

      本文标题:Android studio 3.0配置OpenCV初探

      本文链接:https://www.haomeiwen.com/subject/afjaxftx.html