发布于2022年11月4日3年前 网上的OpenCV配置环境大部分都不能正常配置成功,不是编译时报找不到so,就是运行找不到so.本文是我试了不少坑才找到的配置方法.其原理是让AndroidStudio自己根据mk文件自动配置. 1.下载OpenCV 先去OpenCV官网下载OpenCV的Android版本.速度慢的可以用迅雷下载. OpenCV4.5.5 下载完成之后解压到文件夹 2.AndroidStudio新建C++项目 新建项目选择nativeC++模板. C++标准选默认就好了 创建完成之后如果以前没配置过NDK可能会报错. 打开 Project Structue 切换到 SDK Location标签下,选择一个已安装的NDK即可. 如果没有NDK可供选择,需要先下载NDK.打开 SDK Manager 选择一个合适的版本下载就好,建议不要下载最新版本. 3.配置OpenCV开发环境 在配置OpenCV开发环境之前,可以安装运行一下看一下有没有报错,第一次运行会有较长加载so库的时间. 3.1配置include头文件 找到之前解压好的opencv-4.5.5-android-sdk文件夹,复制下面的 OpenCV-android-sdk\sdk\native\jni\include文件夹到 src/main/cpp文件夹下. 3.2配置CMakeLists.txt文件 将以下内容复制替换到 cpp/CMakeLists.txt 注意将里面的opencv路径替换为自己电脑上的路径.注意斜杆 cmake_minimum_required(VERSION 3.4.1) # ##################### OpenCV 环境 ############################ #设置OpenCV-android-sdk路径,替换为自己电脑上的路径,注意是双斜杠或者反斜杠 set( OpenCV_DIR D:\\Develop\\OpenCV\\opencv-4.5.5-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 ) #jnigraphics是Android bitmap处理库,如果需要在JNI处理bitmap对象,需要添加引用 target_link_libraries( native-lib ${OpenCV_LIBS} log jnigraphics) 4.验证OpenCV是否配置成功 4.1验证头文件是否配置成功 重新build之后打开 native-lib.cpp 导入OpenCV的头文件.如果有提示说明头文件配置成功. 4.2验证OpenCV库是否正确链接到 打开 native-lib.cpp 找到默认生成的stringFromJNI方法 extern "C" JNIEXPORT jstring JNICALL Java_komine_demos_opencvdemo_MainActivity_stringFromJNI(JNIEnv* env,jobject thiz) { //添加这行声明 cv::Mat mat; std::string hello = "Hello from C++"; return env->NewStringUTF(hello.c_str()); } 运行如果没有报错说明OpenCV配置成功 4.3简单使用OpenCV进行图片处理 首先在 MainActivity中声明一个processImage native方法,新版AndroidStudio再也不需要通过javah去生成头文件了, 直接 Alt + Enter生成native的方法声明,我的AndroidStudio版本是3.6.3,高于3.0的应该都能自动生成. 为了更方便使用OpenCV的类,可以导入cv命名空间 //写在include语句的下方 using namespace cv; native实现 extern "C" JNIEXPORT void JNICALL Java_komine_demos_opencvdemo_MainActivity_processImage(JNIEnv *env, jobject thiz,jstring image_path,jstring outPath) { //将jstring转换为const char* const char* path = env->GetStringUTFChars(image_path,NULL); const char* imageOutPath = env->GetStringUTFChars(outPath,NULL); //读取mat对象 Mat sourceMat = imread(path); //灰度mat Mat grayMat; //将图片转换为灰度图 cvtColor(sourceMat,grayMat,COLOR_BGR2GRAY); //将图片写入到文件 imwrite(imageOutPath,grayMat); } 布局文件 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" tools:context=".MainActivity"> <ImageView android:id="@+id/image" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <Button android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="显示灰度图" android:onClick="loadGrayImage" /> </LinearLayout> MainActivity.java public class MainActivity extends AppCompatActivity { private ImageView mImageView; private String mOutputPath; static { System.loadLibrary("native-lib"); } @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); mImageView = findViewById(R.id.image); //注意读写权限,或者将图片upload到files目录 String sourcePath = Environment.getExternalStorageDirectory() + File.separator + "miku.png"; mOutputPath = Environment.getExternalStorageDirectory() + File.separator + "miku_gray.png"; processImage(sourcePath,mOutputPath); } public void loadGrayImage(View view) { mImageView.setImageBitmap(BitmapFactory.decodeFile(mOutputPath)); } public native void processImage(String imagePath,String outPath); } 效果图
创建帐户或登录后发表意见