之前博文《Android学习笔记之——基于Android的opencv开发(Android studio3.6+opencv4.3.0开发环境搭建)》已经在Android studio中搭建了opencv的环境。本博文来进一步学习一下基于android的opencv开发
目录
OpenCV Android SDK
将OpenCV打包jar包的方法
成功在手机上运行基于opencv的demo
参考资料
OpenCV Android SDK 本质上是使用Java 语言接口通过JNI 技术调用OpenCV C++代码完成的算法模块。Open CV 4Android 本身并不是一个纯Java 语言的计算机视觉库,而是基于OpenCVC ++本地代码、通过Java 语言接口定义,基于JNI 技术实现调
用C ++本地方法的SDK 开发包。所以当你下载好OpenCV Android SDK 之后,在它的SDK 目录下可以看到如图所示的目录结构。
OpenCV Android SDK 的功能与Open CV 对应发布版本中的功能完全相同,唯一不同的是因为Java 语言的关系, Java 层封装的接口的参数传递和方法调用,与C++的接口相比有一些差异,这些都是为了更适应Java 语言的特性而做出的改动,使得Android 开发者更加容易学习与使用Open CV 来解决问题。
之前博文《Android学习笔记之——基于Android的opencv开发(Android studio3.6+opencv4.3.0开发环境搭建)》完成了开发环境搭建,但是每次都要这样操作就非常麻烦了,此处将opencv打包为jar包
首先点击右边的gradle,如图所示:
依次选择430,other,如图所示
找到create full jar debug (或者release),如图
双击任意一个运行,运行完成后,改为project视图,在opencv430-bulid-intermediates-full_jar-debug下找到full_jar文件,如图所示
把full_jar复制到app项目的libs下,如图所示:
右键full.jar,add as a library,如图
点击ok
然后你就可以使用opencv中的Java接口,不用每次都Import Module了,如图
测试代码
package com.example.androidopencvtest;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.android.CameraActivity;
import java.io.InputStream;
public class MainActivity extends AppCompatActivity {
// Used to load the 'native-lib' library on application startup.
static {
if (!OpenCVLoader.initDebug()) {
// System.loadLibrary("src/main/jniLibs");
// Handle initialization error
}
// System.loadLibrary("native-lib");
// System.loadLibrary("jniLibs");
// System.loadLibrary("src/main/jniLibs");
// System.loadLibrary("libs");
}
private double max_size = 1024;
private int PICK_IMAGE_REQUEST = 1;
private ImageView myImageView;
private Bitmap selectbp;
//权限
private static String[] PERMISSIONS_STORAGE = {
// Manifest.permission.READ_EXTERNAL_STORAGE,
Manifest.permission.WRITE_EXTERNAL_STORAGE,//写权限
Manifest.permission.CAMERA//照相权限
};
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
staticLoadCVLibraries();
myImageView = (ImageView)findViewById(R.id.imageView);
myImageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
Button selectImageBtn = (Button)findViewById(R.id.select_btn);
selectImageBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// makeText(MainActivity.this.getApplicationContext(), "start to browser image", Toast.LENGTH_SHORT).show();
selectImage();
}
private void selectImage() {
Intent intent = new Intent();
intent.setType("image/*");
intent.setAction(Intent.ACTION_GET_CONTENT);
startActivityForResult(Intent.createChooser(intent,"选择图像..."), PICK_IMAGE_REQUEST);
}
});
//华为手机摄像头权限申请
//用于判断SDK版本是否大于23
if (Build.VERSION.SDK_INT>= Build.VERSION_CODES.M){
//检查权限
int i = ContextCompat.checkSelfPermission(this,PERMISSIONS_STORAGE[0]);
//如果权限申请失败,则重新申请权限
if(i!= PackageManager.PERMISSION_GRANTED){
//重新申请权限函数
startRequestPermission();
Log.e("这里","权限请求成功");
}
}
Button processBtn = (Button)findViewById(R.id.process_btn);
processBtn.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
// makeText(MainActivity.this.getApplicationContext(), "hello, image process", Toast.LENGTH_SHORT).show();
convertGray();
}
});
}
private void staticLoadCVLibraries() {
boolean load = OpenCVLoader.initDebug();
if(load) {
Log.i("CV", "Open CV Libraries loaded...");
}
}
private void convertGray() {
Mat src = new Mat();
Mat temp = new Mat();
Mat dst = new Mat();
Utils.bitmapToMat(selectbp, src);
Imgproc.cvtColor(src, temp, Imgproc.COLOR_BGRA2BGR);
Log.i("CV", "image type:" + (temp.type() == CvType.CV_8UC3));
Imgproc.cvtColor(temp, dst, Imgproc.COLOR_BGR2GRAY);
Utils.matToBitmap(dst, selectbp);
myImageView.setImageBitmap(selectbp);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if(requestCode == PICK_IMAGE_REQUEST && resultCode == RESULT_OK && data != null && data.getData() != null) {
Uri uri = data.getData();
try {
Log.d("image-tag", "start to decode selected image now...");
InputStream input = getContentResolver().openInputStream(uri);
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeStream(input, null, options);
int raw_width = options.outWidth;
int raw_height = options.outHeight;
int max = Math.max(raw_width, raw_height);
int newWidth = raw_width;
int newHeight = raw_height;
int inSampleSize = 1;
if(max > max_size) {
newWidth = raw_width / 2;
newHeight = raw_height / 2;
while((newWidth/inSampleSize) > max_size || (newHeight/inSampleSize) > max_size) {
inSampleSize *=2;
}
}
options.inSampleSize = inSampleSize;
options.inJustDecodeBounds = false;
options.inPreferredConfig = Bitmap.Config.ARGB_8888;
selectbp = BitmapFactory.decodeStream(getContentResolver().openInputStream(uri), null, options);
myImageView.setImageBitmap(selectbp);
} catch (Exception e) {
e.printStackTrace();
}
}
}
private void startRequestPermission(){
//321为请求码
ActivityCompat.requestPermissions(this,PERMISSIONS_STORAGE,321);
}
}
还是不行,应该就是没有将opencv的库编译进去
加入下面的代码
@Override //免安装Opencv manager
protected void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
System.out.println("Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION_3_4_0, this, mLoaderCallback);
} else {
System.out.println("OpenCV library found inside package. Using it!");
mLoaderCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
// OpenCV库加载并初始化成功后的回调函数
private BaseLoaderCallback mLoaderCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
switch (status) {
case LoaderCallbackInterface.SUCCESS: {
System.out.println("OpenCV loaded successfully");
}
break;
default: {
super.onManagerConnected(status);
}
break;
}
}
};
加上上边这段代码,下边这两个方法就是判断是否已经存在OpenCv库,存在就是用打包好的,不存在就下载。然后就ok啦~
接下来基本就可以将之前学过的opencv相关的开发移植到手机上了哈~
https://blog.csdn.net/qq_39321542/article/details/106080136
https://blog.csdn.net/lhhnb/article/details/89705989
https://blog.csdn.net/lhhnb/article/details/94896434