Android配置OpenCV C++开发环境
<p>网上的OpenCV配置环境大部分都不能正常配置成功,不是编译时报找不到so,就是运行找不到so.本文是我试了不少坑才找到的配置方法.其原理是让AndroidStudio自己根据mk文件自动配置.</p><h3 id="1下载opencv">1.下载OpenCV</h3>
<p>先去OpenCV官网下载OpenCV的Android版本.速度慢的可以用迅雷下载.</p>
<p>OpenCV4.5.5</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173539799-901412226.png" alt="" loading="lazy"></p>
<p>下载完成之后解压到文件夹</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173607197-341860655.png" alt="" loading="lazy"></p>
<h3 id="2androidstudio新建c项目">2.AndroidStudio新建C++项目</h3>
<p>新建项目选择nativeC++模板.</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173625169-657736090.png" alt="" loading="lazy"></p>
<p>C++标准选默认就好了</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173634415-292286918.png" alt="" loading="lazy"></p>
<p>创建完成之后如果以前没配置过NDK可能会报错.<br>
<img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173710114-1240846446.png" alt="" loading="lazy"></p>
<p>打开 <code>Project Structue</code><br>
<img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173739341-1646674428.png" alt="" loading="lazy"></p>
<p>切换到 <code>SDK Location</code>标签下,选择一个已安装的NDK即可.</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173757809-768325548.png" alt="" loading="lazy"></p>
<p>如果没有NDK可供选择,需要先下载NDK.打开 <code>SDK Manager</code></p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173814263-24909780.png" alt="" loading="lazy"></p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173833704-1679112855.png" alt="" loading="lazy"></p>
<p>选择一个合适的版本下载就好,建议不要下载最新版本.<br>
<img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415173934456-1512249578.png" alt="" loading="lazy"></p>
<h3 id="3配置opencv开发环境">3.配置OpenCV开发环境</h3>
<p>在配置OpenCV开发环境之前,可以安装运行一下看一下有没有报错,第一次运行会有较长加载so库的时间.</p>
<h4 id="31配置include头文件">3.1配置include头文件</h4>
<p>找到之前解压好的opencv-4.5.5-android-sdk文件夹,复制下面的 <code>OpenCV-android-sdk\sdk\native\jni\include</code>文件夹到 <code>src/main/cpp</code>文件夹下.</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415174000324-173131721.png" alt="" loading="lazy"></p>
<h4 id="32配置cmakeliststxt文件">3.2配置CMakeLists.txt文件</h4>
<p>将以下内容复制替换到 <code>cpp/CMakeLists.txt</code> 注意将里面的opencv路径替换为自己电脑上的路径.注意斜杆</p>
<pre><code>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)
</code></pre>
<h3 id="4验证opencv是否配置成功">4.验证OpenCV是否配置成功</h3>
<h4 id="41验证头文件是否配置成功">4.1验证头文件是否配置成功</h4>
<p>重新build之后打开 <code>native-lib.cpp</code> 导入OpenCV的头文件.如果有提示说明头文件配置成功.</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415174048807-345738215.png" alt="" loading="lazy"></p>
<h4 id="42验证opencv库是否正确链接到">4.2验证OpenCV库是否正确链接到</h4>
<p>打开 <code>native-lib.cpp</code> 找到默认生成的stringFromJNI方法</p>
<pre><code>extern "C" JNIEXPORT jstring JNICALL
Java_komine_demos_opencvdemo_MainActivity_stringFromJNI(JNIEnv* env,jobjectthiz) {
//添加这行声明
cv::Mat mat;
std::string hello = "Hello from C++";
return env->NewStringUTF(hello.c_str());
}
</code></pre>
<p>运行如果没有报错说明OpenCV配置成功</p>
<h4 id="43简单使用opencv进行图片处理">4.3简单使用OpenCV进行图片处理</h4>
<p>首先在 <code>MainActivity</code>中声明一个processImage native方法,新版AndroidStudio再也不需要通过javah去生成头文件了,</p>
<p>直接 <code>Alt + Enter</code>生成native的方法声明,我的AndroidStudio版本是3.6.3,高于3.0的应该都能自动生成.</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415174913131-30348765.png" alt="" loading="lazy"></p>
<p>为了更方便使用OpenCV的类,可以导入cv命名空间</p>
<pre><code>//写在include语句的下方
using namespace cv;
</code></pre>
<p>native实现</p>
<pre><code>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);
}
</code></pre>
<p>布局文件</p>
<pre><code><?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>
</code></pre>
<p>MainActivity.java</p>
<pre><code>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);
}
</code></pre>
<p>效果图</p>
<p><img src="https://img2022.cnblogs.com/blog/2826579/202204/2826579-20220415174307536-1542176301.png" alt="" loading="lazy"></p><br><br>
来源:https://www.cnblogs.com/komine/p/16150349.html
頁:
[1]