Android OpenCV(二):Mat像素操作

Mat

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

Mat方法

方法 使用
public Mat(long addr) {} 指定Native Object地址
public Mat() {} 创建空对象
public Mat(int rows, int cols, int type) {} 指定行数,列数和类型
public Mat(int rows, int cols, int type, ByteBuffer data) {} 指定行数,列数和类型并传入像素数据
public Mat(int rows, int cols, int type, ByteBuffer data, long step) { 指定行数,列数,类型并传入像素数据以及每一行的步长
public Mat(Size size, int type) {} 指定大小(行列)和类型
public Mat(int[] sizes, int type) {} 指定大小(行列)和类型
public Mat(int rows, int cols, int type, Scalar s) {} 指定行数,列数,类型和颜色
public Mat(Size size, int type, Scalar s) {} 指定大小(行列),类型和颜色
public Mat(int[] sizes, int type, Scalar s) {} 指定大小(行列),类型和颜色
public Mat(Mat m, Range rowRange, Range colRange) {} 获取矩阵M下rowRange、colRange范围内的子矩阵
public Mat(Mat m, Range rowRange) {} 获取矩阵M下rowRange范围内的子矩阵
public Mat(Mat m, Range[] ranges) {} 获取矩阵M下rowRange、colRange范围内的子矩阵
public Mat(Mat m, Rect roi) {} 获取矩阵M下roi矩形范围内的子矩阵
public Mat adjustROI(int dtop, int dbottom, int dleft, int dright) {} 指定矩阵左上右下,然后获取当前矩阵的对应子矩阵
public void assignTo(Mat m, int type) {} 提供了一个convertTo的功能形式
public void assignTo(Mat m) {} 提供了一个convertTo的功能形式
public int channels() {} 通道数
public int checkVector(int elemChannels, int depth, boolean requireContinuous) {} 返回符合要求的矩阵中的元素个数(行数、列数和通道数中必有一个为1;其余二者必有一个与checkVector的输入参数一致)
public int checkVector(int elemChannels, int depth) {} 返回符合要求的矩阵中的元素个数(行数、列数和通道数中必有一个为1;其余二者必有一个与checkVector的输入参数一致)
public int checkVector(int elemChannels) {} 返回符合要求的矩阵中的元素个数(行数、列数和通道数中必有一个为1;其余二者必有一个与checkVector的输入参数一致)
public Mat clone() {} 克隆Mat
public Mat col(int x) {} 创建一个具有指定了矩阵头中列数这个参数的矩阵
public Mat colRange(int startcol, int endcol) {} 为指定的列范围创建一个矩阵头
public Mat colRange(Range r) {} 为指定的列范围创建一个矩阵头
public int dims() {} 矩阵的维度
public int cols() {} 矩阵的列数
public void convertTo(Mat m, int rtype, double alpha, double beta) {} 在缩放或不缩放的情况下转换为另一种数据类型
public void convertTo(Mat m, int rtype, double alpha) {} 在缩放或不缩放的情况下转换为另一种数据类型
public void convertTo(Mat m, int rtype) {} 在缩放或不缩放的情况下转换为另一种数据类型
public void copyTo(Mat m) {} 把矩阵复制到另一个矩阵中
public void copyTo(Mat m, Mat mask) {} 把矩阵复制到另一个矩阵中(mask为操作掩码。它的非零元素表示矩阵中某个要被复制)
public void create(int rows, int cols, int type) {} 创建矩阵,指定行数,列数和类型
public void create(Size size, int type) {} 创建矩阵,指定大小和类型
public void create(int[] sizes, int type) {} 创建矩阵,指定行数,列数和类型
public void copySize(Mat m) {} 赋值m矩阵的大小
public Mat cross(Mat m) {} 计算3元素向量的一个叉乘积
public long dataAddr() {} 数据地址
public int depth() {} 矩阵的深度
public Mat diag(int d) {} 提取或创建矩阵对角线
public Mat diag() {} 提取或创建矩阵对角线
public static Mat diag(Mat d) {} 提取或创建矩阵对角线
public double dot(Mat m) {} 计算两向量的点乘
public long elemSize() {} 计算Mat中单个像素点所占的字节数(与通道数有关)
public long elemSize1() {} 计算depth所占的字节数(与通道数无关)
public boolean empty() {} 是否为空
public static Mat eye(int rows, int cols, int type) {} 返回一个恒等指定大小和类型矩阵
public static Mat eye(Size size, int type) {} 返回一个恒等指定大小和类型矩阵
public Mat inv(int method) {} 反转矩阵
public Mat inv() {} 反转矩阵
public boolean isContinuous() {} 判断矩阵是否连续
public boolean isSubmatrix() {} 判断矩阵是否为另外一个矩阵的子矩阵
public void locateROI(Size wholeSize, Point ofs) {} 父矩阵内定位矩阵头
public Mat mul(Mat m, double scale) {} 执行两个矩阵按元素相乘或这两个矩阵的除法(scale为可选缩放系数)
public Mat mul(Mat m) {} 执行两个矩阵按元素相乘或这两个矩阵的除法
public static Mat ones(int rows, int cols, int type) {} 返回一个指定的大小和类型的全为1的数组
public static Mat ones(Size size, int type) {} 返回一个指定的大小和类型的全为1的数组
public static Mat ones(int[] sizes, int type) {} 返回一个指定的大小和类型的全为1的数组
public void push_back(Mat m) {} 在矩阵末尾添加矩阵
public void release() {} 释放内存
public Mat reshape(int cn, int rows) {} 在无需复制数据的前提下改变2D矩阵的形状和通道数或其中之一
public Mat reshape(int cn) {} 在无需复制数据的前提下改变2D矩阵的形状和通道数或其中之一
public Mat reshape(int cn, int[] newshape) {} 在无需复制数据的前提下改变2D矩阵的形状和通道数或其中之一
public Mat row(int y) {} 创建一个指定行数的矩阵头
public Mat rowRange(int startrow, int endrow) {} 为指定的行范围创建一个新的矩阵头
public Mat rowRange(Range r) {} 为指定的行范围创建一个新的矩阵头
public int rows() {} 行数
public Mat setTo(Scalar s) {} 将阵列中所有的或部分的元素设置为指定的值
public Mat setTo(Scalar value, Mat mask) {} 将阵列中所有的或部分的元素设置为指定的值
public Mat setTo(Mat value, Mat mask) {} 将阵列中所有的或部分的元素设置为指定的值
public Mat setTo(Mat value) {} 将阵列中所有的或部分的元素设置为指定的值
public Size size() {} 矩阵的大小
public int size(int i) {} 返回第i个矩阵的大小
public long step1(int i) {} 每一维元素的通道数
public long step1() {} 第一维元素的通道数
public Mat submat(int rowStart, int rowEnd, int colStart, int colEnd) {} 返回指定范围内子矩阵
public Mat submat(Range rowRange, Range colRange) {} 返回指定范围内子矩阵
public Mat submat(Range[] ranges) {} 返回指定范围内子矩阵
public Mat submat(Rect roi) {} 返回指定范围内子矩阵
public Mat t() {} 转置矩阵
public long total() {} 返回数组元素总数
public int type() {} 矩阵的类型
public static Mat zeros(int rows, int cols, int type) {} 返回一个指定的大小和类型的全为0的数组
public static Mat zeros(Size size, int type) {} 返回一个指定的大小和类型的全为0的数组
public static Mat zeros(int[] sizes, int type) {} 返回一个指定的大小和类型的全为0的数组
protected void finalize() {} 析构方法
public String toString() {} toString方法
public String dump() {} dump数组
public int put(int row, int col, double… data) {} 赋值
public int put(int[] idx, double… data) {} 赋值
public int put(int row, int col, float[] data) {}
public int put(int row, int col, int[] data) {}
public int put(int row, int col, short[] data) {}
public int put(int row, int col, byte[] data) {}
赋值
public int put(int[] idx, float[] data) {}
public int put(int[] idx, int[] data) {}
public int put(int[] idx, short[] data) {}
public int put(int[] idx, byte[] data) {
赋值
public int put(int row, int col, byte[] data, int offset, int length) {} 赋值
public int put(int[] idx, byte[] data, int offset, int length) {} 赋值
public int get(int row, int col, byte[] data) {}
public int get(int row, int col, short[] data) {}
public int get(int row, int col, int[] data) {}
public int get(int row, int col, float[] data) {}
public int get(int row, int col, double[] data) {}
取值
public int get(int[] idx, byte[] data) {}
public int get(int[] idx, short[] data) {}
public int get(int[] idx, int[] data) {}
public int get(int[] idx, float[] data) {}
public int get(int[] idx, double[] data) {}
取值
public double[] get(int row, int col) {} 取值
public double[] get(int[] idx) {} 取值
方法 使用
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列对应元素乘积之和。

img

img

img

矩阵除法

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

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

矩阵求逆:设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()
    }
       
    override fun onDestroy() {
        source.release()
        bgr.release()
        super.onDestroy()
    }
}

运行结果

按位非

按位与

按位或

按位异或

矩阵加法

矩阵减法

矩阵乘法

矩阵除法

源码

https://github.com/onlyloveyd/LearningAndroidOpenCV

扫描左方二维码关注持续更新

onlyloveyd CSDN认证博客专家 Android Kotlin OpenCV
个人公众号【Android or OpenCV】,热爱Android、Kotlin、Flutter和OpenCV。毕业于华中科技大学计算机专业,曾就职于华为武汉研究所。目前在三线小城市生活,专注技术与研发。
©️2020 CSDN 皮肤主题: 数字20 设计师: CSDN官方博客 返回首页
实付0元
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值