专栏首页贾志刚-OpenCV学堂Android NDK层编译OpenCV代码开发详解

Android NDK层编译OpenCV代码开发详解

Android NDK层编译OpenCV代码开发详解

使用Android NDK开发编译OpenCV C++代码,这个在OpenCV4Android开发中会经常遇到的要求,因为OpenCV4Android SDK多数Java代码都是基于JNI调用,如果对于实时性与应用要求比较高的场合来说,多次频繁调用JNI层本身就会导致很大的资源开销,这个时候就需要将全部的处理封装在C++层,在C++中调用OpenCV相关API函数,同时通过在JNI层面定义本地方法,力争做到每次处理图像,只调用JNI一次,这样就会达到比较高的运行速度与好的用户体验。下面我们就从OpenCV4Android SDK与Android NDK开发环境搭建,OpenCV C++程序实现,编译完成与运行各个环节介绍如何在Android NDK层面编译OpenCV C++代码实现JNI调用。

一:环境搭建

首先下载Android Studio与Android SDK,在Android Studio中创建一个新项目,然后参照【OpenCV学堂】之前的文章《OpenCv3.2集成Android Studio开发配置》完成OpenCV4Android开发环境搭建即可。

二:JNI接口定义

在MainActivity中添加一个native本地方法即可

public native void convertGray(long srcAddress, long dstAddress);

三:OpenCV C++代码实现

然后在app/src下面新建一个目录jni,然后创建一个cpp源文件,把下面的代码copy到其中保存

#include<jni.h>

#include<opencv2/opencv.hpp>

#include <iostream>

#include<vector>

#include <android/log.h>


#define  LOG_TAG    "MYOPENCV_TEST"


#define  LOGE(...)  __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)

#define  LOGW(...)  __android_log_print(ANDROID_LOG_WARN,LOG_TAG,__VA_ARGS__)

#define  LOGD(...)  __android_log_print(ANDROID_LOG_DEBUG,LOG_TAG,__VA_ARGS__)

#define  LOGI(...)  __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)


using namespace cv;

using namespace std;


extern"C" {

    JNIEXPORT void JNICALL Java_com_example_zhigang_myapplication_MainActivity_convertGray(JNIEnv* env, jobject, jlong srcAddress, jlong dstAddress)

    {

        Mat& src = *(Mat*)srcAddress;

        Mat& dst = *(Mat*)dstAddress;

        cvtColor(src, dst, COLOR_BGR2GRAY);

        LOGD( "Method Description: %s", "convert to gray image..." );

    }

}

其中com.example.zhigang.myapplication.MainActivity表示当前MainActivity完整的包路径。定义的JNI方法为convertGray,两个参数分别是源图像的地址与输出的灰度图像的地址,实现的功能是把彩色图像转换为灰度图像。

四:编译运行

上述代码要想完整的编译与运行,需要创建两个文件Android.mk与Application.mk文件,然后把下面的内容copy到Android.mk中去:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

OPENCV_CAMERA_MODULES:=on

OPENCV_INSTALL_MODULES:=on

include D:/opencv-3.3/opencv/android/install/sdk/native/jni/OpenCV.mk

LOCAL_MODULE := gray_converter

LOCAL_SRC_FILES := gray_mat.cpp

LOCAL_LDLIBS += -llog -ldl

include $(BUILD_SHARED_LIBRARY)

其中include的路径是你OpenCV4Android SDK实际所在的路径,然后把下面内容copy到Application.mk中去:

APP_STL := gnustl_static

APP_CPPFLAGS := -frtti -fexceptions

APP_ABI := armeabi-v7a

APP_PLATFORM := android-14

然后对当前项目添加NDK支持,打开cmd,切换到src/jni目录,然后运行下面的命令行: /ndk-build 即可完成编译,生成的so文件copy到app/libs中去即可,然后就可以在MainActivity的onCreate方法中通过如下代码加载库文件, System.loadLibrary("gray_converter"); 然后就可以参考上面提到文章调用完成代码演示即可。代码如下:

private void convertGray() {

    Mat src = new Mat();

    Mat temp = new Mat();

    Mat dst = new Mat();

    Bitmap image = BitmapFactory.decodeResource(this.getResources(), R.drawable.lena);

    Utils.bitmapToMat(image, src);

    Imgproc.cvtColor(src, temp, Imgproc.COLOR_RGBA2BGR);

    Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));

    //Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);

    convertGray(temp.getNativeObjAddr(), dst.getNativeObjAddr());

    Utils.matToBitmap(dst, image);

    ImageView imageView = (ImageView)findViewById(R.id.image_lena);

    imageView.setImageBitmap(image);


    // release memory

    src.release();

    temp.release();

    dst.release();

}

最终运行结果:

本文分享自微信公众号 - OpenCV学堂(CVSCHOOL),作者:gloomyfish

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2017-12-27

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • OpenCV框架介绍

    概述 OpenCV是一个开放源代码的计算机视觉应用平台,由英特尔公司研发中心俄罗斯团队发起该项目,开源BSD证书,OpenCV的目标是实现实时计算机视觉,,是一...

    OpenCV学堂
  • OpenCV3.2集成Android Studio2.2开发配置

    主要知识点 OpenCV4Android3.2 SDK介绍与下载 AS2.2与OpenCV3.2集成 程序演示与代码 AS集成OpenCV3.2配置常见错误 O...

    OpenCV学堂
  • OpenCV4.4 CUDA编译与加速全解析

    OpenCV4.4中关于CUDA加速的内容主要有两个部分,第一部分是之前OpenCV支持的图像处理与对象检测传统算法的CUDA加速;第二部分是OpenCV4.2...

    OpenCV学堂
  • 数据结构——动手实战双向链表

    在之前介绍SkipList的文章当中,有一些同学反馈说由于对链表缺少认知以及了解,所以直接啃算法有些过于困难。加上之前的文章当中介绍过了栈,所以这次继续线性表这...

    TechFlow-承志
  • RESTful源码笔记之RESTful Framework的基本组件

    开发我们的Web API的第一件事是为我们的Web API提供一种将代码片段实例序列化和反序列化为诸如json之类的表示形式的方式。我们可以通过声明与Djang...

    Jetpropelledsnake21
  • rest_framework框架的基本组件

    阿强Wwlt
  • [随缘一题]合并两个排序链表

    那么其实可以比较两个链表当前节点的值,哪个值小,就把它连接在新链表的后面,并将这个链表的当前指针后移一位.知道某一个链表为空,将另一个链表的所有值链接在后面即可...

    呼延十
  • Django-debug-toolbar(调试使用)

    django-debug-toolbar 是一组可配置的面板,可显示有关当前请求/响应的各种调试信息,并在单击时显示有关面板内容的更多详细信息。

    小小咸鱼YwY
  • 分享一些HTML5的模板

    前几天看到一个HTML5 UP的网站,发现国内许多网站都用的他的模板做的首页,的确非常适合,高端大气上档次。

    timhbw
  • 【 SPA大赛 】数据特征处理技巧

    作为萌新,很荣幸能参加到第一届腾讯社交算法大赛,我们的队名是“竟然有这种操作”,在这里我希望和大家分享一些比赛过程中leakage和trick处理的技巧。

    李宗阳

扫码关注云+社区

领取腾讯云代金券