Android OpenCV(二):Mat像素操作

2,364 阅读4分钟

Mat

Mat类用于表示一个多维的单通道或者多通道的稠密数组。能够用来保存实数或复数的向量、矩阵,灰度或彩色图像,立体元素,点云,张量以及直方图(高维的直方图使用SparseMat保存比较好)。简而言之,Mat就是用来保存多维的矩阵的。Mat对象中包含了图像的各种基本信息与图像像素数据。Mat是由头部与数据部分组成的,其中头部还包含一个指向数据的指针。

Mat方法

由于篇幅限制,无法展示。移步CSDN或者公众号查看。

方法 使用
public int height() {} 行数
public int width() {} 列数
public long getNativeObjAddr() {} Native object地址

Mat位操作

方法 操作
public static void bitwise_not(Mat src, Mat dst) 按位非
public static void bitwise_and(Mat src1, Mat src2, Mat dst) 按位与
public static void bitwise_or(Mat src1, Mat src2, Mat dst) 按位或
public static void bitwise_xor(Mat src1, Mat src2, Mat dst) 按位异或
位运算 操作
非运算 1变为0,0变为1
与运算 只有对应的两个二进位均为1时,结果的对 应二进制位才为1,否则为0
或运算 只有对应的两个二进位都为0时,结果的对应 二进制位才是0,否则为1
异或运算 只有对应的两个二进位不相同时,结果的对应二进制 位才是1,否则为0

Mat算术运算

方法 操作
public static void add(Mat src1, Mat src2, Mat dst) 矩阵加法
public static void subtract(Mat src1, Mat src2, Mat dst) 矩阵减法
public static void multiply(Mat src1, Mat src2, Mat dst) 矩阵乘法
public static void divide(Mat src1, Mat src2, Mat dst, double scale, int dtype) 矩阵除法

矩阵加法

通常的矩阵加法被定义在两个相同大小的矩阵。两个m×n矩阵AB的和,标记为A+B,一样是个m×n矩阵,其内的各元素为其相对应元素相加后的值。例如:

矩阵减法

矩阵的减法,只要其大小相同的话。A-B内的各元素为其相对应元素相减后的值,且此矩阵会和AB有相同大小。例如:

矩阵乘法

1、当矩阵A的列数(column)等于矩阵B的行数(row)时,A与B可以相乘。

2、矩阵C的行数等于矩阵A的行数,C的列数等于B的列数。

3、乘积C的第m行第n列的元素等于矩阵A的第m行的元素与矩阵B的第n列对应元素乘积之和。

矩阵除法

对于矩阵的除法,我们一般不说矩阵的除法,通常都是讲的矩阵求逆

具体操作: 我们先将被除的矩阵转化为它的逆矩阵,之后再与另一个矩阵进行矩阵的乘法运算

矩阵求逆:设A是数域上的一个n阶方阵,若在相同数域上存在另一个n阶矩B,使得: AB=BA=E。 则我们称B是A的逆矩阵,而A则被称为可逆矩阵。其中,E为单位矩阵。典型的矩阵求逆方法有:利用定义求逆矩阵、初等变换法、伴随阵法、恒等变形法等。

Mat位运算和算术运算实现

class MatOperationActivity : AppCompatActivity() {

    private lateinit var mBinding: ActivityMatOperationBinding
    private lateinit var bgr: Mat
    private lateinit var source: Mat

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        mBinding = DataBindingUtil.setContentView(this, R.layout.activity_mat_operation)

        bgr = Utils.loadResource(this, R.drawable.lena)
        source = Mat()
        Imgproc.cvtColor(bgr, source, Imgproc.COLOR_BGR2RGB)
        mBinding.ivSource.setImageResource(R.drawable.lena)
        val bitmap = Bitmap.createBitmap(source.width(), source.height(), Bitmap.Config.ARGB_8888)
        bitmap.density = DisplayMetrics.DENSITY_XXHIGH
        Utils.matToBitmap(bgr, bitmap)
        mBinding.ivBgr.setImageBitmap(bitmap)

    }

    override fun onCreateOptionsMenu(menu: Menu?): Boolean {
        menuInflater.inflate(R.menu.menu_mat_operation, menu)
        return true
    }

    override fun onOptionsItemSelected(item: MenuItem): Boolean {
        when (item.itemId) {
            R.id.bitwise_not
            -> bitwiseNot(source)
            R.id.bitwise_and
            -> bitwiseAnd(source, bgr)
            R.id.bitwise_xor
            -> bitwiseXor(source, bgr)
            R.id.bitwise_or
            -> bitwiseOr(source, bgr)
            R.id.add
            -> add(source, bgr)
            R.id.subtract
            -> subtract(source, bgr)
            R.id.multiply
            -> multiply(source, bgr)
            R.id.divide
            -> divide(source, bgr)
        }
        return true
    }

    private fun showResult(dst: Mat) {
        val bitmap = Bitmap.createBitmap(dst.width(), dst.height(), Bitmap.Config.ARGB_8888)
        Utils.matToBitmap(dst, bitmap)
        mBinding.ivResult.setImageBitmap(bitmap)
    }

    private fun bitwiseNot(source: Mat) {
        val dst = Mat()
        Core.bitwise_not(source, dst)
        showResult(dst)
        dst.release()
    }

    private fun bitwiseAnd(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.bitwise_and(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun bitwiseOr(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.bitwise_or(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun bitwiseXor(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.bitwise_xor(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun add(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.add(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun subtract(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.subtract(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun multiply(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.multiply(source, attach, dst)
        showResult(dst)
        dst.release()
    }

    private fun divide(source: Mat, attach: Mat) {
        val dst = Mat()
        Core.divide(source, attach, dst, 50.0, -1)
        Core.convertScaleAbs(dst, dst)
        showResult(dst)
        dst.release()
    }
}

运行结果

按位非

按位与

按位或

按位异或

矩阵加法

矩阵减法

矩阵乘法

矩阵除法

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

本文使用 mdnice 排版