• 【Android+OpenCV】Android Studio的安装全过程+在Android Studio中配置OpenCV


    版本:
    Android 3.5.2
    SDK     28.0.2
    opencv  3.4.10
    ndk     r16b
    

    1、安装Android Studio 以及 OpenCV

    1.1 下载安装包:

    (1)去Android Studio中文社区下载android-studio-ide-191.5977832-windows.exe

    (2)去OpenCV官网,下载OpenCV-3.4.10-android-sdk

    (3)去NDK官网下载 android-ndk-r16b-windows-x86_64

    1.2 安装Android Studio

    双击android-studio-ide-191.5977832-windows.exe开始安装,过程如下:
    把两个都勾上,下一步:
    在这里插入图片描述
    改成自己的文件夹,注意路径中务必不能有空格:
    在这里插入图片描述

    直接下一步:
    在这里插入图片描述

    继续下一步:
    在这里插入图片描述
    点击finish,同时开启AS:
    在这里插入图片描述
    启动界面如下:在这里插入图片描述
    弹出如下报错框,正常,点击Cancel取消该框:
    在这里插入图片描述
    选Custom:
    在这里插入图片描述
    勾上,更改SDK位置,点next:
    在这里插入图片描述
    点finish:
    在这里插入图片描述
    出现如下界面,点击Configure按钮:
    在这里插入图片描述
    选择SDK Manager:
    在这里插入图片描述
    我的电脑内存8G,所选的默认虚拟机内存大小2G:
    在这里插入图片描述
    点击finish:
    在这里插入图片描述
    下载好了之后,点finish:
    在这里插入图片描述

    1.3 第一次新建工程项目

    在下面这个界面里,点击第一项 Start a new Android Studio project
    在这里插入图片描述
    滑到最后,选择原生C++模板:在这里插入图片描述

    改名后,选择java模板,next:
    在这里插入图片描述
    修改为C++14,finish:
    在这里插入图片描述
    这里,正在下载gradle,如果网不好,可以叉掉整个界面,等会用离线方式下载gradle。
    在这里插入图片描述

    gradle官网下载gradle-5.4.1-all.zip
    在这里插入图片描述
    下载好后,把压缩包文件gradle-5.4.1-all.zip拷贝到文件夹,删除文件夹中原来的两个半成品文件,最后如图所示:

    在这里插入图片描述

    打开AS:
    将左侧Android模式切换成Project模式,点击右侧小象按钮,开始解压…

    在这里插入图片描述

    此时可以做其他工作:
    File—>Settings—>Appearance & Behavior—>System Settings—>取消勾选Reopen last project on startup(省的每次都打开最近项目,勾掉后,每次打开启动页面,进入选择页面而非项目页面)

    做好了其他工作回来发现报错了:ERROR: Failed to install the following Android SDK packages as some licences have not been accepted.

    解决办法:进入SDK的目录,在目录的地址栏D:Android2SDK oolsin输入cmd,回车打开命令行终端,这里面有个windows批处理文件sdkmanager.bat。运行下面的命令,然后就有一大堆的 license 等着你输入yes,统计了一下,总共要输入8个y:

    sdkmanager --licenses
    

    关闭命令行终端窗口,重新点击AS中的右上角小象图标。开始重新解压缩,解压缩完毕后是下面这样:

    继续报错:ERROR: CMake ‘3.10.2’ was not found in PATH or by cmake.dir property.

    报错原因是没有安装cmake工具,在如下位置安装即可:(File—>Settings)
    在这里插入图片描述
    等着下载结束,安装完成后,点finish。此时重新点小象按钮重新解压,还是会出错。关掉整个AS,重新打开项目,点击小象按钮,一切正常:
    在这里插入图片描述

    1.4 修改项目的NDK版本

    官方给的版本过高r20,需要调整为r16

    File—>Project Structure—>SDK Location—> 选择本地的NDK,然后点击Apply和OK。又开始一轮编译,等完成。
    在这里插入图片描述

    2、使用OpenCV在安卓端处理图片

    参考牛人链接:OpenCV On Android最佳环境配置指南(Android Studio篇)

    2.1 CMake文件

    cmake_minimum_required(VERSION 3.4.1)
    
    # ##################### OpenCV 环境 ############################
    #设置OpenCV-android-sdk路径
    set( OpenCV_DIR D:/AndroidData/opencv-3.4.10-android-sdk/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)
    
    # ###################### 项目原生模块 ###########################
    
    add_library( native-lib
            SHARED
            native-lib.cpp)
    
    target_link_libraries( native-lib
            ${OpenCV_LIBS}
            log
            jnigraphics)
    

    路径的修改参考的是本地OpenCV包中的以下位置:
    在这里插入图片描述

    2.2 activity_main.xml

    <?xml version="1.0" encoding="utf-8"?>
    <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
        android:layout_width="match_parent"
        android:layout_height="match_parent">
    
        <ImageView
            android:id="@+id/imageView"
            android:layout_width="match_parent"
            android:layout_height="match_parent" />
    
        <LinearLayout
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:layout_alignParentBottom="true"
            android:orientation="horizontal">
    
            <Button
                android:id="@+id/show"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="show" />
    
            <Button
                android:id="@+id/process"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:layout_weight="1"
                android:text="process" />
        </LinearLayout>
    
    </RelativeLayout>
    

    2.3 MainActivity.java

    package com.example.opencvdemo;
    
    import androidx.appcompat.app.AppCompatActivity;
    
    import android.graphics.Bitmap;
    import android.graphics.BitmapFactory;
    import android.os.Bundle;
    import android.view.View;
    import android.widget.ImageView;
    import android.widget.TextView;
    
    public class MainActivity extends AppCompatActivity implements View.OnClickListener {
        private ImageView imageView;
    
        static {//加载so库
            System.loadLibrary("native-lib");
        }
    
        @Override
        protected void onCreate(Bundle savedInstanceState) {
            super.onCreate(savedInstanceState);
            setContentView(R.layout.activity_main);
            imageView = findViewById(R.id.imageView);
            findViewById(R.id.show).setOnClickListener(this);
            findViewById(R.id.process).setOnClickListener(this);
        }
    
        @Override
        public void onClick(View v) {
            if (v.getId() == R.id.show) {
                Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat);
                imageView.setImageBitmap(bitmap);
            } else {
                Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.cat);
                getEdge(bitmap);
                imageView.setImageBitmap(bitmap);
            }
        }
    
        //获得Canny边缘
        native void getEdge(Object bitmap);
    }
    

    这几个文件的修改顺序如下,其中,JAVA中,cat是张图片。
    在这里插入图片描述

    2.4 原生层操作

    应用层写好了,现在开始原生层操作:

    2.4.1 生成头文件

    打开Android Studio下方Terminal栏,输入cd appsrcmainjava(所有应用都一样,进入java文件夹即可),回车。然后输入javah -encoding UTF-8 包名.类名,这里输入的是

    javah -encoding UTF-8 com.example.opencv.MainActivity
    

    回车后,将在appsrcmainjava目录下生成一个头文件,如下图所示,之后将该头文件移动到appsrcmaincpp目录下。
    在这里插入图片描述

    2.4.2 native-lib.cpp

    修改native-lib.cpp内容,最终结果如下面代码所示:
    在这里插入图片描述

    #include "com_example_opencvdemo_MainActivity.h"
    #include <android/bitmap.h>
    #include <opencv2/opencv.hpp>
    
    using namespace cv;
    
    extern "C" JNIEXPORT void
    JNICALL Java_com_demo_opencv_NativeActivity_getEdge
            (JNIEnv *env, jobject obj, jobject bitmap) {
        AndroidBitmapInfo info;
        void *pixels;
    
        CV_Assert(AndroidBitmap_getInfo(env, bitmap, &info) >= 0);
        CV_Assert(info.format == ANDROID_BITMAP_FORMAT_RGBA_8888 ||
                  info.format == ANDROID_BITMAP_FORMAT_RGB_565);
        CV_Assert(AndroidBitmap_lockPixels(env, bitmap, &pixels) >= 0);
        CV_Assert(pixels);
        if (info.format == ANDROID_BITMAP_FORMAT_RGBA_8888) {
            Mat temp(info.height, info.width, CV_8UC4, pixels);
            Mat gray;
            cvtColor(temp, gray, COLOR_RGBA2GRAY);
            Canny(gray, gray, 45, 75);
            cvtColor(gray, temp, COLOR_GRAY2RGBA);
        } else {
            Mat temp(info.height, info.width, CV_8UC2, pixels);
            Mat gray;
            cvtColor(temp, gray, COLOR_RGB2GRAY);
            Canny(gray, gray, 45, 75);
            cvtColor(gray, temp, COLOR_GRAY2RGB);
        }
        AndroidBitmap_unlockPixels(env, bitmap);
    }
    

    2.4.3 build.gradle

    修改app下的build.gradle,部分内容需要修改成:

    ...
            externalNativeBuild {
                cmake {
                    cppFlags "-std=c++14 -frtti -fexceptions"
                    arguments "-DANDROID_STL=gnustl_shared"
                }
            }
    ...
    

    完整build.gradle如下:

    apply plugin: 'com.android.application'
    
    android {
        compileSdkVersion 29
        buildToolsVersion "29.0.3"
        defaultConfig {
            applicationId "com.example.opencvdemo"
            minSdkVersion 15
            targetSdkVersion 29
            versionCode 1
            versionName "1.0"
            testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
            externalNativeBuild {
                cmake {
                    cppFlags "-std=c++14 -frtti -fexceptions"
                    arguments "-DANDROID_STL=gnustl_shared"
                }
            }
        }
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
            }
        }
        externalNativeBuild {
            cmake {
                path "src/main/cpp/CMakeLists.txt"
                version "3.10.2"
            }
        }
    }
    
    dependencies {
        implementation fileTree(dir: 'libs', include: ['*.jar'])
        implementation 'androidx.appcompat:appcompat:1.0.2'
        implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
        testImplementation 'junit:junit:4.12'
        androidTestImplementation 'androidx.test.ext:junit:1.1.0'
        androidTestImplementation 'androidx.test.espresso:espresso-core:3.1.1'
    }
    

    点击右上角sync now,重新编译一下。

    2.4.4 CMakeLists.txt(这里仅做展示,不要实践这个步骤)

    编译完成后,为了增加兼容性,在已有的CMakeLists.txt文件中,添加如下语句,增加兼容性:

    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a") #增加兼容性
    

    添加完后的完整CMakeLists.txt文件:

    cmake_minimum_required(VERSION 3.4.1)
    
    # ##################### OpenCV 环境 ############################
    #设置OpenCV-android-sdk路径
    set( OpenCV_DIR D:/AndroidData/opencv-3.4.10-android-sdk/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(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a") #增加兼容性
    # ###################### 项目原生模块 ###########################
    
    add_library( native-lib
            SHARED
            native-lib.cpp)
    
    target_link_libraries( native-lib
            ${OpenCV_LIBS}
            log
            jnigraphics)
    

    有的时候,做的多了未必是好事,比如这里就是,加上这句看似能增加兼容性的代码,反而各种报错,我现在能力不足以解决这个问题,先放在这,后面在解决。

    2.4.5 安装更多组件

    Tools—>SDK Manager—>Appearance & Behavior–>System Settings—>Android SDK—>SDK Tools—>在右下角勾上Show Package Details—>选中:

    Android SDK 28.0.2
    NDK(Side By Side)16.1.4479499
    CMake3.6.4111459
    

    点击Apply,安装完成:
    在这里插入图片描述

    3 结果展示

    运行程序,安装在真机上:点击show,出现喵喵小可爱!
    在这里插入图片描述
    点击处理按钮,出现喵喵小可爱的轮廓:
    在这里插入图片描述
    至此,完成在Android Studio中配置OpenCV的整个过程,置于后续的使用和美化,需要进一步的学习。


    十分有用的b站教程:
    第一集
    第二集

    其余参考文件(都没能帮上啥忙):
    android studio 使用 jni 编译 opencv 完整实例 之 图像边缘检测!从此在andrid中自由使用 图像匹配、识别、检测
    opencv在android平台下的开发【1】-android studio集成opencv-sdk
    Android 接入 OpenCV库的三种方式

  • 相关阅读:
    MySQL DATE_SUB和SUBDATE函数:日期减法运算
    stream将list转化为map
    HackLab-脚本1
    隐写术-2
    Bug-变量
    Bug-you must stop it
    Bug-域名解析
    Bug-web3
    Bug-矛盾
    Bug-web基础$_POST 30
  • 原文地址:https://www.cnblogs.com/dindin1995/p/13059060.html
Copyright © 2020-2023  润新知