Android studio 3.0配置OpenCV初探

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

前言

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

简介

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

准备条件

NDK环境搭建

   首先,在Android Studio中打开File->setting->Android SDK->SDK Tools
选择CMake和NDK然后点击Apply等待下载完成即可。
img_2a5e60e8fa9ec533c9643ae4d2decaaf.png
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完成创建,如下图所示。
    
img_6d11f81c643f7b3c30de25dfdd8bc57c.png
Android Studio创建工程.png
  • 然后

       导入OpenCV中的Java库,这个库是OpenCV-android-sdk --->sdk--->java,选择java之后直接导入。
    之后点击Android Studio中的Project Structure,或者直接按ctrl+alt+shift+s打开库依赖面板,
    选择moudle Dependency,选择OpenCVLibrary330添加即可,如下图所示。
    
img_2d50fb2d2ca1b67fa0c80fe43628f0a9.png
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>
    
  • 资源文件的效果如下图所示


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


    img_d876a3d4a28ed102ed9a5a995375a503.png
    AS效果图.png

感言

相关文章
|
20天前
|
SQL 人工智能 Dart
Android Studio的插件生态非常丰富
Android Studio的插件生态非常丰富
33 1
|
20天前
|
Ubuntu Linux Android开发
Android Studio支持多种操作系统
Android Studio支持多种操作系统
44 1
|
20天前
|
前端开发 数据处理 Android开发
Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍
本文深入探讨了Flutter前端开发中的调试技巧与工具使用方法,涵盖调试的重要性、基本技巧如打印日志与断点调试、常用调试工具如Android Studio/VS Code调试器和Flutter Inspector的介绍,以及具体操作步骤、常见问题解决、高级调试技巧、团队协作中的调试应用和未来发展趋势,旨在帮助开发者提高调试效率,提升应用质量。
41 8
|
20天前
|
数据可视化 开发工具 Android开发
Android Studio
Android Studio
63 1
|
2月前
|
Ubuntu Linux 编译器
Linux/Ubuntu下使用VS Code配置C/C++项目环境调用OpenCV
通过以上步骤,您已经成功在Ubuntu系统下的VS Code中配置了C/C++项目环境,并能够调用OpenCV库进行开发。请确保每一步都按照您的系统实际情况进行适当调整。
408 3
|
2月前
|
编译器 Android开发
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
配置环境变量,使CMakeLists.txt可直接使用Android NDK工具链编译项目
|
2月前
|
Java Unix Linux
Android Studio中Terminal运行./gradlew clean build提示错误信息
遇到 `./gradlew clean build`命令执行出错时,首先应检查错误信息的具体内容,这通常会指向问题的根源。从权限、环境配置、依赖下载、版本兼容性到项目配置本身,逐一排查并应用相应的解决措施。记住,保持耐心,逐步解决问题,往往复杂问题都是由简单原因引起的。
317 2
|
2月前
|
Java Android开发 Windows
玩转安卓之配置gradle-8.2.1
为安卓开发配置Gradle 8.2.1,包括下载和解压Gradle、配置环境变量、修改配置文件以增加国内镜像,以及在Android Studio中配置Gradle和JDK的过程。
95 0
玩转安卓之配置gradle-8.2.1
|
3月前
|
XML IDE 开发工具
🔧Android Studio高级技巧大公开!效率翻倍,编码不再枯燥无味!🛠️
【9月更文挑战第11天】在软件开发领域,Android Studio凭借其强大的功能成为Android开发者的首选IDE。本文将揭示一些提升开发效率的高级技巧,包括自定义代码模板、重构工具、高级调试技巧及多模块架构。通过对比传统方法,这些技巧不仅能简化编码流程,还能显著提高生产力。例如,自定义模板可一键插入常用代码块;重构工具能智能分析并安全执行代码更改;高级调试技巧如条件断点有助于快速定位问题;多模块架构则提升了大型项目的可维护性和团队协作效率。掌握这些技巧,将使你的开发之旅更加高效与愉悦。
72 5
|
2月前
|
计算机视觉
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解
这篇文章详细介绍了OpenCV库中的图像二值化函数`cv2.threshold`,包括二值化的概念、常见的阈值类型、函数的参数说明以及通过代码实例展示了如何应用该函数进行图像二值化处理,并展示了运行结果。
479 0
Opencv学习笔记(三):图像二值化函数cv2.threshold函数详解