专栏简介 | ||
💒个人主页 📰专栏目录 点击上方查看更多内容 | 📖心灵鸡汤📖 我们唯一拥有的就是今天,唯一能把握的也是今天 建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 | 🧭文章导航🧭 ⬆️ 6.Mat之局部区域读写及Range和Rect介绍 ⬇️ 8.Mat之多维元组(Tuple) |
Mat之转换与算法
- 一、转换
- 1.类型转换
- convertTo
- 2.对象转换(转置矩阵)
- t()
- 二、 重塑
- reshape
- 三、计算
- 1.乘积
- 1.矩阵的乘积
- 1.matMul(Mat m)
- 2.逐元素乘积
- 1.mul
- 2.叉积
- cross(Mat m)
- 3.点积(点乘运算)
- dot(Mat m)
- 4.逆矩阵(求逆运算)
- inv(int method)
一、转换
1.类型转换
convertTo
该方法用于将输入的Mat对象转换为指定的数据类型,并进行缩放和平移操作。
convertTo(Mat m, int rtype, double alpha, double beta) | |
参数: | |
m | 输入的矩阵对象 |
rtype | 转换后的Mat对象的数据类型。可以使用 CV_8U、 CV_8S、 CV_16U、 CV_16S、 CV_32F、 CV_64F等 |
alpha | 像素值的缩放因子 |
beta | 像素值的偏移量 |
//转换 类型转化 -用于转换数据类型
Mat mat = new Mat(3,3,CvType.CV_8UC1);
mat.put(0,0,1,2,3,4,0,6,7,8,9);
Mat convertToMat = new Mat();
mat.convertTo(convertToMat,CvType.CV_16F,1,-1 );
System.out.println("mat = " + mat);
System.out.println("convertToMat = \n" + convertToMat);
System.out.println("mat.dump() = \n" + mat.dump());
System.out.println("convertToMat.dump() = \n" + convertToMat.dump());
请自行验证结果
,具体来说,该方法会将输入的Mat对象m转换为指定的数据类型rtype,并应用线性变换,即将每个像素值乘以alpha并加上beta。最后,结果将存储在原始的Mat对象m中。(ps:通过它可以调节图像的亮度,产生一个曝光的效果)
2.对象转换(转置矩阵)
t()
转置矩阵是将原矩阵的行和列互换得到的新矩阵。这个方法返回一个新的Mat对象,其中包含原始矩阵的转置矩阵数据。转置矩阵的行数等于原矩阵的列数,列数等于原矩阵的行数。
Mat mat = new Mat(3,3,CvType.CV_8UC1);
mat.put(0,0,1,2,3,4,5,6,7,8,9);
Mat t = mat.t();
System.out.println("mat.dump() = \n" + mat.dump());
System.out.println("t.dump() = \n" + t.dump());
二、 重塑
reshape
该方法的作用是将矩阵重塑为具有指定通道数的新矩阵。重塑后的矩阵将具有相同的总元素数
,但通道数将改变
。
这个方法在处理图像时非常有用,可以用于改变图像的通道数,例如将RGB图像转换为灰度图像。
部分方法就不代码举例了,请自行验证
1.指定通道数
reshape(int cn) | |
参数: | |
cn | 通道数 |
2.指定通道数和行数
reshape(int cn, int rows) | |
参数: | |
cn | 通道数 |
rows | 新矩阵的行数 |
reshape(int cn, int[] newshape) | |
参数: | |
cn | 通道数 |
rtype | 一个整数数组,指定重塑后的矩阵的行数和列数 |
Mat mat = new Mat(3,3,CvType.CV_8UC2);
System.out.println("mat.() = " + mat.size());
mat.put(0,0,1,2,3,4,5,6,7,8);
System.out.println("mat.dump() = \n" + mat.dump());
int [] newshap={2,3};
Mat reshape = mat.reshape(3,newshap);
System.out.println("reshape = " + reshape);
System.out.println("reshape.dump() = \n" + reshape.dump());
三、计算
1.乘积
1.矩阵的乘积
1.matMul(Mat m)
计算两个矩阵的乘积
matMul(Mat m) | |
参数: | |
m | 另一个Mat对象,表示要与当前矩阵进行乘法运算的矩阵 |
2.逐元素乘积
1.mul
执行逐元素的乘法运算
mul(Mat m, double scale) | |
参数: | |
m | 另一个Mat对象,表示要与当前矩阵进行乘法运算的矩阵 |
scale | 可选的缩放因子,用于在乘法运算后缩放结果矩阵。默认值为 1.0,表示不进行缩放 |
public static void main(String[] args) {
//创建3X3矩阵
Mat mat1=new Mat(new Size(3,3), CvType.CV_32FC1);
mat1.put(0,0,1,2,3,4,5,6,7,8,9);
Mat mat2= new Mat();
//赋值矩阵
mat1.copyTo(mat2);
System.out.println("mat1.dump() :\n" + mat1.dump());
System.out.println("mat2.dump() :\n " + mat2.dump());
Mat mat = mat1.mul(mat2,2);
System.out.println("mat.dump() :\n " + mat.dump());
}
2.叉积
cross(Mat m)
cross 方法用于计算两个 3x1 或者 1x3 向量矩阵的叉积(Cross Product)。这个方法接受一个 Mat 对象作为参数,并返回一个新的 Mat 对象,表示计算得到的叉积结果。
叉积在二维空间中是一个向量运算,但在 OpenCV 中,这个方法用于计算两个三维向量矩阵的叉积。在三维空间中,叉积可以用来表示旋转和方向。
cross 方法要求输入矩阵的尺寸必须为 3x1
3.点积(点乘运算)
dot(Mat m)
计算两个矩阵的点积(内积),返回结果为一个标量值
public static void main(String[] args) {
// 创建两个矩阵
Mat mat1 = new Mat(3, 3, CvType.CV_32F);
mat1.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
Mat mat2 = new Mat(3, 3, CvType.CV_32F);
mat2.put(0, 0, 9, 8, 7, 6, 5, 4, 3, 2, 1);
// 计算两个矩阵的点积
double result = mat1.dot(mat2);
// 打印结果
System.out.println("mat1.dump() :\n " + mat1.dump());
System.out.println("mat2.dump() :\n" + mat2.dump());
System.out.println("Dot product: " + result);
}
4.逆矩阵(求逆运算)
inv(int method)
设A是一个n阶矩阵,若存在另一个n阶矩阵B,使得: AB=BA=E ,则称方阵A可逆,并称方阵B是A的逆矩阵。更多内容请查看
百度学科。
逆矩阵的作用是可以用来解决线性方程组、求解特征值、特征向量、矩阵的对角化等问题。通过计算矩阵的逆矩阵,我们可以求解线性方程组Ax=b的解,其中b是一个列向量,x是未知向量,A是系数矩阵。具体地,如果A是可逆的,则方程组有唯一解x=A^-1b。
仅列举其中一个方法进行说明
Mat inv(int method) | |
参数: | |
method | 计算方法,可以是以下值之一: Core.DECOMP_LU:使用 LU 分解法计算逆矩阵。(默认方法) Core.DECOMP_SVD:使用奇异值分解法计算逆矩阵. 更多查看:Core.DECOMP_ |
该方法仅支持CV_64F和CV_32F类型
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
/**
* @author lvyq
* @version 1.0
* Create by 2023-12-31 9:05
*/
public class InvExample {
static {
String libraryPath = System.getProperty("user.dir") + "\\lib\\opencv_java460.dll";
System.load(libraryPath);
}
public static void main(String[] args) {
// 创建矩阵
Mat mat = new Mat(3, 3, CvType.CV_32FC1);
//矩阵赋值
mat.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
//计算矩阵的逆矩阵
Mat inv = mat.inv(Core.DECOMP_SVD);
System.out.println("mat.dump() :\n " + mat.dump());
System.out.println("inv.dump() :\n " + inv.dump());
}
}