android接入opencv方式

2023-11-12

原网址:https://www.cnblogs.com/xiaoxiaoqingyi/p/6676096.html

Android 接入 OpenCV库的三种方式

       OpenCV是一个基于BSD许可(开源)发行的跨平台计算机视觉库,可以运行在Linux、Windows、Android和Mac OS操作系统上。它轻量级而且高效——由一系列 C 函数和少量 C++ 类构成,同时提供了Python、Ruby、MATLAB等语言的接口,实现了图像处理和计算机视觉方面的很多通用算法。

 

       我们利用它来做一些图片的处理,能大大的优化内存的处理。下面我来说说接下OpenCV 的三种方式:

 

一、接入OpenCV 的Java SDK 包,这样你可以直接在Java调用OpenCV 的大部分方法。第一种方式适用于对Opencv c++ 不熟悉的童鞋,不需要直接调用C++方案, 因为SDK 已经用JNI 全部封装好了。假设你已经安装好JDK、AndroidStudio与NDK环境。

         先到官网http://opencv.org/releases.html ,下载Android 包,如:opencv-3.2.0-android-sdk.zip。

sdk 目录提供了Android的API与Java 库

sdk/java 目录包含了一个 Eclipse 项目,该项目提供 OpenCV 的Java API,且可以导入到开发环境里。

sdk/native 目录包含了OpenCV C++ 头文件(用于JNI),与Android的 .so动态库 .a静态库。

sdk/etc 目录包含了Haar 与 LBP cascades 级联。

apk  目录包含了用户安装在指定的Android设备的安装文件,该文件使opencv 库可以管理opencv API

 

首先: File > New > New Module

 

然后:选择Import Eclipse ADT Project

 

把sdk/java 下的项目导入到项目里,然后把这个modules 添加到 app modules里,

直接在 app 目录下build.gradle 文件里dependencies 大括号下添加:

compile project(':openCVLibrary')

 

接着在 app/src/main 目录下 创建一个jniLibs 目录,然后把sdk/native/libs 下所有文件 拷贝到jniLibs下,编译,运行。

 

如果导入后,出现一些android 自带的类识别不了,那就是因为编译的SDK版本出错了。

打开 刚导入 的模块下 build.gradle 文件,把 compileSdkVersion 与 targetSdkVersion修改成你最新的SDK版本,如:

 

复制代码

apply plugin: 'com.android.library'

android {
    compileSdkVersion 25
    buildToolsVersion "25.0.0"

    defaultConfig {
        minSdkVersion 15
        targetSdkVersion 25
    }

    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt'
        }
    }
}

复制代码

运行,则成功了,我发现似乎不需要再安装额外的 opencv 的apk 了。

下面链接是我添加成功的例子: 

https://github.com/xiaoxiaoqingyi/NDKDemos     OpenCV_java 项目

 

二、使用opencv sdk 提供的 C++ 头文件与 .so动态库 与 .a静态库,自己封装jni,这样使用的效率会比第一种方法高一些, 且可以100%使用opencv 的接口。下面看一下安装的方式:

 

      用AndroidStudio 创建一个项目,然后在 Java 类里创建一个native 方法,

再在app/src/main 下创建 jni,然后创建 cpp 文件对于 native 方法。

以上是一个简单的jni 方法,你可以查看我以前的 文章: http://www.cnblogs.com/xiaoxiaoqingyi/p/6524165.html

在基本的jni 跑通下,我们把 opencv 库加入项目里,首先:

 

1、把 sdk/native 目录 拷贝到 项目的 jni 目录下,

 

然后就是配置 Android.mk文件:

复制代码

LOCAL_PATH:=$(call my-dir)

include $(CLEAR_VARS)
OpenCV_INSTALL_MODULES := on
OpenCV_CAMERA_MODULES := off
OPENCV_LIB_TYPE :=STATIC

ifeq ("$(wildcard $(OPENCV_MK_PATH))","")
include $(LOCAL_PATH)/native/jni/OpenCV.mk
else
include $(OPENCV_MK_PATH)
endif
LOCAL_MODULE := OpenCV
LOCAL_SRC_FILES := com_magicing_eigenndk_NDKUtils.cpp
LOCAL_LDLIBS +=  -lm -llog
include $(BUILD_SHARED_LIBRARY)

复制代码

 

接着配置 Application.mk 文件:

APP_STL := gnustl_static
APP_CPPFLAGS := -frtti -fexceptions
APP_PLATFORM := android-9

 

最后在 cpp 文件调用 opencv 的方法, 首先导入 #include <opencv2/opencv.hpp> 如:

复制代码

#include <jni.h>
#include <string>
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#include <opencv2/opencv.hpp>

using namespace cv;

extern "C"

  JNIEXPORT jintArray JNICALL Java_com_magicing_eigenndk_NDKUtils_gray(
          JNIEnv *env, jclass obj, jintArray buf, int w, int h) {

      jint *cbuf;
      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四字节,其彩色值存储方式为:BGRA
          int 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;
  }

复制代码

 

然后在 activity 页面里显示处理过的图片,如下:

复制代码

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        NDKUtils ndk = new NDKUtils();

        Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
                R.mipmap.pic_test)).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=ndk.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);

    }

}

复制代码

运行成功后:

 

我编译成功的项目链接:

https://github.com/xiaoxiaoqingyi/NDKDemos   (OpenCV_native项目)

官网参考资料:

http://docs.opencv.org/2.4/doc/tutorials/introduction/android_binary_package/dev_with_OCV_on_Android.html#native-c

 

三、通过opencv 的源码,重新编译成 Android sdk 库,这样的好处是能获取到最新的功能,缺点是编译有点困难(对于不懂C++/C 的童鞋),且新的代码或许会存在不兼容与错误。

 

http://code.opencv.org/projects/opencv/wiki/Building_OpenCV4Android_from_trunk

     以上的链接是官网推荐的编译过程,我也尝试过编译成功,如果在windows 下安装Cygwin,然后来编译是通过不了的,需要重新安装cmake、shell 以及其它的软件,编译的过程确实复杂很多。

     我是在MAC下编译的,只需安装 cmake软件,当然也要有NDK的环境。大概的步骤:

https://github.com/opencv/opencv 下载opencv 源码包

 

1、在mac 下安装好 cmake 软件,

2、配置NDK环境变量, 参考百度:http://jingyan.baidu.com/article/d2b1d1029c1ea65c7e37d4c9.html

3、build_android_arm/install 目录下 得到编译好的jni 目录。

 

     如果你想编译 opencv_contrib 也就是 opencv extra库的话,你需要把https://github.com/Itseez/opencv_contrib 额外库包也下载下来。我曾经把opencv_contrib包的tracking模块 加入到opencv 核心库,编译到PC的CodeBlocks开发环境就成功了,但是编译成Android的环境就出错了,这个问题我一直没有解决,最后我换用了其它的方法,我把相应的一些资料提供给大家:

 

https://github.com/alexkarargyris/Caffe_OpenCV_Android_App

https://zami0xzami.wordpress.com/2016/03/17/building-opencv-for-android-from-source/

      我参考了上述的资料,在加载opencv 额外库的时候,编译了几次也没能成功,会报cmake 编译出错。我也让C++ 的同事尝试用cmake 帮我编译,也没能成功,也许我们对cmake 了解不够深,据说opencv extra 库是需要收费的,所以Android端不能直接编译进来,但是PC端是成功编译了的。如有编译成功的大神,请多多指教!

分类: NDK 开发笔记

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

android接入opencv方式 的相关文章

  • PLC控制运料小车往返运动

    实验要求 1 实验控制电路应该具有控制回路的总控制 其功能是启动和停止控制电路 它可以使小车停站的位置行程开关处于压合的位置 脱离延迟控制往返时为启动状态 及零压保护电路功能 2 小车沿轨道自动往返运动时 小车在行程内的任何位置时都可以起动
  • c++实现创建一个cocos2d-x的场景类

    文件 http pan baidu com s 1ntlu14H createVSClass cpp 定义控制台应用程序的入口点 include stdafx h include
  • RocketMQ消费者端消息列队六种负载均衡算法分析

    在RocketMQ启动的时候会启动负载均衡线程 过程如下 DefaultMQPullConsumerImpl start mQClientFactory start 上面点进去 gt MQClientInstance start rebal
  • 区间调度1.找到移除区间的最小数量

    求出最多有几个互不相交的区间 则做法是按end升序排序 选择一个结束最早的x 然后把区间中与它冲突的全部删除 别的区间的start要大于这个区间的end 接着重复步骤直到堆中没有区间 不用堆只用数组的话可以用一个for循环遍历整个数组 记录
  • 火猴之arc以及gesturemanager的应用(firemonkey)

    效果 目标 1 向左滑动 环形进度条从0 100 2 向右滑动 环形进度条从100 0 思路 1 放置3个arc组件 rotationangle设置为270 stroke的thickness设为30 2 放置gesturemanager组件
  • [Windows] 在磁盘管理中,脱机选项不可选,无法将磁盘脱机

    1 在磁盘管理中遇到无法脱机磁盘的情况 脱机选项不可选 可能是由于将虚拟内存设置到该磁盘上导致的 2 进入电脑属性 gt 高级系统设置 gt 高级 gt 性能设置 gt 高级 gt 更改 3 取消在该磁盘上设置的虚拟内存 4 再进入磁盘管理
  • Qt 智能指针

    C 11 标准中的提供的智能指针 在 Qt 中也提供了类似的替代功能 并且比 C 11 标准中提供的功能还要强大 所以如果我们使用 Qt 作为基础库 Qt 智能指针包括 QSharedPointer QScopedPointer QScop
  • 【react】js表达式和js语句(代码)的区别

    何为表达式 一定注意区分 js语句 代码 与 js表达式 1 表达式 一个表达式会产生一个值 可以放在任何一个需要值的地方 下面这些都是表达式 1 a 2 a b 3 demo 1 4 arr map 5 function test 2 语
  • Tomcat载入配置

    错误出现原因 未配置环境变量
  • (N1盒子) Openwrt 下 docker 容器访问互联网故障排除

    环境 硬件 N1盒子 Openwrt版本 openwrt flippy 60 o 情况描述 先是跑了个运行php的docker容器 日志里报错信息为 cURL error 7 Failed to connect to 域名 port 端口号
  • 《基于Linux物联网综合项目》常见问题汇总fae

    关于该课程说明 1 本课程目标 通过web浏览器访问服务器 实现登录 注册 数据库操作 远程操控硬件 采集环境信息 远程监控 拍照 图片显示等功能 将单片机 linux html 摄像头 数据库等知识点融入到一个项目中 2 什么群体适合学习
  • 自然语言处理卷积神经网络c 代码,卷积神经网络CNN 在自然语言处理中的应用

    序言 CNN在文本分类中取得了不俗的结果 而运用在这里的卷积可以分为1d 2d甚至是3d的 我们知道 CNN一般用来做图像 图像是可以通过预处理 将每幅照片都处理成一样的size的 也就是height和width具有一样的像素值 然后用一个
  • SPRINGBOOT学习记录

    SPRINGBOOT 1 入门 1 1 springBoot具体流程 1yaml 配置文件 2 自动装配 3集成web框架 4 集成数据库 5分布式开发 Dubbo rpc zookeeper 6 swagger 接口文档 7 任务调度 8
  • 图论--差分约束

    小引入 如果一个系统由n个变量和m个约束条件组成 形成如xi xj lt k ij 1 n 的不等式 则称其为查分约束系统 写成一个矩阵形式的不等式组的话则系数有且仅有一个1和一个 1 解这种不等式组为何会与图论扯上关系呢 在我们求解最短路
  • kindle刷机ttl_[原创]只需USB线对Kindle 3修砖的小白教程

    文章的最后有笔者用的电池测试方法和笔者在网盘上传的文件链接 正式开工 1 运行ATK 把i MX CPU设为iMX35 TO2 Device memory initial设为MDDR Host Setting设成USB 2 连接Kindle
  • WCF系列(五) -- 也谈序列化(下)

    1 DataContractSerializer支持的类型 2 1 1 用 DataContract 属性标记的类型 2 1 2 net 原生类型
  • 在Visual Studio 2017 中编写C#安装NuGet、使用元组特性的详细步骤

    主要是解决一下小白的迷茫 一 安装NuGet管理器 1 打开vs2017 打开 工具 扩展与更新 2 左侧目录点 联机 右上侧搜索栏输入 Nuget 搜索 3 下载NuPack NuGet Packager扩展 一次点击可能会下载不成功 那
  • 04_Qt信号与槽机制

    文章目录 一 信号和槽 1 1 Qt5的书写方式 1 1 1 处理子窗口的信号不带参数 1 1 2 处理子窗口的信号带参数 使用函数指针 1 2 Qt4的书写方式 1 3 Lambda表达式 匿名函数对象 二 自定义信号槽 2 1 信号 2
  • Linux学习之权限

    在学习Linux权限之前 我们先理解一下关于Linux内核与shell外壳之间的关系 shell命令以及运行原理 Linux严格意义上说的是一个操作系统 我们称之为 核心 kernel 但我们一般用户 不能直接使用kernel 而是通过ke
  • 室友打了一把端游,我入门了Vue

    快速入门Vue 多种选择器 class选择器 标签选择器 data数据对象 Vue 指令 设置标签的文本值 textContent 设置标签的innerHtml v html 为元素绑定事件 v on 根据表达式的真假 切换元素的显示和隐藏

随机推荐

  • 【Python基础】matplotlib字体设置看这一篇就够了

    本文示例文件已上传至我的Github仓库https github com CNFeffery DataScienceStudyNotes 1 简介 matplotlib作为数据可视化的利器 被广泛用于数据分析之中 但不太友好的是matplo
  • 全数字锁相环(DPLL)的原理简介以及verilog设计代码

    随着数字电路技术的发展 数字锁相环在调制解调 频率合成 FM 立体声解码 彩色副载波同步 图象处理等各个方面得到了广泛的应用 数字锁相环不仅吸收了数字电路可靠性高 体积小 价格低等优点 还解决了模拟锁相环的直流零点漂移 器件饱和及易受电源和
  • 微信小程序——数据绑定

    在微信小程序中 可以通过以下代码实现数据绑定 在WXML中 使用双大括号 绑定数据 将数据渲染到对应的视图中
  • 【蓝桥杯】 (算法训练篇)K好数

    蓝桥杯 算法训练篇 K好数 问题描述 如果一个自然数N的K进制表示中任意的相邻的两位都不是相邻的数字 那么我们就说这个数是K好数 求L位K进制数中K好数的数目 例如K 4 L 2的时候 所有K好数为11 13 20 22 30 31 33
  • 一个人,仅30天!开发一款3D竞技足球游戏!他究竟经历了些什么?

    今天 晓衡向大家推荐一款Coco Store 优质 3D足球竞技游戏 资源 足球快斗 玩法介绍 游戏为 7V7 足球竞技类玩法 玩家控制本队的一个球员 脚下高亮圆圈显示的是玩家 其他球员和守门员为电脑AI控制 期间可以玩家可以换人 A按钮换
  • pycharm tips pycharm 使用技巧

    你好 这里只是pycharm tips 的翻译内容 任何工具窗口中的Esc键都将焦点移动到编辑器 Shift Esc将焦点移动到编辑器 并隐藏当前 或最后一个活动 工具窗口 F12键将焦点从编辑器移动到最后一个聚焦工具窗口 在编辑器中Ctr
  • Python语言程序设计 第一周习题

    Python语言程序设计 第一周习题 习题1 获得用户输入的一个整数 参考该整数值 打印输出 Hello World 要求 如果输入值是0 直接输出 Hello World 如果输入值大于0 以两个字符一行方式输出 Hello W
  • ESP32使用Arduino发布和订阅MQTT

    该项目展示了如何在ESP32上使用MQTT通信协议来发布消息和订阅主题 举例来说 我们会将BME280传感器的读数发布到Node RED仪表板 并控制ESP32输出 我们将使用Arduino IDE对ESP32进行编程 介绍 在此示例中 有
  • Ubuntu-16.06 + OpenCV-3.3.0 + 一些常见的问题

    前言 2017 11 18 根据实践过程整理出第一版 2018 01 05 更新对 pkgconfig 的说明 今天在跑一个faster rcnn的案例 https pjreddie com darknet yolo 涉及到编译 openC
  • tomcat 虚拟目录和目录浏览设置

    为了方便开发 需要开设置虚拟目录和目录浏览 如果是生产环境就不要开放目录浏览 设置虚拟目录 先建 d site 设置 CATALINA HOME bin conf server conf
  • Android--使用相对布局搭建用户注册界面

  • oracle:any,some,all的区别

    相关例子 SELECT emp empno emp ename emp job emp sal FROM scott emp WHERE sal gt any SELECT sal FROM scott emp WHERE job MANA
  • Spring 过滤器 拦截器 AOP区别

    简介 这几天在回顾Spring的AOP时 对过滤器 拦截器 AOP的关系有点好奇 故记录做以备份 在实现一些公共逻辑的时候 很多功能通过过滤器 拦截器 AOP都能实现 但是不同的方式有不同的效率 具体有什么区别 看下文描述 前后端交互基本逻
  • 使用Java VisualVM监控远程JVM(远程服务器为linux配置)

    我们经常需要对我们的开发的软件做各种测试 软件对系统资源的使用情况更是不可少 目前有多个监控工具 相比JProfiler对系统资源尤其是内存的消耗是非常庞大 JDK1 6开始自带的VisualVM就是不错的监控工具 这个工具就在JAVA H
  • C++ 函数重载(overroad) 覆盖(override) 隐藏(hide) 的区别

    原文转自 http blog chinaunix net u 15921 showart 227111 html 成员函数被重载的特征 1 相同的范围 在同一个类中 2 函数名字相同 3 参数不同 4 virtual 关键字可有可无 覆盖是
  • 点到UI 不会误点到物体

    这几天在做捕鱼达人游戏时发现 当鼠标点击UI时 炮台的子弹也会发射子弹 这样会影响用户体验 然后网上百度了一波 发现在UGUI系统上 EventSystem提供了一些方法 那就是EventSystem current IsPointerOv
  • ZeroMQ入门

    官网 ZeroMQ 简介 ZeroMQ是一个库 不是消息队列也不是消息中间件 介于应用层和传输层之间 按照TCP IP划分 传统的Socket通信模式需要创建连接 销毁连接 选择协议等一些列操作 而ZeroMQ是在Socket封装一层的并行
  • Java使用多线程查询数据

    目录 前言 实例 前言 什么是进程 进程 是操作系统的概念 一个独立运行的程序 就是一个 进程 什么是线程 线程 是由 进程创建 的 一个进程可以创建任意多的线程 每个线程都包含一些代码 线程中的代码会同主进程或者其他线程 同时运行 什么是
  • 排序算法(六)——希尔排序

    基本思想 希尔排序是基于插入排序的 又叫缩小增量排序 在插入排序中 标记符左边的元素是有序的 右边的是没有排过序的 这个算法取出标记符所指向的数据 存入一个临时变量 接着 在左边有序的数组中找到临时变量应该插入的位置 然后将插入位置之后的元
  • android接入opencv方式

    原网址 https www cnblogs com xiaoxiaoqingyi p 6676096 html Android 接入 OpenCV库的三种方式 OpenCV是一个基于BSD许可 开源 发行的跨平台计算机视觉库 可以运行在Li