Mat
Mat的概念
在Android中对图像是用bitmap格式来进行处理,而OpenCV中则是采用Mat格式,所以我们在程序中需要将bitmap转换成Mat格式以便使用OpenCV。Mat类用于表示一个多维的单通道或者多通道数组,能够用来保存实数或复数的向量,矩阵,灰度或者彩色图形,立体元素,张量以及直方图。简而言之,Mat就是表示图像的矩阵。
加载图片
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.lbxx);
Bitmap和Mat的转换
Bitmap转Mat
Utils.matToBitmap(srcMat, dstMat);
Mat转Bitmap
Utils.bitmapToMat(srcMat,dstMat);
常见Mat位运算运算
| 修饰语与类型 | 方法 | 描述 |
|---|---|---|
| static void | and (Mat src1, Mat src2, Mat dst) | 计算两个数组或一个数组和一个标量的每个元素的和 |
| static void | bitwise_not (Mat src, Mat dst) | 反转数组的每一位 |
| static void | bitwise_or (Mat src1, Mat src2, Mat dst) | 计算两个数组或一个数组和一个标量的逐元素逐位析取 |
| static void | bitwise_xor (Mat src1, Mat src2, Mat dst) | 在两个数组或一个数组和一个标量上按位计算每个元素的“互斥或”操作 |
常见Mat算数运算
| 修饰语与类型 | 方法 | 描述 |
|---|---|---|
| static void | add (Mat src1, Mat src2, Mat dst) | 计算两个数组或一个数组和一个标量的每个元素的和 |
| static void | subtract (Mat src1, Mat src2, Mat dst) | 计算两个数组或数组与标量之间每个元素的差值 |
| static void | multiply (Mat src1, Mat src2, Mat dst) | 计算两个数组按元素缩放的乘积 |
| static void | divide (Mat src1, Mat src2, Mat dst) | 对两个数组或一个标量执行每个元素的除法 |
案例
这里以and()方法为例,即计算两个Mat的和,然后将结果显示出来
由于Android基本语法不是本文重点,所以界面的编写不做阐述,简单来说上面两个为源图像,下面的为结果图像,按钮AND会将计算他们两个每个元素的合,然后将结果显示到下面的图像。
加载源图像
try {
srcMat1 = Utils.loadResource(this, R.drawable.lbxx);
srcMat2 = Utils.loadResource(this, R.drawable.lbxx2);
} catch (IOException e) {
e.printStackTrace();
}
AND按钮的监听事件
btnAnd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.bitwise_and(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(dstMat.width(), dstMat.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
按下后结果如下图所示
完整代码
MainActivity.java
package com.example.opencvdemo;
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.Core;
import org.opencv.core.Mat;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
private String TAG = "MainActivity";
private Button btnAnd, btnNot, btnOr, btnXor, btnAdd, btnSub, btnMul, btnDiv;
private ImageView imageViewSrc1, imageViewSrc2, imageViewDst;
private Mat srcMat1, srcMat2, dstMat;
private Bitmap resultBitmap;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
OpenCVInit();
btnAnd = findViewById(R.id.btn_and);
btnNot = findViewById(R.id.btn_not);
btnOr = findViewById(R.id.btn_or);
btnXor = findViewById(R.id.btn_xor);
btnAdd = findViewById(R.id.btn_add);
btnSub = findViewById(R.id.btn_sub);
btnMul = findViewById(R.id.btn_mul);
btnDiv = findViewById(R.id.btn_div);
srcMat1 = new Mat();
srcMat2 = new Mat();
dstMat = new Mat();
imageViewSrc1 = findViewById(R.id.iv_src1);
imageViewSrc2 = findViewById(R.id.iv_src2);
imageViewDst = findViewById(R.id.iv_dst);
try {
srcMat1 = Utils.loadResource(this, R.drawable.lbxx);
srcMat2 = Utils.loadResource(this, R.drawable.lbxx2);
} catch (IOException e) {
e.printStackTrace();
}
btnAnd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.bitwise_and(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(dstMat.width(), dstMat.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnNot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.bitwise_not(srcMat1, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnOr.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.bitwise_or(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnXor.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.bitwise_xor(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnAdd.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.add(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnSub.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.subtract(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnMul.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.multiply(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
btnDiv.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Core.divide(srcMat1, srcMat2, dstMat);
resultBitmap = Bitmap.createBitmap(srcMat1.width(), srcMat1.height(), Bitmap.Config.ARGB_8888);
Utils.matToBitmap(dstMat, resultBitmap);
imageViewDst.setImageBitmap(resultBitmap);
}
});
}
private void OpenCVInit() {
boolean success = OpenCVLoader.initDebug();
if (success) {
Log.d(TAG, "OpenCV Lode success");
} else {
Log.d(TAG, "OpenCV Lode failed ");
}
}
@Override
protected void onDestroy() {
srcMat1.release();
srcMat2.release();
dstMat.release();
super.onDestroy();
}
}
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/iv_src1"
android:layout_width="125dp"
android:layout_height="125dp"
app:layout_constraintBottom_toTopOf="@+id/btn_not"
app:layout_constraintEnd_toStartOf="@id/iv_src2"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@drawable/lbxx" />
<ImageView
android:id="@+id/iv_src2"
android:layout_width="125dp"
android:layout_height="125dp"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/iv_src1"
app:layout_constraintTop_toTopOf="@+id/iv_src1"
app:srcCompat="@drawable/lbxx2" />
<Button
android:id="@+id/btn_and"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="and"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_not"
app:layout_constraintHorizontal_bias="0.5"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.363" />
<Button
android:id="@+id/btn_not"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="not"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_or"
app:layout_constraintStart_toEndOf="@id/btn_and"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.363" />
<Button
android:id="@+id/btn_or"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="or"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@id/btn_xor"
app:layout_constraintStart_toEndOf="@id/btn_not"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.363" />
<Button
android:id="@+id/btn_xor"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="xor"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintStart_toEndOf="@id/btn_or"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintVertical_bias="0.363" />
<Button
android:id="@+id/btn_add"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="add"
app:layout_constraintStart_toStartOf="@+id/btn_and"
app:layout_constraintTop_toBottomOf="@+id/btn_and" />
<Button
android:id="@+id/btn_sub"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="sub"
app:layout_constraintStart_toStartOf="@+id/btn_not"
app:layout_constraintTop_toTopOf="@+id/btn_add" />
<Button
android:id="@+id/btn_mul"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="mul"
app:layout_constraintStart_toStartOf="@+id/btn_or"
app:layout_constraintTop_toTopOf="@+id/btn_sub" />
<Button
android:id="@+id/btn_div"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="div"
app:layout_constraintStart_toStartOf="@+id/btn_xor"
app:layout_constraintTop_toTopOf="@+id/btn_mul" />
<ImageView
android:id="@+id/iv_dst"
android:layout_width="206dp"
android:layout_height="206dp"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintHorizontal_bias="0.497"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toBottomOf="@+id/btn_sub"
app:srcCompat="@drawable/lbxx" />
</androidx.constraintlayout.widget.ConstraintLayout>
图像素材