Window系统Eclipse+NDK+Android+OpenCv开发教程

2024-08-30 05:08

本文主要是介绍Window系统Eclipse+NDK+Android+OpenCv开发教程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

     1.Android NDK环境搭建

      http://jingyan.baidu.com/article/5d6edee22d908799eadeec9f.html
     2.官方文档
     Android.mk与Application.mk如何编写,OpenCV库如何调用
     官方文档链接 官方文档链接
     3.OpenCv测试代码来源
      http://www.verydemo.com/demo_c131_i131095.html
     4 NDK OpenCv测试入门程序(有问题)
      http://blog.csdn.net/pwh0996/article/details/8957764
     5 NDK测试入门程序(有问题)
      http://blog.csdn.net/redoffice/article/details/6654714
         6 出现部分问题的解法
           http://blog.csdn.net/houshunwei/article/details/17217695
           目前Android平台下调用OpenCv库 函数 有两种方式:
            1使用封装的OpenCV API开发android:这种方式调用Java的包中的类实现类似。
            2 利用JNI接口通过NDK平台调用OpenCV API函数(这种方式比较普遍)。
           本文将实现这两种方式的调用。
            第一部分 准备工作:
            1.1 本文所使用的软件版本如下:
            ADT版本:ADT-22.6.3 ,  开发工具 ADT(Android Development Tool),集成了最新的ADT和NDK插件以及Eclipse,还有一个最新版本SDK。解压之后就可以用了,下载地址 http://developer.android.com/tools/sdk/ndk/index.html
            NDK: android-ndk-r10, NDK插件:用于开发Android NDK的插件,ADT版本在20以上,就能安装NDK插件,另外NDK集成了CDT插件,NDK版本在r7以上之后就集成了Cygwin,而且还是十分精简版。下载链接见: http://developer.android.com/tools/sdk/ndk/index.html
          OpenCV:OpenCV-2.4.4-android-sdk, 下载地址 http://opencv.org/downloads.html
           1.2 配置NDK的环境变量
          1.2.1解压NDK压缩包,配置环境变量。
          将解压的地址写入 环境变量 PATH中。在命令提示符下输入ndk-build如果弹出如下的错误,而不是说ndk-build not found,就说明ndk环境已经安装成功了。特别提示一下,搜索引擎中会告诉一些早期的NDK版本的使用,是在命令提示符下输入build/host- setup.sh;但是NDK经过更新,这个文件已经没有了。只需要输入ndk-build就可以了。
             Android NDK: Could not find application  project  directory !   
             Android NDK: Please define the NDK_PROJECT_PATH variable to point to it.                  /home/braincol/workspace/android/android-ndk-r5/build/core/build-local.mk:85: *** Android NDK: Aborting    .  Stop.
          1.2.2 Eclipse配置NDK环境
             打开Eclipse,点Window->Preferences->Android->NDK,设置NDK路径,例如当前的NDK版本是是E:/ android -ndk-r10。

1.3 配置OpenCv

下载 OpenCV-2.4.4-android-sdk解压出来,可以看到文件下有apk文件,doc文档,sample例子程序,以及OpenCV4Android-sdk。

其 中,OpenCV4Android-sdk目录即是我们开发opencv所需要的类库;samples目录中存放着若干opencv应用示例(包括人脸检测等),可为我们进行 android下的opencv开发提供参考;doc目录为opencv类库的使用说明及api文档等;而apk目录则存放着对应于各内核版本的。

1.3.1 安装OpenCV_Manager

OpenCV_2.4.3.2_Manager_2.4应用安装包。此应用用来管理手机设备中的opencv类库,在运行opencv应用之前,必须确保手机中已经安装了OpenCV_2.4.4.4_Manager_2.6_*.apk,否则opencv应用将会因为无法加载opencv类库而无法运行。

可以根据自己的手机类型来安装OpenCV_2.4.4.4_Manager.apk.

通过查询自己的手机CPU信息

adb shell

cat /proc/cpuinfo

我的手机是arm v7 –neon 架构的,Android版本为4.4.4选择第3个,第四个是适用于低版本Android系统的手机。

安装完毕后,可以测试OpenCV_2.4.4.4_Manager.apk.是否正确。

在samples文件架中找个例子安装包,如example-15-puzzle.apk,安装到手机测试这个拼图游戏是否正常运行。

1.3.2 OpenCV4Android-sdk引入工作空间

(1) 将OpenCV4Android-sdk目录copy至后面的Android工程的工作空间;

(2)打开eclipse,将OpenCV-SDK引入到工作空间中,如下图所示:

第二部分 开始实战---使用封装的OpenCV API开发android(不通过jni接口)

2.1 创建工程

        (1) 打开 eclipse ,创建 android 应用工程 API_OPENCV ;

(2) 在手机的的SD卡根目录/sdcard上新建一个目录andimg ,放入图像img1.jpg

        (3) 在 Package Explorer 中选择项目 API_OPENCV ,单击右键在弹出菜单中选择Properties ,然后在弹出的 Properties 窗口中左侧选择 Android ,然后点击右下方的Add 按钮,选择 OpenCV Library 2.4.4 并点击 OK ,操作完成后,会将 OpenCV 类库添加到 API_OPENCV 的 Android Dependencies 中,如下图所示:

2.2 工程代码:

(1) 布局文件: main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

xmlns:tools="http://schemas.android.com/tools"

android:layout_width="match_parent"

android:layout_height="match_parent"

tools:context="${packageName}.${activityClass}" >

<Button

android:id="@+id/imagegray"

android:layout_width="fill_parent"

android:layout_height="wrap_content"

android:text="图像灰度化" />

<ImageView

android:id="@+id/imageview"

android:layout_width="wrap_content"

android:layout_height="wrap_content"

android:layout_below="@+id/imagegray"

android:layout_centerHorizontal="true"

android:layout_marginTop="86dp" />

</RelativeLayout>

(2) 在AndroidManifest.xm l 文件中加入

<!-- 在SDCard中创建与删除文件权限 -->

<uses-permission

android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<!-- 往SDCard写入数据权限 -->

<uses-permission

android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

如图所示

 (3) MainActivity.java

package com.example.api_opencv;

import org.opencv.android.BaseLoaderCallback;

import org.opencv.android.LoaderCallbackInterface;

import org.opencv.android.OpenCVLoader;

import org.opencv.android.Utils;

import org.opencv.core.Mat;

import org.opencv.imgproc.Imgproc;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.BitmapFactory;

import android.os.Bundle;

import android.view.Menu;

import android.view.MenuItem;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

public class MainActivity extends Activity {

         private Button btngray;

     private ImageView imageview;

     private Bitmap bmp;

     //OpenCV类库加载并初始化成功后的回调函数,在此我们不进行任何操作

        private BaseLoaderCallback mOpenCVCallBack = new BaseLoaderCallback(this) {

     @Override

     public void onManagerConnected(int status) {

     switch (status) {

     case LoaderCallbackInterface.SUCCESS:

     {

     } break;

     default:

     {

     super.onManagerConnected(status);

     } break;

     }

     }

     };

        @SuppressLint("SdCardPath")

        @Override

        protected void onCreate(Bundle savedInstanceState) {

            super.onCreate(savedInstanceState);

            setContentView(R.layout.activity_main);

            this.setTitle("Android API OpenCV");

            btngray = (Button)findViewById(R.id.imagegray);

     imageview = (ImageView)this.findViewById(R.id.imageview);

     bmp=BitmapFactory.decodeFile("/sdcard/andimg/img1.jpg");

     imageview.setImageBitmap(bmp);

     btngray.setOnClickListener(new OnClickListener() {    

                @Override

                public void onClick(View v) {

         Mat rgbMat = new Mat();

         Mat grayMat = new Mat();

         //获取lena彩色图像所对应的像素数据

         Utils.bitmapToMat(bmp, rgbMat);

         //将彩色图像数据转换为灰度图像数据并存储到grayMat中

         Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);

         //创建一个灰度图像

         Bitmap grayBmp = Bitmap.createBitmap(bmp.getWidth(), bmp.getHeight(), Config.RGB_565);

         //将矩阵grayMat转换为灰度图像

         Utils.matToBitmap(grayMat, grayBmp);

         imageview.setImageBitmap(grayBmp);

                }

            });

        }

        @Override

     public void onResume()

     {

     //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是

     //OpenCV_2.4.4_Manager_2.4_*.apk程序包,存在于OpenCV安装包的apk目录中

     super.onResume();

     OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_2_4_4, this, mOpenCVCallBack);

     }

}

2.3 运行结果

 

第三部分 开始实战--- 利用JNI接口通过NDK平台调用OpenCV API函数

3.1新建一个Android工程 NDK_OPENCV(后面将会看到这种命名方式不是很好)

默认使用MainActivitiy,包名com.example.ndk_opencv

3.2构建Android的Java层代码

(1) 布局文件: main.xml

  1. <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

  2. xmlns:tools="http://schemas.android.com/tools"

  3. android:layout_width="match_parent"

  4. android:layout_height="match_parent"

  5. tools:context="${packageName}.${activityClass}" >

  6. <Button
  7. android:id="@+id/imagegray"

  8. android:layout_width="fill_parent"

  9. android:layout_height="wrap_content"

  10. android:text="图像灰度化" />

  11. <ImageView
  12. android:id="@+id/imageview"

  13. android:layout_width="wrap_content"

  14. android:layout_height="wrap_content"

  15. android:layout_below="@+id/imagegray"

  16. android:layout_centerHorizontal="true"

  17. android:layout_marginTop="86dp" />

  18. </RelativeLayout>

(2) 在AndroidManifest.xml文件中加入

<!-- 在SDCard中创建与删除文件权限 -->

<uses-permission

android:name="android.permission.MOUNT_UNMOUNT_FILESYSTEMS"/>

<!-- 往SDCard写入数据权限 -->

<uses-permission

android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>

 (3) MainActivity.java

package com.example.ndk_opencv;

import android.annotation.SuppressLint;

import android.app.Activity;

import android.graphics.Bitmap;

import android.graphics.Bitmap.Config;

import android.graphics.BitmapFactory;

import android.os.Bundle;

import android.view.View;

import android.view.View.OnClickListener;

import android.widget.Button;

import android.widget.ImageView;

@SuppressLint("SdCardPath")

public class MainActivity extends Activity {

private Button btngray;

private ImageView imageview;

private Bitmap bmp;

@SuppressLint("SdCardPath")

@Override

protected void onCreate(Bundle savedInstanceState) {

super.onCreate(savedInstanceState);

setContentView(R.layout.activity_main);

this.setTitle("Android NDK OpenCV");

btngray = (Button)findViewById(R.id.imagegray);

//btnProc.setOnClickListener(this);

imageview = (ImageView)this.findViewById(R.id.imageview);

bmp=BitmapFactory.decodeFile("/sdcard/andimg/img1.jpg");

imageview.setImageBitmap(bmp);

//点击按钮,调用Opencv接口实现SD卡中的图片灰度化

btngray.setOnClickListener(new OnClickListener() {

@Override

public void onClick(View v) {

bmp=BitmapFactory.decodeFile(stringNDKOPENCV());

imageview.setImageBitmap(bmp);

}

});

}

//通过jni接口实现的本地函数

public native String stringNDKOPENCV();

static {

System.loadLibrary("NDK_OPENCV");

}

}

3.2 配置工程的NDK编译环境

在工程上右键点击Android Tools->Add Native Support...,然后给我们的.so文件取个名字,例如: NDK_OPENCV(默认为工程名字)

这时候工程就会多一个jni的文件夹,jni下有Android.mk和 NDK_OPENCV .cpp文件。

工程右键,点Properties->C/C++ Build的Building Settings中去掉Use default build command,然后输入${NDKROOT}/ndk-build.cmd

在C/C++ Build中点击Environment,点Add...添加环境变量NDKROOT,值为NDK的根目录E:/project/Android/adt-bundle-windows-x86-20140321/android-ndk-r10

3.3 编写NDK_OPENCV.cpp文件

3.3.1生成.h文件

在编写 NDK_OPENCV .cpp文件前,需要利用javah这个工具生成相应的.h文件,然后根据这个.h文件编写相应的C/C++代码。用eclipse编译该工程,生成相应的.class文件,这步必须在下一步之前完成,因为生成.h文件需要用到相应的.class文件。暂时不考虑报错信息。

进入到刚才建立的 NDK_OPENCV 工程目录中,在工程目录下执行: 

Javah -classpath bin/classes -d jni com.example.ndk_opencv.MainActivity

这里-classpath表示类的路径;-d jni表示生成的.h文件存放的目录com.example.ndk_opencv.MainActivity则是完整的类名。现在可以在jni目录下看到多了一个.h文件:com_example_ndk_opencv_MainActivity.h;

打开后,可以看到.h的内容:

/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class com_example_ndk_opencv_MainActivity */

#ifndef _Included_com_example_ndk_opencv_MainActivity

#define _Included_com_example_ndk_opencv_MainActivity

#ifdef __cplusplus

extern "C" {

#endif

/*

* Class: com_example_ndk_opencv_MainActivity

* Method: stringNDKOPENCV

* Signature: ()Ljava/lang/String;

*/

JNIEXPORT jstring JNICALL Java_com_example_ ndk_1opencv_MainActivity_stringNDKOPENCV

(JNIEnv *, jobject);

#ifdef __cplusplus

}

#endif

#endif

代码解释 :

  1. JNI接口的命名规范是:Java_ + 调用该方法的包名(包名的点用_代替) + _ + 调用该接口的类名 + _ + 方法名。函数名比较长但是完全按照:java_pacakege_class_mathod 形式来命名。也就是说:MainActivity.java中stringNDKOPENCV () 方法对应于 C/C++中的 Java_com_example_ndk_1opencv_MainActivity_stringNDKOPENCV () 方法。
  2. 对于实例方法, JNIEXPORT 和 JNICALL 是jni的宏,在android的jni中不需要,当然写上去也不会有错。注意下其中的注释:Signature: ()Ljava/lang/String表示函数的参数为空,这里为空是指除了JNIEnv *, jobject 这两个参数之外没有其他参数,JNIEnv*, jobject是所有jni函数必有的两个参数,分别表示jni环境和对应的java类(或对象)本身,Ljava/lang/String表示函数的返回值是java的String对象。
  3. ndk_1opencv 代码中的红色标记处多了个1,这个1应该表示ndk_opencv为一个整体而非继承结构,因此不建议包名出现空格,以免出错。

3.3.2 编写 NDK_OPENCV.cpp

#include <jni.h>

#include <string.h>

#include <opencv2/core/core.hpp>

#include <opencv2/features2d/features2d.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

#include <opencv2/calib3d/calib3d.hpp>

#include <opencv2/imgproc/imgproc_c.h>

extern "C" jstring

Java_com_example_ ndk_1opencv _MainActivity_stringNDKOPENCV( JNIEnv* env,

jobject thiz )

{

//return env->NewStringUTF("/sdcard/andimg/img2.jpg");

const char* file="/sdcard/andimg/img1.jpg";

IplImage* object = cvLoadImage(file,CV_LOAD_IMAGE_GRAYSCALE);

std::string filePath="/sdcard/andimg/img1_result.jpg";

jstring filePath1=env->NewStringUTF(filePath.c_str());

const char * resultpath=env->GetStringUTFChars(filePath1, 0);

cvSaveImage(resultpath,object);

//env->ReleaseStringUTFChars(path, file);

env->ReleaseStringUTFChars(filePath1, resultpath);

return filePath1;

}

代码解释:

  1. 这段代码首先读取了SD卡中的一张图像,接着调用env->GetStringUTFChars,以灰度形式读取图像并保存在SD卡中,最后返回灰度图像的路径。
  2. Java_com_example_ ndk_1opencv _MainActivity_stringNDKOPENCV( JNIEnv* env,jobject thiz )是根据.h文件给出的

3.4利用NDK平台编译C++语言函数成.so文件

3.4.1首先需要编写Android.mk文件

LOCAL_PATH : = $(call my-dir)

include $(CLEAR_VARS)

# OpenCV

OPENCV_CAMERA_MODULES: =on

OPENCV_INSTALL_MODULES: =on

OPENCV_LIB_TYPE: =STATIC

include E:/project/JavaWork/JavaExistWork/sdk/native/jni/OpenCV.mk

LOCAL_MODULE : = NDKCPP

LOCAL_SRC_FILES : = NDKCPP.cpp

include $(BUILD_SHARED_LIBRARY)

其中 include E:/project/JavaWork/JavaExistWork/sdk/native/jni/OpenCV.mk 为OpenCV SDK的路径MK文件路径,引入Opencv库

3.4.2同时建立Application.mk文件

APP_STL : = gnustl_static

APP_CPPFLAGS : = -frtti -fexceptions

APP_ABI : = armeabi-v7a

APP_PLATFORM : = android-9

4测试运行

如果在Eclipse下面打开NDK_OPECV文件会出现很多错误,需要将错误删除掉,否则无法编译。

运行结果

 

原文地址:http://www.th7.cn/Program/Android/201408/265565.shtml

这篇关于Window系统Eclipse+NDK+Android+OpenCv开发教程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119884

相关文章

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

不懂推荐算法也能设计推荐系统

本文以商业化应用推荐为例,告诉我们不懂推荐算法的产品,也能从产品侧出发, 设计出一款不错的推荐系统。 相信很多新手产品,看到算法二字,多是懵圈的。 什么排序算法、最短路径等都是相对传统的算法(注:传统是指科班出身的产品都会接触过)。但对于推荐算法,多数产品对着网上搜到的资源,都会无从下手。特别当某些推荐算法 和 “AI”扯上关系后,更是加大了理解的难度。 但,不了解推荐算法,就无法做推荐系

这15个Vue指令,让你的项目开发爽到爆

1. V-Hotkey 仓库地址: github.com/Dafrok/v-ho… Demo: 戳这里 https://dafrok.github.io/v-hotkey 安装: npm install --save v-hotkey 这个指令可以给组件绑定一个或多个快捷键。你想要通过按下 Escape 键后隐藏某个组件,按住 Control 和回车键再显示它吗?小菜一碟: <template

基于人工智能的图像分类系统

目录 引言项目背景环境准备 硬件要求软件安装与配置系统设计 系统架构关键技术代码示例 数据预处理模型训练模型预测应用场景结论 1. 引言 图像分类是计算机视觉中的一个重要任务,目标是自动识别图像中的对象类别。通过卷积神经网络(CNN)等深度学习技术,我们可以构建高效的图像分类系统,广泛应用于自动驾驶、医疗影像诊断、监控分析等领域。本文将介绍如何构建一个基于人工智能的图像分类系统,包括环境

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,

Hadoop企业开发案例调优场景

需求 (1)需求:从1G数据中,统计每个单词出现次数。服务器3台,每台配置4G内存,4核CPU,4线程。 (2)需求分析: 1G / 128m = 8个MapTask;1个ReduceTask;1个mrAppMaster 平均每个节点运行10个 / 3台 ≈ 3个任务(4    3    3) HDFS参数调优 (1)修改:hadoop-env.sh export HDFS_NAMENOD

Makefile简明使用教程

文章目录 规则makefile文件的基本语法:加在命令前的特殊符号:.PHONY伪目标: Makefilev1 直观写法v2 加上中间过程v3 伪目标v4 变量 make 选项-f-n-C Make 是一种流行的构建工具,常用于将源代码转换成可执行文件或者其他形式的输出文件(如库文件、文档等)。Make 可以自动化地执行编译、链接等一系列操作。 规则 makefile文件

使用opencv优化图片(画面变清晰)

文章目录 需求影响照片清晰度的因素 实现降噪测试代码 锐化空间锐化Unsharp Masking频率域锐化对比测试 对比度增强常用算法对比测试 需求 对图像进行优化,使其看起来更清晰,同时保持尺寸不变,通常涉及到图像处理技术如锐化、降噪、对比度增强等 影响照片清晰度的因素 影响照片清晰度的因素有很多,主要可以从以下几个方面来分析 1. 拍摄设备 相机传感器:相机传

嵌入式QT开发:构建高效智能的嵌入式系统

摘要: 本文深入探讨了嵌入式 QT 相关的各个方面。从 QT 框架的基础架构和核心概念出发,详细阐述了其在嵌入式环境中的优势与特点。文中分析了嵌入式 QT 的开发环境搭建过程,包括交叉编译工具链的配置等关键步骤。进一步探讨了嵌入式 QT 的界面设计与开发,涵盖了从基本控件的使用到复杂界面布局的构建。同时也深入研究了信号与槽机制在嵌入式系统中的应用,以及嵌入式 QT 与硬件设备的交互,包括输入输出设

OpenHarmony鸿蒙开发( Beta5.0)无感配网详解

1、简介 无感配网是指在设备联网过程中无需输入热点相关账号信息,即可快速实现设备配网,是一种兼顾高效性、可靠性和安全性的配网方式。 2、配网原理 2.1 通信原理 手机和智能设备之间的信息传递,利用特有的NAN协议实现。利用手机和智能设备之间的WiFi 感知订阅、发布能力,实现了数字管家应用和设备之间的发现。在完成设备间的认证和响应后,即可发送相关配网数据。同时还支持与常规Sof