一、问题如下:
AS->File->New->Import Module 选择导入(压缩包路径)/sdk/java文件夹,然后发现AS没有下一步?
二、解决办法
新建一个项目-在新建项目下创建一个包命名library
将opencv-android-sdk下的java包放进新建的包下改名opencv,写一个build文件(或者在github网站里找到自己想要的项目,将项目里面的library里面的文件复制到自己创建的library,这里,我是使用别人项目里面的包)
打开项目在setting.gradle添加include ':library
添加依赖,File-Project Structure-Dependencies-点击app然后点击加号,选择3(module Dependency),选择library。
然后在main下创建jniLib包,将opencv-sdk-native-libs下的文件复制到jniLib文件下。
以上是基本完成了opencv环境的配置。
三、下面介绍两个基于opencv的两个小demo。
1、图片灰度化
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;
import org.opencv.android.Utils;
import org.opencv.core.Mat;
import org.opencv.imgproc.Imgproc;
import org.opencv.osgi.OpenCVNativeLoader;
public class MainActivity extends AppCompatActivity {
private ImageView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OpenCVNativeLoader loader = new OpenCVNativeLoader();
loader.init();
mImageView = findViewById(R.id.imageView);
mImageView.setImageResource(R.drawable.img_origin);
mImageView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(),R.drawable.img_origin);
Mat mat = new Mat();
Mat grayMat = new Mat();
Utils.bitmapToMat(bitmap,mat);
Imgproc.cvtColor(mat, grayMat, Imgproc.COLOR_RGB2GRAY);
Utils.matToBitmap(grayMat,bitmap);
mImageView.setImageBitmap(bitmap);
}
});
}
}
XML的程序如下
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />
</androidx.constraintlayout.widget.ConstraintLayout>
2、人脸检测
mainActivity下的程序如下:
import androidx.annotation.NonNull;
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import android.Manifest;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import org.opencv.android.CameraBridgeViewBase;
import org.opencv.android.OpenCVLoader;
import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.osgi.OpenCVNativeLoader;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.util.logging.Logger;
public class MainActivity extends AppCompatActivity implements CameraBridgeViewBase.CvCameraViewListener2 {
private CameraBridgeViewBase openCvCameraView;
private static final String TAG = "OpencvActivity";
private CascadeClassifier cascadeClassifier = null; //级联分类器
private Mat mRgba; //图像容器
private Mat mGray;
private int absoluteFaceSize = 0;
private Handler handler;
private void initializeOpenCVDependencies() {
try {
InputStream is = getResources().openRawResource(R.raw.lbpcascade_frontalface_improved); //OpenCV的人脸模型文件: lbpcascade_frontalface_improved
File cascadeDir = getDir("cascade", Context.MODE_PRIVATE);
File mCascadeFile = new File(cascadeDir, "lbpcascade_frontalface_improved.xml");
FileOutputStream os = new FileOutputStream(mCascadeFile);
byte[] buffer = new byte[4096];//其实byte[] buffer = new byte[4096]只是在内存中开辟块缓冲区而已。大小随便你写(假如你不是Extreme Programming的FANS),只要不超过你实际可用内存大小就好。不过太大或者太小都会对性能有影响
int bytesRead;
while ((bytesRead = is.read(buffer)) != -1) {
os.write(buffer, 0, bytesRead);
}
is.close();
os.close();
// 加载cascadeClassifier
cascadeClassifier = new CascadeClassifier(mCascadeFile.getAbsolutePath());
} catch (Exception e) {
Log.e(TAG, "Error loading cascade", e);
}
// 显示
openCvCameraView.enableView();
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if(requestCode == 0) {
try {
for(int i = 0; i < permissions.length; i++) {
Log.d(TAG, permissions[i] + ":" + grantResults[i]);
}
}catch(Exception e){
e.printStackTrace();
}
}
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
//new GetRunAuthorityUtil().getRunAuthority(this, this); //动态获取权限
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.CAMERA,
Manifest.permission.WRITE_EXTERNAL_STORAGE},1);
handler = new Handler();
openCvCameraView = (CameraBridgeViewBase) findViewById(R.id.javaCameraView);
openCvCameraView.setCameraIndex(1); //摄像头索引 -1/0:后置双摄 1:前置
openCvCameraView.enableFpsMeter(); //显示FPS
openCvCameraView.setCvCameraViewListener(this);
}
@Override
public void onResume() {
super.onResume();
if (!OpenCVLoader.initDebug()) {
Log.e(TAG, "OpenCV init error");
}
initializeOpenCVDependencies();
}
@Override
public void onCameraViewStarted(int width, int height) {
mRgba = new Mat();
mGray = new Mat();
}
@Override
public void onCameraViewStopped() {
mRgba.release();
mGray.release();
}
@Override
public Mat onCameraFrame(CameraBridgeViewBase.CvCameraViewFrame inputFrame) {
mRgba = inputFrame.rgba(); //RGBA
mGray = inputFrame.gray(); //单通道灰度图
if (absoluteFaceSize == 0) {
int height = mGray.rows();
if (Math.round(height * 0.2f) > 0) {
absoluteFaceSize = Math.round(height * 0.2f);
}
}
//解决 前置摄像头旋转显示问题
//Core.flip(mRgba, mRgba, 1); //旋转
//Core.flip(mGray, mGray, 1);
//检测并显示
MatOfRect faces = new MatOfRect();
if (cascadeClassifier != null) {
cascadeClassifier.detectMultiScale(mGray, faces, 1.1, 2, 2, new Size(absoluteFaceSize, absoluteFaceSize), new Size());
}
Rect[] facesArray = faces.toArray();
if (facesArray.length > 0){
for (int i = 0; i < facesArray.length; i++) { //用框标记
Imgproc.rectangle(mRgba, facesArray[i].tl(), facesArray[i].br(), new Scalar(0, 255, 0, 255), 3);
}
}
return mRgba;
}
}
XML下的程序如下
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<org.opencv.android.JavaCameraView
android:id="@+id/javaCameraView"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</androidx.constraintlayout.widget.ConstraintLayout>
在res下创建一个raw包,将opencv-android-sdk下面的sdk-etc-libpacascades里面的两个文件复制到raw里面,如下图:
然后运行,应该没啥问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)