前言
OpenCV 是功能非常强大的 跨平台计算机视觉库。
引入Android中使用。
1.下载
到 OpenCV 官网https://opencv.org/releases/ 下载 Android 对应的 SDK 。
下载下来的 opencv-4.5.1-android-sdk 压缩包中的 sdk 文件夹就是我们需要的。
2.导入到AS
在 AS 上新建一个工程备用,新建好之后引入 sdk 。
File – New – Import Project ,然后选择 sdk 文件夹, Finish 完成。
导入成功后在左侧预览页面可以看到 module sdk 。
3.配置
在工程的 app 的 build.gradle
中引入 sdk
dependencies {
implementation project(path: ':sdk')
// other option
}
4.开始使用
4.1 初始化
使用 OpenCV 前需要初始化,很合理。
本例放到 Application 中初始化。
自定义一个 Application ,
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.test.androidopencvdemo">
<application
android:name=".MyApplication" //很简单,这样自定义就可以了
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
初始化,
public class MyApplication extends Application {
private static final String TAG = MyApplication.class.getSimpleName();
private BaseLoaderCallback mCallback = new BaseLoaderCallback(this) {
@Override
public void onManagerConnected(int status) {
//super.onManagerConnected(status);
switch (status){
case LoaderCallbackInterface.SUCCESS:
Log.i(TAG, "OpenCV loaded successfully");
break;
default:break;
}
}
};
@Override
public void onCreate() {
super.onCreate();
initOpenCV();
}
private void initOpenCV(){
if (!OpenCVLoader.initDebug()) {
Log.d(TAG, "Internal OpenCV library not found. Using OpenCV Manager for initialization");
OpenCVLoader.initAsync(OpenCVLoader.OPENCV_VERSION, this, mCallback);
} else {
Log.d(TAG, "OpenCV library found inside package. Using it!");
mCallback.onManagerConnected(LoaderCallbackInterface.SUCCESS);
}
}
}
如果不初始化会报错:
java.lang.UnsatisfiedLinkError: No implementation found for long org.opencv.core.Mat.n_Mat(int, int, int) (tried Java_org_opencv_core_Mat_n_1Mat and Java_org_opencv_core_Mat_n_1Mat__III)
4.2 使图片变灰
示例很简单,使用 ImageView 显示一张图片,点击 Button 后图片置灰显示。
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private ImageView mImageView;
private Button mButton;
private MainActivity mActivity;
private Bitmap mBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mActivity = MainActivity.this;
mImageView = (ImageView) findViewById(R.id.image);
mButton = (Button) findViewById(R.id.button);
mButton.setOnClickListener(mActivity);
}
@Override
protected void onResume() {
super.onResume();
mBitmap = decodeSampleBitmap(getResources(), R.drawable.huluwa, 100, 100);
mImageView.setImageBitmap(mBitmap);
}
@Override
public void onClick(View v) {
if (v.getId() == R.id.button) {
Bitmap bit = mBitmap.copy(Bitmap.Config.ARGB_8888, false);
Mat mat = new Mat(bit.getHeight(), bit.getWidth(), CvType.CV_8UC(3));
Utils.bitmapToMat(bit, mat);
Imgproc.cvtColor(mat, mat, Imgproc.COLOR_BGR2GRAY);
Utils.matToBitmap(mat, mBitmap);
mImageView.setImageBitmap(mBitmap);
}
}
@Override
protected void onStop() {
super.onStop();
if (mBitmap != null) {
mBitmap.recycle();
}
}
public static Bitmap decodeSampleBitmap(Resources resources, int resId, int reqWidth, int reqHeight){
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true;
BitmapFactory.decodeResource(resources, resId, options);
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight);
options.inJustDecodeBounds = false;
return BitmapFactory.decodeResource(resources, resId, options);
}
public static int calculateInSampleSize(BitmapFactory.Options options, int reqWidth, int reqHeight){
final int width = options.outWidth;
final int height = options.outHeight;
int sampleSize = 1;
if (height > reqHeight || width > reqWidth) {
final int halfHeight = height/2;
final int halfWidth = width/2;
while ( (halfHeight / sampleSize) >= reqHeight &&
(halfWidth / sampleSize) >= reqWidth){
sampleSize *= 2;
}
}
return sampleSize;
}
}
前后对比,