参考链接:
(1) https://zhuanlan.zhihu.com/p/666307982
(2) https://forum.opencv.org/t/opencv-4-8-0-cannot-resolve-symbol-opencv-engine-interface/14307/2
以下操作以张思民老师的《Android Studio应用程序设计》第3版中的例9-2为例进行操作。
1. 下载OpenCV Android SDK
(1) 进入OpenCV 官网:https://opencv.org/releases/
(2) 点击下方的Android开始下载
(3) 下载的OpenCV Android SDK为如图所示的压缩包
(4) 解压以上压缩包
2. 搭建开发环境
(1) 新建一个空白项目
(2) 选择菜单File→New→Import Module
(3) 在Import module from source对话框中选择OpenCV-android-sdk解压目录下的sdk
注意:是目录下的sdk而不是课本中sdk/java
(4)稍等,运行项目出现以下报错
Plugin [id: ‘com.android.application’, version: ‘8.1.0’, apply: false] was not found in any of the following sources:
(5)解决以上问题
① 查看以下信息
② 打开opencv/build.gradle
③ 修改方框中的参数与步骤①中参数一致,修改后如下图所示
④ 将apply plugin: ‘kotlin-android’ 注释掉
⑤ 添加namespace “org.opencv”
⑥ 打开项目目录中的settings.gradle和settings.gradle.kts
⑦ 将settings.gradle.kts中的内容复制到settings.gradle
settings.gradle.kts 内容保持不变
settings.gradle 在末尾添加一行include(“:opencv”)
重新编译,报错消失
3. 编写代码
(1) 在res/drawable文件夹下放置一张图片
(2) 将布局文件复制到res/layout/activity_main.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="289dp"
android:layout_height="324dp"
android:layout_marginStart="4dp"
android:layout_marginLeft="4dp"
android:layout_marginTop="4dp"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/dog" />
<Button
android:id="@+id/button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="12dp"
android:layout_marginLeft="12dp"
android:layout_marginTop="12dp"
android:text="图像模糊"
app:layout_constraintStart_toStartOf="@+id/imageView"
app:layout_constraintTop_toBottomOf="@+id/imageView" />
<Button
android:id="@+id/button2"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="24dp"
android:layout_marginLeft="24dp"
android:text="图像锐化"
app:layout_constraintStart_toEndOf="@+id/button"
app:layout_constraintTop_toTopOf="@+id/button" />
</androidx.constraintlayout.widget.ConstraintLayout>
(3) 将JAVA主程序复制到MainActivity文件中
package com.example.example_9_2;
import androidx.appcompat.app.AppCompatActivity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
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.core.Point;
import org.opencv.core.Size;
import org.opencv.imgproc.Imgproc;
public class MainActivity extends AppCompatActivity {
ImageView imgView;
Button btn1, btn2;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
imgView = findViewById(R.id.imageView);
btn1 = findViewById(R.id.button);
btn2 = findViewById(R.id.button2);
btn1.setOnClickListener(new mClick1());
btn2.setOnClickListener(new mClick2());
boolean success = OpenCVLoader.initDebug();
}
class mClick1 implements View.OnClickListener {
@Override
public void onClick(View v) {
/*
* */
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.flower2);
//(1)定义3×3模糊卷积核
Mat kernel = new Mat(3, 3, CvType.CV_32FC1);
float[] data = new float[]{0, 1.0f/8.0f, 0,
1.0f/8.0f, 0.5f, 1.0f/8.0f,
0, 1.0f/8.0f, 0};
kernel.put(0, 0, data);
//(2)使用上面定义的卷积核实现滤波
Mat src = new Mat();
Mat dst = new Mat();
for( int i=1; i<5; i++) {
Utils.bitmapToMat(bitmap, src);
Imgproc.filter2D(src, dst, -1, kernel, new Point(-1, -1), 0.0, Imgproc.CCL_BOLELLI);
//高斯模糊
Imgproc.GaussianBlur(src, dst, new Size(5.0, 5.0), 10.0, 20.0);
Utils.matToBitmap(dst, bitmap);
}
imgView.setImageBitmap(bitmap);
src.release();
dst.release();
}
}
class mClick2 implements View.OnClickListener{
@Override
public void onClick(View v) {
/* */
Bitmap bitmap = BitmapFactory.decodeResource(MainActivity.this.getResources(), R.drawable.flower2);
//(1)定义锐化算子卷积核
Mat kernel = new Mat(3, 3, CvType.CV_32FC1);
float[] data = new float[]{-1, -1, -1, -1, 9, -1, -1, -1, -1};
// float[] data = new float[]{0, -1, 0, -1, 5, -1, 0, -1, 0};
kernel.put(0, 0, data);
//(2)使用上面定义的卷积核实现滤波
Mat src = new Mat();
Mat dst = new Mat();
for( int i=1; i<2; i++) {
Utils.bitmapToMat(bitmap, src);
Imgproc.filter2D(src, dst, -1, kernel, new Point(-1, -1), 0.0, Imgproc.CCL_BOLELLI);
Utils.matToBitmap(dst, bitmap);
}
imgView.setImageBitmap(bitmap);
src.release();
dst.release();
}
}
}
(4) 报错 Cannot resolve symbol ‘opencv’
(5) 点击代码中报错位置的小红灯
选择其中第一项
稍等片刻,报错消除
(6) 点击运行,OpenCVEngineInterface报错
(7) 参考链接:https://forum.opencv.org/t/opencv-4-8-0-cannot-resolve-symbol-opencv-engine-interface/14307/2
在opencv的build.gradle中添加代码
buildFeatures {
aidl = true
buildConfig = true
}