6.java openCV4.x 入门-Mat之局部区域读写及Range和Rect介绍

本文详细介绍了OpenCV中Mat对象的Range类和Rect类,涉及构造函数、常用方法和矩阵范围读写,如col(),colRange(),row(),rowRange(),diag(),submat(),以及兴趣区域的调整和定位。
摘要由CSDN通过智能技术生成
专栏简介

💒个人主页
📰专栏目录

点击上方查看更多内容
📖心灵鸡汤📖

我们唯一拥有的就是今天,唯一能把握的也是今天


建议把本文当作笔记来看,据说专栏目录里面有相应视频🤫
🧭文章导航🧭
⬆️ 5.Mat之像素读写
⬇️ 7.Mat之转换、重塑与计算


   在之前先了解下Range类和 Rect类

一、🌳Range类

   Range类用于表示一个范围(一个连续的数值范围),并用于选择图像或矩阵的子区域。

1.构造函数

   这里仅解释下构造函数,就不代码举例了。
在这里插入图片描述
1.

Range​(double[] vals)
参数:
vals 一个包含两个元素的double数组,分别表示范围的起始值和结束值
2.
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对象,使用vals
        double vals[] ={0,1,4,4};
        Rect rect = new Rect(vals);
        //Rect rect = new Rect(0,1,4,4);
        System.out.println("rect = " + rect);
  1. 其中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 是否要求向量是连续的
如果矩阵是一个合法的向量,则返回向量的长度;否则返回-1

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()

  获取矩阵的宽度(列数)

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

不要喷香水

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值