} }

public void toGary(Bitmap bitmap) { if (isInit) { Mat mat = new Mat(); Utils.bitmapToMat(bitmap, mat); Imgproc.cvtColor(mat, mat, Imgproc.COLOR_RGBA2GRAY); Utils.matToBitmap(mat, bitmap); } else { Toast.makeText(context, “OpenCV init error”, Toast.LENGTH_LONG).show(); } } }

然后是MainActivity,内容如下:

public class MainActivity extends Activity implements OnClickListener { private ImageView imageView; private Bitmap bitmap; private Button showBtn, processBtn; private OpenCV_Java javaUtil = new OpenCV_Java(this);

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById(R.id.imageView); showBtn = (Button) findViewById(R.id.show); showBtn.setOnClickListener(this); processBtn = (Button) findViewById(R.id.process); processBtn.setOnClickListener(this); }

@Override public void onResume() { super.onResume(); if (!OpenCVLoader.initDebug()) { OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, javaUtil); } else { javaUtil.onManagerConnected(LoaderCallbackInterface.SUCCESS); } }

@Override public void onClick(View v) { if (v == showBtn) { bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); imageView.setImageBitmap(bitmap); } else { if (bitmap != null) {//避免二次处理 javaUtil.toGary(bitmap); imageView.setImageBitmap(bitmap); bitmap = null; } } } }

布局内容:

代码编写完毕,但此时还不能运行,因为手机还未安装OpenCV Manager.apk。

2.3、安装OpenCV Manager

位于OpenCV-android-sdk\apk目录下,选择合适的apk程序安装(一般选择OpenCV_3.2.0_Manager_3.20_armeabi.apk)。

2.4、运行Demo

将项目编译打包成apk,安装到手机,运行,点击按钮show后,对图像进行灰度处理,效果如下图所示:

注意:

如果出现OpenCV was not initialised correctly.Application will be shut down,可能是你的OpenCV Manager程序与你的cpu架构不同,选择合适的apk即可。如果手机版本较高,可能会出现调用不到OpenCV Manager的情况,这是因为手机厂商做了限制,防止恶意软件相互唤醒(如百度全家桶),解决方法请自行百度(因为没有统一的方法)。

2.5、抛弃OpenCV Manager:

安装一个额外的apk对用户来说非常不友好,但使用C/C++编程,又对一些Java程序员又提高了实现难度,故我们应该想一个两全其美的方法,即帮助开发人员使用 Java 快速开发,又无需让用户安装额外的软件。

思路:

Java库实际上只是对NDK库进行java封装,将so文件放在OpenCV Manager内,通过AIDL进行交互,从而实现图像处理。

解决方案:

如果我们将OpenCV Manager里面的so文件直接打包到我们的应用里,不就能抛弃OpenCV Manager了吗?

没错,就是这样,并且 OpenCV 官方也给我们提供了现成的so文件,只需将OpenCV-android-sdk\sdk\native\libs\[ARM架构]\ 目录下(一般采用armeabi-v7a即可)的libopencv_java3.so,放到你的项目libs\[ARM架构]\目录下,如图所示:

然后在你的MainActivity.java里面主动加载这个so库

public class MainActivity extends Activity implements OnClickListener { private ImageView imageView; private Bitmap bitmap; private Button showBtn, processBtn; private OpenCV_Java javaUtil = new OpenCV_Java(this);

static{ System.loadLibrary(“opencv_java3”); }

…下面内容不变 }

编译并安装,这时候,你就可以将你的 OpenCV Manager 卸载掉了。运行结果与之前的无异。

注意: 此方法并不是完美的,因为在这个程序里,你只实现了图像的灰度处理,但却引入了libopencv_java3.so这个so文件,apk足足有4.39M,相比之前的194k来说,接近增长了20倍。除非你的应用比较大,而这个so文件的大小是固定的,此时采用此方法也是一个不错的选择。

三、OpenCV NDK库使用指南

3.1、环境配置

第一步: 配置NDK路径

进入菜单->Window->Preferences->Android->NDK,设置NDK Location,注:请确保该路径下存在ndk-build.cmd文件。如下图:

第二步: 配置JNI环境

这里我们通过导入配置文件进行配置:

在你的项目右键Android Tools->Add native support->输入合适的名称->确定,这里我直接使用默认名称。本地新建一个xml文件,将下面内容 copy 进去,并修改其中的路径为你ndk库对应的路径。

D:\AndroidSDK\AndroidStudio\ndk-bundle\sysroot\usr\include D:\AndroidSDK\AndroidStudio\ndk-bundle\sources\cxx-stl\gnu-libstdc++\4.9\include D:\OpenCV\OpenCV-android-sdk\sdk\native\jni\include D:\AndroidSDK\AndroidStudio\ndk-bundle\toolchains\arm-linux-androideabi-4.9\prebuilt\windows-x86_64\lib\gcc\arm-linux-androideabi\4.9.x\include

项目右键选择最后一个Properties,然后选择C/C++ General -> Path and Symbols,如图所示:

点击Import Settings->Browse,在电脑本地选择上面的xml文件,点击Finish,环境就导入成功了。

第三步: 检查环境是否正确

将编译器切换到C/C++编辑器模式:

检查Includes路径是否都存在:确保路径不为灰色(如下图),并且都能展开。

查看环境是否正常。

进入jni目录,打开OpenCVDemo.cpp,在#include上使用Ctrl+鼠标左键,如果eclipse能打开jni.h文件,说明你的JNI环境就搭建成功了。

第四步: 配置OpenCV NDK环境

将下面内容 copy 到Android.mk文件,注意修改OPENCV_ANDROID_SDK为你的OpenCV路径,并阅读我添加的注释。

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)

#这里改成你的路径,分割线内其余内容不变 OPENCV_ANDROID_SDK := D:/OpenCV/OpenCV-android-sdk

#OPENCV_BULID_TYPE := NDK #默认NDK环境,不会自动导入openCV_java3.so,故不支持OpenCV Java库 OPENCV_BULID_TYPE := JAVA_AND_NDK #将自动导入openCV_java3.so,来支持Java库(无需安装OpenCV Manager)

ifeq ($(OPENCV_BULID_TYPE), JAVA_AND_NDK) OPENCV_LIB_TYPE := SHARED OPENCV_INSTALL_MODULES := on else OPENCV_LIB_TYPE := STATIC endif

ifdef OPENCV_ANDROID_SDK ifneq (“”,“$(wildcard $(OPENCV_ANDROID_SDK)/OpenCV.mk)”) include ${OPENCV_ANDROID_SDK}/OpenCV.mk else include ${OPENCV_ANDROID_SDK}/sdk/native/jni/OpenCV.mk endif else include …/…/sdk/native/jni/OpenCV.mk endif

#动态链接日志库 LOCAL_LDLIBS += -llog -ljnigraphics

LOCAL_MODULE := OpenCVDemo LOCAL_SRC_FILES := OpenCVDemo.cpp

include $(BUILD_SHARED_LIBRARY)

在jni目录下增加Application.mk文件,内容如下:

APP_STL := gnustl_static APP_CPPFLAGS := -frtti -fexceptions APP_ABI := all APP_PLATFORM := android-15 APP_OPTIM := debug

至此,NDK环境就配置完毕。

3.2、Demo编写

布局文件还是采用之前的布局文件,修改MainActivity.java内容如下:

public class MainActivity extends Activity implements OnClickListener { private ImageView imageView; private Bitmap bitmap; private Button showBtn, processBtn; private OpenCV_NDK nativeUtil = new OpenCV_NDK ();

@Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); imageView = (ImageView) findViewById (R.id.imageView); showBtn = (Button) findViewById (R.id.show); showBtn.setOnClickListener(this); processBtn = (Button) findViewById (R.id.process); processBtn.setOnClickListener(this); }

@Override public void onClick(View v) { if (v == showBtn) { bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher); imageView.setImageBitmap(bitmap); } else { if (bitmap != null) { nativeUtil.toGary(bitmap); imageView.setImageBitmap(bitmap); bitmap = null; } } } }

可以看到,MainActivity与之前修改不大。

然后是 OpenCV_NDK.java 内容如下:

public class OpenCV_NDK { static { System.loadLibrary(“OpenCVDemo”); } native void toGary(Object bitmap); }

是不是非常简单!

现在只需要为toGary()这个native方法生成头文件,这一步需要使用到javah命令,具体用法,请参考百度。

然后将 OpenCVDemo.cpp 修改为如下内容:

最后

这里附上上述的技术体系图相关的几十套腾讯、头条、阿里、美团等公司2021年的面试题,把技术点整理成了视频和PDF(实际上比预期多花了不少精力),包含知识脉络 + 诸多细节,由于篇幅有限,这里以图片的形式给大家展示一部分。

相信它会给大家带来很多收获:

当程序员容易,当一个优秀的程序员是需要不断学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好! 《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取! 学习的,从初级程序员到高级程序员,从初级架构师到资深架构师,或者走向管理,从技术经理到技术总监,每个阶段都需要掌握不同的能力。早早确定自己的职业方向,才能在工作和能力提升中甩开同龄人。

无论你现在水平怎么样一定要 持续学习 没有鸡汤,别人看起来的毫不费力,其实费了很大力,这四个字就是我的建议!!!我希望每一个努力生活的IT工程师,都会得到自己想要的,因为我们很辛苦,我们应得的。

当我们在抱怨环境,抱怨怀才不遇的时候,没有别的原因,一定是你做的还不够好! 《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》,点击传送门,即可获取!

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: