使用AndroidStudio打包OpenCV和C++代码并在安卓上运行

在为服务器部署OpenCV和C++的过程中尝试了很多方法,这里记录一下在AndroidStudio上打包OpenCV和C++的过程。

1.准备开发环境

这里我直接在mac上开发,没有在虚拟机中。
安装AndroidStudio,jdk等,参考:https://blog.csdn.net/wu__di/article/details/78556724
opencv官网下载Android sdk:https://opencv.org/releases.html
cmake安装:https://blog.csdn.net/baimafujinji/article/details/78588488

2.创建工程

创建一个空项目,注意勾选【Include C++ support】,参考:http://www.sohu.com/a/250633784_663371

3.准备文件

现在项目中有一些基础的文件。

其中,jniLibs文件名是固定的,不能自定义,这个是AndroidStudio的默认搜索路径。
将OpenCV-android-sdk/sdk/native/libs下的库文件拷贝到jniLibs目录下,即图上的7个文件夹。AndroidStudio导入其他so文件同理,将对应架构的so文件拷贝到图上文件夹对应的目录中,AS会自动加载这些文件,并在安装时拷贝到APP的库目录下。

native-lib.cpp代码:

#include <jni.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
extern "C" {// 注意这里的函数名格式:Java_各级包名_类名_函数名(参数...),需严格按照这种格式,否则会出错JNIEXPORT jintArray JNICALL Java_com_example2_apple_myapplication_MainActivity_gray(JNIEnv *env,jobject instance,jintArray buf,jint w,jint h) {jint *cbuf = env->GetIntArrayElements(buf, JNI_FALSE );if (cbuf == NULL) { return 0; }Mat imgData(h, w, CV_8UC4, (unsigned char *) cbuf);uchar* ptr = imgData.ptr(0);for(int i = 0; i < w*h; i ++){//计算公式:Y(亮度) = 0.299*R + 0.587*G + 0.114*B// 对于一个int四字节,其彩色值存储方式为:BGRAint grayScale = (int)(ptr[4*i+2]*0.299 + ptr[4*i+1]*0.587 + ptr[4*i+0]*0.114);ptr[4*i+1] = grayScale; ptr[4*i+2] = grayScale;ptr[4*i+0] = grayScale;}int size = w * h;jintArray result = env->NewIntArray(size);env->SetIntArrayRegion(result, 0, size, cbuf);env->ReleaseIntArrayElements(buf, cbuf, 0);return result;}JNIEXPORT jstring JNICALL Java_com_example2_apple_myapplication_MainActivity_stringFromJNI(JNIEnv* env,jobject /* this */) {std::string hello = "Hello from C++";return env->NewStringUTF(hello.c_str());}
}

MainActivity代码:

package com.example2.apple.myapplication;import android.graphics.Bitmap;
import android.graphics.drawable.BitmapDrawable;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.widget.ImageView;public class MainActivity extends AppCompatActivity {// Used to load the 'native-lib' library on application startup.static {System.loadLibrary("native-lib"); System.out.println(System.getProperty("java.library.path"));}@Override protected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable( R.drawable.pic)).getBitmap();int w = bitmap.getWidth(), h = bitmap.getHeight();int[] pix = new int[w * h];bitmap.getPixels(pix, 0, w, 0, 0, w, h);int [] resultPixes=gray(pix,w,h);Bitmap result = Bitmap.createBitmap(w,h, Bitmap.Config.RGB_565);result.setPixels(resultPixes, 0, w, 0, 0,w, h);ImageView img = (ImageView)findViewById(R.id.img2);img.setImageBitmap(result);System.out.println(stringFromJNI());}/** * A native method that is implemented by the 'native-lib' native library, * which is packaged with this application. */public native int[] gray(int[] buf, int w, int h);public native String stringFromJNI();
}

res/layout/activity_main.xml代码:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:tools="http://schemas.android.com/tools"android:id="@+id/activity_main"android:layout_width="match_parent"android:layout_height="match_parent"android:paddingBottom="16dp"android:paddingLeft="16dp"android:paddingRight="16dp"android:paddingTop="16dp"android:orientation="vertical"tools:context="com.example2.apple.myapplication.MainActivity"><TextView android:id="@+id/txt"android:layout_width="wrap_content"android:layout_height="wrap_content"android:text="原图:" /><ImageView android:id="@+id/img"android:layout_width="wrap_content"android:layout_height="wrap_content"android:src="@drawable/pic"/><!--在res/drawable目录下随便放一张图片pic.png并在此加载,图片尺寸最好小些--><TextView android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginTop="10dp"android:text="处理后的图:" /><ImageView android:id="@+id/img2"android:layout_width="wrap_content"android:layout_height="wrap_content"/>
</LinearLayout>

build.gradle代码:

apply plugin: 'com.android.application'android {compileSdkVersion 26 //根据自己的版本设置defaultConfig {applicationId "com.example2.apple.myapplication"minSdkVersion 15 //根据自己的版本设置targetSdkVersion 26 //根据自己的版本设置versionCode 1versionName "1.0"testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"externalNativeBuild {cmake {cppFlags "-std=c++11 -frtti -fexceptions" // 根据情况设置abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a' // 根据情况设置}}}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'}}externalNativeBuild {cmake {path "CMakeLists.txt"}}// 这段代码功能是将工程打包为jar供第三方调用,还需一些其他改动,参考:
// https://blog.csdn.net/qq_24056881/article/details/81017450
// https://blog.csdn.net/xiayiye5/article/details/79639044
//    task makeJar(type: Copy) {//        //删除存在的
//        delete 'build/libs/myjar.jar'
//        //设置拷贝的文件
//        from('build/intermediates/packaged-classes/debug/')
//        //打进jar包后的文件目录
//        into('build/libs/')
//        //将classes.jar放入build/libs/目录下
//        //include ,exclude参数来设置过滤
//        //(我们只关心classes.jar这个文件)
//        include('classes.jar')
//        //重命名
//        rename('classes.jar', 'myjar.jar')
//    }
//    makeJar.dependsOn(build)
}dependencies {implementation fileTree(dir: 'libs', include: ['*.jar'])implementation 'com.android.support:appcompat-v7:26.0.0'implementation 'com.android.support.constraint:constraint-layout:1.0.2'testImplementation 'junit:junit:4.12'
}

CMakeLists代码:

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html #设置OpenCv sdk的路径变量
set(pathToOpenCv /Users/apple/Downloads/OpenCV-android-sdk/)#cmake version 根据自己的情况设置
cmake_minimum_required(VERSION 3.4.1)#支持-std=gnu++11
set(CMAKE_VERBOSE_MAKEFILE on)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=gnu++11")#配置加载native依赖
include_directories(${pathToOpenCv}/sdk/native/jni/include)#动态方式加载
add_library(lib_opencv STATIC IMPORTED )#引入libopencv_java3.so文件
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${PROJECT_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI}/libopencv_java3.so )# 自己的源文件
add_library( # Sets the name of the library.native-lib # Sets the library as a shared library.SHARED# Provides a relative path to your source file(s).src/main/cpp/native-lib.cpp)#查找库
find_library(# Sets the name of the path variable.log-lib# Specifies the name of the NDK library that# you want CMake to locate.log
)#链接库
target_link_libraries(# Specifies the target library.native-lib# Links the target library to the log library# included in the NDK.${log-lib} android -ljnigraphics lib_opencv
)

通过这些设置opencv就可以在Android中运行了,编译运行一下:
我这里在模拟器中运行:

参考资料:
http://www.sohu.com/a/250633784_663371
https://www.cnblogs.com/xiaoxiaoqingyi/p/6676096.html
https://sriraghu.com/2017/03/11/opencv-in-android-an-introduction-part-1/
AndroidStudio项目CMakeLists解析:https://www.cnblogs.com/chenxibobo/p/7678389.html
https://blog.csdn.net/bailsong/article/details/77527773

使用AndroidStudio打包OpenCV和C++代码并在安卓上运行相关推荐

  1. idea将web项目打包成war包并部署到服务器上运行

    idea将web项目打包成war包并部署到服务器上运行 以下是工作案例总结: 1.首先idea配置服务器:tomcat服务器或者jetty服务器均可 2.idea配置环境设置:点击如下图标 接下来如下 ...

  2. linux java的启动内存溢出,java - Java的R代码可在Linux上运行,但不能在Windows中运行 - 堆栈内存溢出...

    我在做什么? 我正在用Java编写一个数据分析程序,该程序依赖R的arulesViz库来挖掘关联规则. 我想要什么? 我的目的是将规则存储在Java中的String变量中,以便以后进行处理. 它是如何 ...

  3. Docker打包 Asp.Net Core应用,在CentOS上运行

    本文主要介绍下运用docker虚拟技术打包Asp.net core应用. Docker作为一个开源的应用容器引擎,近几年得到广泛的应用,使用Docker我们可以轻松实现应用的持续集成部署,一次打包,到 ...

  4. AVOD——Aggregate View Object Detection代码在centos服务器上运行过程

    一.简单介绍 代码地址:https://github.com/kujason/avod 文章地址:https://arxiv.org/pdf/1712.02294 Kitti数据集:http://ww ...

  5. python Win32com代码无法在IIS上运行

    报错代码: app = win32com.client.Dispatch("Excel.Application") 报错: <class 'pywintypes.com_er ...

  6. 好玩C++代码:在电脑上运行了一个C++程序,结果满屏图标!

    今天本教授分享一个可以让格斯莱特林扣十分的C++程序,但老邓头应该不会知道 虽然我是一个魔药课教授,而且魔法部明令禁止使用麻瓜物品--电脑,但我斯教可不是一般人 好了,格兰芬多扣100000分! To ...

  7. YOLO工程代码如何在windows上配置和运行!window上YOLO训练样本的制作

    我使用的YOLO的GPU版本工程是代码链接是:yolo-windows-master,其博客地址是:http://blog.csdn.net/sinat_30071459/article/detail ...

  8. Spark Standalone -- 独立集群模式、Spark 提交任务的两种模式、spark在yarn上运行的环境搭建、自己写的spark代码如何提交到yarn上并运行...

    目录 Spark Standalone -- 独立集群模式 Standalone 架构图 Standalone 的搭建 1.上传.解压.重命名 2.配置环境变量 3.修改配置文件 conf 4.同步到 ...

  9. OpenCV在Android设备上运行深度网络

    OpenCV在Android设备上运行深度网络 在Android设备上运行深度网络 介绍 要求 创建一个空的Android Studio项目 添加OpenCV依赖项 做一个样品 在Android设备上 ...

最新文章

  1. vue-video-player有画面没声音_电视盒子没声音?问题都在这了!
  2. Oracle的join默认为,Oracle中的三种Join方法详解
  3. CV:基于深度学习实现目标检测之GUI界面产品设计并实现图片识别、视频识别、摄像头识别(准确度非常高)
  4. 程序练习:Matlab 实现最小二乘法
  5. Java黑皮书课后题第3章:**3.29(几何:两个圆)编写程序,提示用户输入两个圆的中心坐标和各自的半径值,然后判断圆是在第一个圆内,还是和第一个圆重叠
  6. linux系统中常见的目录,Linux系统中常见的目录名称以及相应内容
  7. 通过Cisco packet Tracer 划分vlan实现不同交换机间pc进行通信
  8. electerm,免费开源的SSH桌面终端,像xshell、termius一样好用
  9. QQ春节游园会被拆开11.2亿个福袋 近一半都被00后给拆了
  10. SQL SERVER 数据库通过连接服务器 调用ORACLE 数据库中的存储过程
  11. JAVA语法——选择排序
  12. caffe中 softmax 函数的前向传播和反向传播
  13. 在线文件管理html,KODExplorer可道云-开源Web在线文件管理系统
  14. python中字符串的处理_Python中字符串的处理技巧分享
  15. threejs修改模型旋转轴
  16. 数据库服务器对硬件配置的五个要求
  17. 解决MainActivity.onCreate(Unknown Source)的混淆错误
  18. 电脑显示器连接主机 没反应 no signal!!
  19. python实现刷问卷星份数(面向对象)
  20. 群论:同构 与 同态 (群同构 与 群同态)

热门文章

  1. AlphaZero称王!DeepMind AI制霸三大棋类游戏
  2. 用Python的turtle画出beautiful四扇风车图
  3. 科学计算机免费,科学计算器3D免费版ScientificCalculator3DFree
  4. CSS radial-gradient() 函数 - 用径向渐变创建图像
  5. WPS表格 - 根据日期,快速计算出是星期几
  6. 天分聪明打一计算机专业术语,有趣的中秋节灯谜
  7. 虚拟机VM安装linux以及网卡配置
  8. 清华计算机研究生和五道口哪个难考6,最难考研的6所大学,考上就是“铁饭碗”,前途不可限量...
  9. Java中的得墨meter耳定律–最少知识原理–实际示例
  10. SE11 创建搜索帮助