专栏简介 | ||
💒个人主页 📰专栏目录 点击上方查看更多内容 | 📖心灵鸡汤📖 我们唯一拥有的就是今天,唯一能把握的也是今天 建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫 | 🧭文章导航🧭 ⬆️ 5.Mat之像素读写 ⬇️ 7.待更新 |
Mat之范围读写
- 一、🌳Range类
- 1.构造函数
- 2.方法介绍
- 1.all()
- 2.intersection(Range r1)
- 3.set(double[] vals)
- 4.shift(int delta)
- 5.size()
- 二、🌳Rect类
- 1.构造函数
- 2.方法介绍
- 1.area()
- 2.contains(Point p)
- 3.br()
- 4.tl()
- 5.size()
- 三、🌳矩阵范围读写
- 1.col(int x)
- 2.colRange
- 3.row(int y)
- 4.rowRange
- 5.diag
- 6.submat
- 四、🌳感兴趣区域
- 1.adjustROI
- 2.locateROI
- 五、其它函数
- 1.isSubmatrix()
- 2.channels()
- 3.checkVector
- 4.cols()
- 5.dataAddr()
- 6.depth()
- 7.dims()
- 8.dump()
- 9.elemSize()
- 10.elemSize1()
- 11. empty()
- 12.finalize()
- 13.getNativeObjAddr()
- 14.height()
- 15. isContinuous()
- 16.release()
- 17.rows()
- 18.size()
- 19. size(int i)
- 20.step1()
- 21.step1(int i)
- 22.total()
- 23.type()
- 24.width()
在之前先了解下Range类和 Rect类
一、🌳Range类
Range类用于表示一个范围(一个连续的数值范围),并用于选择图像或矩阵的子区域。
1.构造函数
这里仅解释下构造函数,就不代码举例了。
1.
Range(double[] vals) |
vals | 一个包含两个元素的double数组,分别表示范围的起始值和结束值 |
Range(int s, int e) |
s | 范围的起始值 |
e | 范围的结束值 |
2.方法介绍
这里仅列举部分,简单直接的函数就不列举了
1.all()
返回一个表示整个范围的Range对象。换句话说,它返回一个从负无穷到正无穷的范围。
System.out.println("Range.all() = " + Range.all());
结果
Range.all() = [-2147483648, 2147483647)
2.intersection(Range r1)
计算两个Range对象的交集,并返回一个新的Range对象表示交集部分。
1.如果两个Range对象有交集,则返回一个新的Range对象,该对象的start为两个Range对象中start值较大的那个,end为两个Range对象中end值较小的那个。
2.如果两个Range对象没有交集,则返回一个start值为两个对象中最大的值,end值也为两个对象中最大的值的一个Range对象(ps或者说无交集是返回一个空的Range对象,这里所说的空Range对象并不是代表Range对象是空的,而是指Range对象没有范围或范围是0
)
public class IntersectionExample {public static void main(String[] args) {Range range1 = new Range(1,5);Range range2 = new Range(3,7);Range intersection = range1.intersection(range2);System.out.println("intersection.toString() = " + intersection.toString());}
}
请自行验证
3.set(double[] vals)
设置Range对象的范围。vals包含两个元素的数组,分别表示范围的起始值和结束值。
4.shift(int delta)
调整Range对象的范围,使其向右或向左移动
public static void main(String[] args) {Range range = new Range(4,8);System.out.println("range = " + range);//向右移动2位Range shift_r = range.shift(2);System.out.println("shift_r = " + shift_r);//向左移动4位Range shift_l = shift_r.shift(-4);System.out.println("shift_l = " + shift_l);}
5.size()
返回范围的大小,即范围内的元素数量。
二、🌳Rect类
Rect类的作用包括: 表示矩形区域的位置和大小:Rect类包含了四个整型成员变量x、y、width和height,分别表示矩形区域的左上角点的x坐标、y坐标,以及矩形区域的宽度和高度。 用于图像处理和计算机视觉算法:在OpenCV中,Rect类常常用于表示图像中的感兴趣区域(Region of Interest,ROI),即在图像中选择一个矩形区域进行特定的操作,如图像裁剪、目标检测、特征提取等。 作为其他类的参数和返回值:Rect类常常作为其他OpenCV函数和类的参数和返回值,用于传递和获取矩形区域的位置和大小信息。 |
1.构造函数
Point 和Size类之前我们已经了解过了,这里就不再介绍相关类了。
我这里只解释下部分构造函数。
1.
Rect(double[] vals) |
vals | 包含四个 double 值的数组,分别表示矩形的左上角 x 坐标、左上角 y 坐标、宽度和高度 |
//创建Rect对象,使用valsdouble vals[] ={0,1,4,4};Rect rect = new Rect(vals);//Rect rect = new Rect(0,1,4,4);System.out.println("rect = " + rect);
- 其中p1和p2分别表示矩形的对角线的两个顶点
Rect(Point p1, Point p2) |
p1 | 顶点1 |
p2 | 顶点2 |
Point point1 = new Point(1,2);Point point2 =new Point(5,5);Rect rect_p = new Rect(point1,point2);System.out.println("rect_p = " + rect_p);
2.方法介绍
只列举部分,不列举不代表不重要!!!
1.area()
计算矩形区域的面积。该方法返回一个double类型的值,面积的计算是通过矩形的宽度和高度相乘得到的。
2.contains(Point p)
判断一个点是否在一个矩形区域内部
//创建一个矩形Rect rect = new Rect(0,0,100,100);boolean contains = rect.contains(new Point(11, 11));System.out.println("contains = " + contains);
如果给定的点p在矩形内部,则返回true。如果给定的点p在矩形外部,则返回false。
3.br()
返回矩形的右下角点的坐标,以Point对象的形式返回
4.tl()
返回矩形的左上角顶点的坐标,以Point对象的形式返回
5.size()
返回矩形的大小。它返回一个Size对象,该对象包含矩形的宽度和高度信息。
三、🌳矩阵范围读写
请自行验证示例结果
1.col(int x)
返回一个包含矩阵的第x列数据的新的Mat对象。这个新的Mat对象将会是一个单列矩阵,其中包含了矩阵的第x列的所有元素。
Mat mat = new Mat(3,3,CvType.CV_8UC1);//设置值mat.put(0,0,1,2,3,4,5,6,7,8,9);//获取第二列值Mat col = mat.col(1);//打印结果System.out.println("mat.dump() = \n" + mat.dump());System.out.println("col.dump() = \n" + col.dump());
2.colRange
获取矩阵的指定列范围。
1.
colRange(int startcol, int endcol) |
startcol | 起始列的索引(包含在范围内) |
endcol | 结束列的索引(不包含在范围内) |
Mat mat = new Mat(3,3,CvType.CV_8UC1);//设置值mat.put(0,0,1,2,3,4,5,6,7,8,9);//获取第一列到第三列之间的Mat对象,不包含第三列Mat colRange = mat.colRange(0, 2);//打印结果System.out.println("mat.dump() = \n" + mat.dump());System.out.println("col.dump() = \n" + colRange.dump());
2.获取矩阵的指定列范围
colRange(Range r) |
r | Range范围的对象,可以使用Range类的构造函数指定范围,例如new Range(0, 2)表示提取第一列到第三列的范围 |
3.row(int y)
回一个包含矩阵的第y行数据的新的Mat对象。这个新的Mat对象将会是一个单行矩阵,其中包含了矩阵的第y行的所有元素。
4.rowRange
参考colRange
5.diag
返回矩阵的对角线元素。
1.diag()
diag()方法用于返回一个包含矩阵对角线元素的列向量。该方法返回的矩阵的行数等于列数 |
Mat mat = new Mat(3,3,CvType.CV_8UC1);//设置值mat.put(0,0,1,2,3,4,5,6,7,8,9);Mat diag = mat.diag();System.out.println("diag.dump() = \n" + diag.dump());
2.返回矩阵的对角线元素
diag(int d) |
d | 对角线的索引。当d为正数时,表示获取主对角线元素;当d为负数时,表示获取副对角线元素 |
// 创建一个3x3的矩阵Mat mat = new Mat(3, 3, CvType.CV_32F);mat.put(0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9);System.out.println("mat.dump(): \n" + mat.dump());// 获取主对角线元素Mat diag = mat.diag(0);System.out.println("主对角线元素:");System.out.println(diag.dump());// 获取副对角线元素Mat subDiag = mat.diag(-1);System.out.println("副对角线元素:");System.out.println(subDiag.dump());
3.diag(Mat d)
这个函数和上面两个不一样的操作,这个函数用于创建对角矩阵 |
d | 用于创建对角矩阵的矩阵 |
// 创建一个1x3的矩阵Mat d = new Mat(1, 3, CvType.CV_32F);d.put(0, 0, 1);d.put(0, 1, 2);d.put(0, 2, 3);System.out.println("d.dump() :\n " + d.dump());// 创建对角矩阵Mat diagMatrix = Mat.diag(d);// 输出对角矩阵System.out.println(diagMatrix.dump());
6.submat
返回当前矩阵的子矩阵.只列举部分
1.
submat(Range rowRange, Range colRange) |
rowRange | 子矩阵在行上的范围 |
colRange | 子矩阵在列上的范围 |
submat(Rect roi) |
roi | 用于指定子矩阵的区域。Rect对象包含四个整数值,分别表示矩形的左上角坐标(x,y)和矩形的宽度和高度(width,height) |
Mat mat = new Mat(3,3,CvType.CV_8UC1);//设置值mat.put(0,0,1,2,3,4,5,6,7,8,9);Mat submat = mat.submat(new Rect(0, 0, 2, 2));System.out.println("submat.dump()= \n" + submat.dump());
四、🌳感兴趣区域
1.adjustROI
调整当前矩阵的感兴趣区域(Region of Interest,ROI),这个方法允许扩大或缩小矩阵的边界。
adjustROI(int dtop, int dbottom, int dleft, int dright) |
dtop | 上边界的调整量。正数表示增加,负数表示减少 |
dbottom | 下边界的调整量。正数表示增加,负数表示减少 |
dleft | 左边界的调整量。正数表示增加,负数表示减少 |
dright | 右边界的调整量。正数表示增加,负数表示减少 |
Mat mat=Mat.eye(5,5, CvType.CV_8UC1);System.out.println("mat:\n"+ mat.dump());// 调整 ROI,移除左右边界的 1 像素,并移除上下的 1 像素Mat roiAdjusted = mat.adjustROI(-1, -1, -1, -1);System.out.println("roiAdjusted:\n"+roiAdjusted.dump());
2.locateROI
获取感兴趣区域在整个图像中的位置和偏移量。(通过子矩阵重建原始矩阵的大小以及提取的子矩阵在原始矩阵中的位置
)
通过调用该方法,可以获取感兴趣区域的位置和偏移量信息,以便在需要时可以将其与其他图像进行对齐或合并等操作。
代码参考:https://docs.opencv.org/4.8.0/d3/d63/classcv_1_1Mat.html#a4b22e1c23af7a7f2eef8fa478cfa7434
locateROI(Size wholeSize, Point ofs) |
wholeSize | 表示整个图像的大小,即包含感兴趣区域的完整图像的尺寸 |
ofs | 表示感兴趣区域在整个图像中的偏移量,即感兴趣区域的左上角在整个图像中的坐标 |
Mat A = Mat.eye(10, 10, CvType.CV_32S);Mat B = A.submat(new Range(0, A.rows()), new Range(1, 3));Mat C = B.submat(new Range(5, 9), new Range(0, B.cols()));Size size = new Size();Point ofs = new Point();C.locateROI(size, ofs);System.out.println("Size: " + size);System.out.println("Offset: " + ofs);
扩展:为了能直观的理解这个函数的作用,我这里整了个示例。这些函数作用目前不必追究,后面的章节中会说到。(自己本地找个图片替换执行下即可看到效果
)
//读取图片Mat imread = Imgcodecs.imread("C:\\Users\\admin\\Pictures\\Camera Roll\\generalized_hough_gui.jpg");//获取部分矩阵Mat submat = imread.submat(new Range(100, 300), new Range(100, 300));//定位//在原图中的偏移量Point point = new Point();submat.locateROI(imread.size(),point);//输出偏移量System.out.println("point = " + point);//绘制在原图中的位置Imgproc.rectangle(imread,new Rect((int) point.x, (int) point.y,submat.width(),submat.height()),new Scalar(255,0,0));//显示HighGui.imshow("submat",submat);HighGui.imshow("imread",imread);HighGui.waitKey();
五、其它函数
请自行验证下方函数,部分函数就不代码举例了
1.isSubmatrix()
检查当前矩阵是否是另一个矩阵的子矩阵
2.channels()
返回图像的通道数
3.checkVector
检查矩阵是否是一个合法的向量
我们以 checkVector(int elemChannels, int depth, boolean requireContinuous)
为例说明下。
checkVector(int elemChannels, int depth, boolean requireContinuous) |
elemChannels | 向量元素的通道数 |
depth | 向量元素的深度 |
requireContinuous | 是否要求向量是连续的 |
public class CheckVectorExample {static {System.loadLibrary(Core.NATIVE_LIBRARY_NAME);}public static void main(String[] args) {// 创建一个3行1列的矩阵,表示一个向量Mat vector = new Mat(3, 1, CvType.CV_8UC1);// 检查向量是否合法int vectorLength = vector.checkVector(1, CvType.CV_8U, false);if (vectorLength != -1) {System.out.println("向量长度为:" + vectorLength);} else {System.out.println("矩阵不是一个合法的向量");}}
}
4.cols()
返回矩阵的列数(宽度)
5.dataAddr()
获取Mat对象的数据存储地址
6.depth()
返回图像的像素深度。像素深度是指图像中每个像素的位数,表示每个像素可以存储的颜色信息的数量。常见的像素深度有8位(灰度图像)、24位(彩色图像)等。
7.dims()
返回矩阵的维度数。
8.dump()
将Mat对象的内容以字符串的形式输出
9.elemSize()
返回每个元素(像素)的大小。返回值取决于矩阵的数据类型。例如,对于一个8位无符号整数的矩阵,每个元素的大小为1字节;对于一个32位浮点数的矩阵,每个元素的大小为4字节。
10.elemSize1()
这个方法返回的是每个元素的字节数。和elemSize()
有点类似。通过下方示例可以看出两者的具体区别。
Mat mat = new Mat(5,5,CvType.CV_8UC2);System.out.println("mat.elemSize() = " + mat.elemSize());System.out.println("mat.elemSize1() = " + mat.elemSize1());
请自行验证,试着改变下数据类型
11. empty()
检查Mat对象是否为空
12.finalize()
释放资源
13.getNativeObjAddr()
获取Mat对象的数据存储地址
14.height()
获取矩阵的高度(行数)
15. isContinuous()
用于检查矩阵是否是连续的
16.release()
释放Mat对象所占用的内存空间
17.rows()
返回矩阵的行数(高度)
18.size()
获取Mat对象的尺寸大小
19. size(int i)
返回Mat对象在指定维度上的大小。
i 表示维度的索引,0表示行数,1表示列数。例如,如果Mat对象是一个3行4列的矩阵,那么调用size(0)将返回3,调用size(1)将返回4 |
20.step1()
返回矩阵的步长(step)。步长是指在内存中,从一个元素到下一个元素的字节数
21.step1(int i)
返回矩阵指定维度上的步长(step)
i 表示维度的索引,0表示行数,1表示列数。 |
22.total()
返回矩阵的总元素数量
23.type()
获取图像的类型值。它表示图像的通道数和数据类型。
类型值由四个部分组成:CV_类型前缀、通道数、深度和符号位。 CV_类型前缀指示了数据类型,例如CV_8U表示8位无符号整数,CV_32F表示32位浮点数。 通道数表示图像的通道数,例如灰度图像只有一个通道,彩色图像有三个通道(BGR)。 深度表示每个像素的位数,例如8位深度表示每个像素使用8位来表示。 符号位表示数据是否有符号,例如无符号整数类型没有符号位。 |
24.width()
获取矩阵的宽度(列数)