OpenCV入门教程01.09:常用类

索引地址:系列索引

Mat

Mat对象是OpenCV中最常用的一种数据结构,它是一个容器,存储任何通道任何数值的图片数据。简单来说,它是放在内存中的JPG图片。使用完成后,内存自动释放。

Mat()对象的六种创建方法和用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
#include "opencv2/highgui/highgui.hpp"
#include <iostream>

int main() {
// 方法1:创建无初始化矩阵
cv::Mat image1;
// 方法2:创建6行6列类型为8位单通道矩阵
cv::Mat image2(6, 6, CV_8UC1);
// 方法3:创建大小为7x7类型为8位3通道矩阵
cv::Mat image3(cv::Size(7, 7), CV_8UC3);
// 方法4:创建一个用1+3j填充的 8x8 复矩阵
cv::Mat image4(8, 8, CV_32FC2, cv::Scalar(1, 3));
// 方法5:创建大小为 9x9 类型为8位3通道矩阵
cv::Mat image5(cv::Size(9, 9), CV_8UC3, cv::Scalar(1, 2, 3));
//方法6:创建以image2赋值给image6,共用数据对象
cv::Mat image6(image2);
// 输出矩阵结果
std::cout << image1 << std::endl;
std::cout << image2 << std::endl;
std::cout << image3 << std::endl;
std::cout << image4 << std::endl;
std::cout << image5 << std::endl;
std::cout << image6 << std::endl;

cv::Mat Image1(10, 8, CV_8UC1, cv::Scalar(5));
// 矩阵行列数获取
std::cout << "Image1 row: " << Image1.rows << std::endl;
std::cout << "Image1 col: " << Image1.cols << std::endl;
// 取指定行列元素
std::cout << Image1.rowRange(1, 3) << std::endl;
std::cout << Image1.colRange(2, 4) << std::endl;
// 创建 8X8 复数矩阵1+5j
cv::Mat Image2(8, 8, CV_32FC2, cv::Scalar(1, 5));
// 利用create方法重新创建 10X10的8位无符号3通道矩阵
Image2.create(10, 10, CV_8UC(3));
std::cout << "Image2 channels:" << Image2.channels() << std::endl;
// 矩阵类型转换
Image2.convertTo(Image2, CV_32F);
std::cout << "Image2 depth:" << Image2.depth() << std::endl;
// zeros 创建矩阵
cv::Mat Image3 = cv::Mat::zeros(Image2.rows, Image2.cols, CV_8UC1);
// srcImage1的第4行元素变换成srcImage1的第5行元素乘2
Image1.row(4) = Image1.row(5) * 2;
std::cout << Image1 << std::endl;
// 创建srcImage4矩阵赋值为srcImage1的第4列
cv::Mat Image4 = Image1.col(4);
std::cout << Image4 << std::endl;
// 创建srcImage1矩阵的第一列拷贝到srcImage4中
Image1.col(1).copyTo(Image4);
std::cout << Image4 << std::endl;

return 0;
}

终端输出为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
[]
[ 48, 48, 48, 48, 58, 48;
48, 47, 48, 48, 48, 48;
58, 48, 48, 58, 49, 53;
46, 48, 47, 48, 48, 48;
48, 58, 48, 51, 58, 48;
48, 46, 48, 47, 117, 115]
[ 83, 66, 95, 67, 76, 65, 83, 83, 95, 70, 82, 79, 77, 95, 68, 65, 84, 65, 66, 65, 83;
69, 61, 72, 117, 98, 0, 69, 0, 73, 68, 95, 85, 83, 66, 95, 80, 82, 79, 84, 79, 67;
79, 76, 95, 70, 82, 79, 77, 95, 68, 65, 84, 65, 66, 65, 83, 69, 61, 70, 117, 108, 108;
32, 115, 112, 101, 101, 100, 32, 40, 111, 114, 32, 114, 111, 111, 116, 41, 32, 104, 117, 98, 0;
69, 0, 73, 68, 95, 86, 69, 78, 68, 79, 82, 95, 70, 82, 79, 77, 95, 68, 65, 84, 65;
66, 65, 83, 69, 61, 76, 105, 110, 117, 120, 32, 70, 111, 117, 110, 100, 97, 116, 105, 111, 110;
0, 69, 0, 73, 68, 95, 77, 79, 68, 69, 76, 95, 70, 82, 79, 77, 95, 68, 65, 84, 65]
[1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3, 1, 3]
[ 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
[ 48, 48, 48, 48, 58, 48;
48, 47, 48, 48, 48, 48;
58, 48, 48, 58, 49, 53;
46, 48, 47, 48, 48, 48;
48, 58, 48, 51, 58, 48;
48, 46, 48, 47, 117, 115]
Image1 row: 10
Image1 col: 8
[ 5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5]
[ 5, 5;
5, 5;
5, 5;
5, 5;
5, 5;
5, 5;
5, 5;
5, 5;
5, 5;
5, 5]
Image2 channels:3
Image2 depth:5
[ 5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
10, 10, 10, 10, 10, 10, 10, 10;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5;
5, 5, 5, 5, 5, 5, 5, 5]
[ 5;5;5;5;10;5;5;5;5;5]
[ 5;5;5;5;10;5;5;5;5;5]

感兴趣区域

ROI(region of interest),感兴趣区域。机器视觉、图像处理中,从被处理的图像以方框、圆、椭圆、不规则多边形等方式勾勒出需要处理的区域,称为ROI。在Halcon、OpenCV、Matlab等机器视觉软件上常用到各种算子(Operator)和函数来求得ROI,并进行图像的下一步处理。

简单来说,我需要的就是ROI,可以是算法算出来的,也可以是我指定的一片区域。

测试代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
// 功能:代码 2-20 Rect 选择感兴趣区域
// 作者:朱伟 zhu1988wei@163.com
// 来源:《OpenCV图像处理编程实例》
// 博客:http://blog.csdn.net/zhuwei1988
// 更新:2016-8-1
// 说明:版权所有,引用或摘录请联系作者,并按照上面格式注明出处,谢谢。//
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
// 全局变量源图像
cv::Mat srcImage;
// 方法1 利用Rect选择区域(100, 180, 150, 50)
void regionExtraction(int xRoi, int yRoi, int widthRoi, int heightRoi) {
// 指定坐标区域提取
cv::Mat roiImage(srcImage.rows, srcImage.cols, CV_8UC3);
std::cout << srcImage.rows << " " << srcImage.cols << std::endl;
// 将兴趣区域拷贝到目标图像
srcImage(cv::Rect(xRoi, yRoi, widthRoi, heightRoi)).copyTo(roiImage);
cv::imshow("roiImage", roiImage);
cv::waitKey(0);
}
int main() {
// 源图像载入及判断
srcImage = cv::imread("lena.jpg");
if (!srcImage.data)
return 1;
cv::imshow("ROIing", srcImage);
cv::waitKey(0);
// 方法1 利用Rect选择区域(100, 180, 150, 50)
int xRoi = 80;
int yRoi = 180;
int widthRoi = 150;
int heightRoi = 100;
regionExtraction(xRoi, yRoi, widthRoi, heightRoi);
return 0;
}

测试结果:

roi

多张图片合并显示

imshow行数一次只能显示一个Mat对象,一个Mat对象对应一张图片,如果需要显示多张图片,就需要一些操作。最常用的操作是将图片缩小然后利用roi原理移至对应的位置,这样就是在一个Mat中有多个Mat数据,再用imshow显示这一个Mat。

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <opencv2/opencv.hpp>
#include <iostream>

using namespace cv;

void showManyImages(const std::vector<cv::Mat> &srcImages,
cv::Size imgSize)
{
int nNumImages = srcImages.size();
cv::Size nSizeWindows;
if (nNumImages > 12)
{
std::cout << " Not more than 12 images!" << std::endl;
return;
}
// 根据图片序列数量来确定分割小窗口形态
switch (nNumImages)
{
case 1:
nSizeWindows = cv::Size(1, 1);
break;
case 2:
nSizeWindows = cv::Size(2, 1);
break;
case 3:
case 4:
nSizeWindows = cv::Size(2, 2);
break;
case 5:
case 6:
nSizeWindows = cv::Size(3, 2);
break;
case 7:
case 8:
nSizeWindows = cv::Size(4, 2);
break;
case 9:
nSizeWindows = cv::Size(3, 3);
break;
default:
nSizeWindows = cv::Size(4, 3);
break;
}
// 设置小图像尺寸,间隙,边界
int nShowImageSize = 200;
int nSplitLineSize = 15;
int nAroundLineSize = 50;
// 创建输出图像,图像大小根据输入源确定
const int imagesHeight = nShowImageSize * nSizeWindows.width +
nAroundLineSize + (nSizeWindows.width - 1) * nSplitLineSize;
const int imagesWidth = nShowImageSize * nSizeWindows.height +
nAroundLineSize + (nSizeWindows.height - 1) * nSplitLineSize;
std::cout << imagesWidth << " " << imagesHeight << std::endl;
cv::Mat showWindowImages(imagesWidth, imagesHeight,
CV_8UC3, cv::Scalar(0, 0, 0));
// 提取对应小图像的左上角坐标X,Y
int posX = (showWindowImages.cols - (nShowImageSize *
nSizeWindows.width +
(nSizeWindows.width - 1) *
nSplitLineSize)) /
2;
int posY = (showWindowImages.rows - (nShowImageSize *
nSizeWindows.height +
(nSizeWindows.height - 1) *
nSplitLineSize)) /
2;
std::cout << posX << " " << posY << std::endl;
int tempPosX = posX;
int tempPosY = posY;
// 将每一小幅图像整合大图像
for (int i = 0; i < nNumImages; i++)
{
// 小图像坐标转换
if ((i % nSizeWindows.width == 0) && (tempPosX != posX))
{
tempPosX = posX;
tempPosY += (nSplitLineSize + nShowImageSize);
}
// 利用Rect区域将小图像置于大图像相应区域
cv::Mat tempImage = showWindowImages(cv::Rect(tempPosX,
tempPosY, nShowImageSize, nShowImageSize));
// 利用resize函数实现图像缩放
resize(srcImages[i], tempImage,
cv::Size(nShowImageSize, nShowImageSize));
tempPosX += (nSplitLineSize + nShowImageSize);
}
cv::imshow("show Images", showWindowImages);
imwrite("result.jpg",showWindowImages);
}

int main()
{
// 图像源输入
std::vector<cv::Mat> srcImages(9);
srcImages[0] = cv::imread("lenna.jpg");
srcImages[1] = cv::imread("lenna.jpg");
srcImages[2] = cv::imread("lenna.jpg");
srcImages[3] = cv::imread("lenna.jpg");
srcImages[4] = cv::imread("lenna.jpg");
srcImages[5] = cv::imread("lenna.jpg");
srcImages[6] = cv::imread("lenna.jpg");
srcImages[7] = cv::imread("lenna.jpg");
srcImages[8] = cv::imread("lenna.jpg");
// 判断当前vector读入的正确性
for (int i = 0; i < srcImages.size(); i++)
{
if (!srcImages[i].data)
{
std::cout << "read error!" << std::endl;
return -1;
}
}
// 调用单窗口显示图像
showManyImages(srcImages, cv::Size(512, 400));
cv::waitKey(0);
return 0;
}

运行结果:

multi

颜色通道

所谓通道,即路。每条路上有不同的数据,如果只有一条路(单通道)就组成二值图,即值只有0和255;如果是三通道,由R(ed)G(reen)B(lue)组成,就成了最常见的彩色图,三通道也有可能是其他组成,比如YUV。

OpenCV中颜色通道由CV_8UC1等表示:8表示数据有8位(00000000);UC表示unsigned char,即无符号整数,那么数据值为0-255;1表示1通道。CV_8UC1表示一张灰度图。float是32位的,对应数据结构参数就是:CV_32FC1,CV_32FC2,CV_32FC3…double是64位,对应数据结构参数:CV_64FC1,CV_64FC2,CV_64FC3等。

以上是最常用的RGB表示法,还有HVI表示法等等。如果不同通道类型的图片需要转换使用,使用函数cvColor()。

cvtColor()

函数作用:转换图像的颜色,彩色-灰度,HSV 等等

函数调用形式:

1
void cvtColor(InputArray src, OutputArray dst, int code, int dstCn=0 );

参数说明:

  • InputArray src:输入图像
  • OutputArray dst:输出图像
  • int code:表示图像转换的类型;<彩色图像—灰度图像>CV_RGB2GRAY,CV_BGR2YCrCb, CV_RGB2YCrCb, CV_YCrCb2BGR, CV_YCrCb2RGB,CV_BGR2HSV, CV_RGB2HSV, CV_HSV2BGR, CV_HSV2RGB
  • int dstCn=0:表示输出图像的通道,如果是0表示跟输入图像的通道数一样

测试代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "opencv2/opencv.hpp"
using namespace cv;

int main() {
/// 读取一副图片,不改变图片本身的颜色类型(该读取方式为DOS运行模式)
Mat src = imread("lena.jpg", 1);
Mat src_gray;

/// 将图片转换成灰度图片
cvtColor(src, src_gray, COLOR_RGB2GRAY);
imshow("gray", src_gray);
waitKey(0);
return 0;
}

效果:

gray

Scalar

函数原型:

1
Scalar_ (_Tp v0, _Tp v1, _Tp v2=0, _Tp v3=0);

默认四个参数,其中两个是有默认值的,分别对应RGBA四个参数。通过其可以设置一个颜色。

默认使用方法是:

1
Mat M(7,7,CV_32FC2,Scalar(1,3));

上面的代码表示:创建一个2通道,且每个通道的值都为(1,3),深度为32,7行7列的图像矩阵。CV_32F表示每个元素的值的类型为32位浮点数,C2表示通道数为2,Scalar(1,3)表示对矩阵每个元素都赋值为(1,3),第一个通道中的值都是1,第二个通道中的值都是3。

测试代码1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;
void scalar_demo1(){
Mat M(4,4,CV_32FC2,Scalar(1,3));
cout<<M<<endl;
}
void scalar_demo2(){
Mat M(4,4,CV_32FC3,Scalar(1,2,3));
cout<<M<<endl;
}
void scalar_demo3(){
Mat M(4,4,CV_32FC4,Scalar(1,2,3));
cout<<M<<endl;
}
int main(void)
{
scalar_demo1();
cout<<"**********************************"<<endl;
scalar_demo2();
cout<<"**********************************"<<endl;
scalar_demo3();
return 0;
}

编译运行以上代码输出如下,可以发现最后一个矩阵是4通道的,但是我们在初始化的时候只给出了三个通道的值,所以第四个通道的值都默认为0。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
$ ./scalar
[1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3;
1, 3, 1, 3, 1, 3, 1, 3]
**********************************
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3;
1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
**********************************
[1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0;
1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0]

测试代码2:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/imgproc/imgproc.hpp>

using namespace std;
using namespace cv;

int main(void)
{
Mat blue_m(256,256,CV_8UC3,Scalar(255,0,0));
Mat green_m(256,256,CV_8UC3,Scalar(0,255,0));
Mat red_m(256,256,CV_8UC3,Scalar(0,0,255));
imshow("Blue",blue_m);
waitKey(0);
imshow("Green",green_m);
waitKey(0);
imshow("Red",red_m);
waitKey(0);

return 0;
}

编译之后再终端运行,点击一次之后显示一张结果,连点三下之后显示三个结果,点击第四下自动关闭运行界面。

rgb

相信读到这你已经明白Scalar是用来干什么的了,它将各个通道的值构成一个整体,赋给具有相同通道数的矩阵元素。

Rect()

一个矩形对象,是一个面,面由点组成。最基本的包括x,y,width,height,即在x轴起点(一般为0)y轴起点(一般为0)宽度和高度。

此对象还有面积,是否包含点等。

函数原型:

1
typedef Rect_<int> Rect;

也就是说Rect()是用int类型实例化的Rect_,那么我们具体看一下Rect_的函数原型。

1
2
3
4
5
6
Rect_();//形参列表为空,即定义一个空窗口(默认值为:x=y=width=height=0);
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);//定义一个左上角点坐标为(_x, _y)的_width*_height矩形窗口;
Rect_(const Rect_& r);//使用其他的Rect_对象初始化;
Rect_(const CvRect& r);//使用CvRect对象初始化;
Rect_(const Point_<_Tp>& org, const Size_<_Tp>& sz);//分别将位置坐标(_x, _y)和窗口大小(_width, _height)用Point_和Size_对象初始化;
Rect_(const Point_<_Tp>& pt1, const Point_<_Tp>& pt2);//分别将坐标位置(_x, _y)和窗口大小(_width, _height)用Point_和Point_对象初始化。

就是一个面最基本的,左上角x,y的起始点,然后是宽度和高度。可以用于指定上图中的黑色方框。也就是说,可以用于获取一张图片中某个子图片。

CvRect和Rect有什么区别呢?没什么区别,CvRect是C的函数,Rect是C++。

以下是Rect的常用用法:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include <iostream>
#include <opencv2/opencv.hpp>
#include <vector>

using namespace std;
using namespace cv;

int main() {
Mat image = imread("lena.jpg");
Rect rect1(256, 256, 128, 128);
Rect rect2(224, 224, 128, 128);

Mat roi1;
image(rect1).copyTo(roi1); // 将image中rect1的部分复制到roi1中
imshow("1", roi1);
waitKey(0);

Mat roi2;
image(rect2).copyTo(roi2); // 将image中rect2复制到roi2中
imshow("2", roi2);
waitKey(0);

cv::Rect rect3 = rect1 & rect2; // rect1和rect2的交集
Mat roi3;
image(rect3).copyTo(roi3);
imshow("3", roi3);
waitKey(0);

Rect rect4 = rect1 | rect2; // rect1和rect2的并集(两幅图的最小外接矩形)
Mat roi4;
image(rect4).copyTo(roi4);
imshow("4", roi4);
waitKey(0);

Rect rect5(10, 10, 128, 128);
roi1.copyTo(image(rect5)); // 将rect1复制到image的指定区域rect5中
imshow("5", image);
waitKey(0);
}

测试效果如图:

rect

两幅图像的&|操作之后在介绍。

Size()

查询Size()的官方参考手册可得:

1
2
typedef Size2i cv::Size;
typedef Size_<int> cv::Size2i;

查看Size_<_TP>详细信息:

1
2
3
4
5
Size_ ();//默认构造函数
Size_ (_Tp _width, _Tp _height);//通过宽高来指定尺寸
Size_ (const Size_ &sz);//通过已有的尺寸来获得新的尺寸
Size_ (Size_ &&sz) CV_NOEXCEPT
Size_ (const Point_< _Tp > &pt)

除了构造函数之外,还有公有属性,重载运算符函数,以及一些属性函数等等。size表示一张图片的尺寸,即宽(width/cols)高(height/rows)。

此对象还可以获取图片面积(宽×高),长宽比(宽/高),是否是空图片等等。

对于OpenCV4来说,我们关心的只是其最基本的属性,宽高,有可能用到面积等。

Point()

Point()函数用于描述图片上面的二维点,比如Point(0,0)表示左上角的坐标原点。

下图为OpenCV坐标系,右横向为x轴正向。

使用方法1:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <iostream>
#include <vector>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main(){
Point2f p(6, 2);
cout << "【2维点】p = " << p << ";\n" << endl;

Point3f p3f(8, 2, 0);
cout << "【3维点】p3f = " << p3f << ";\n" << endl;

vector<float> v;
v.push_back(3);
v.push_back(5);
v.push_back(7);

vector<Point2f> points(20);
for (size_t i = 0; i < points.size(); ++i)
points[i] = Point2f((float)(i * 5), (float)(i % 7));

cout << "【二维点向量】points = " << points<<";";
}

测试输出为:

1
2
3
4
5
2维点】p = [6, 2];

3维点】p3f = [8, 2, 0];

【二维点向量】points = [0, 0; 5, 1;10, 2; 15, 3; 20, 4; 25, 5; 30, 6; 35, 0; 40, 1; 45, 2; 50, 3; 55, 4; 60, 5; 65, 6; 70, 0; 75, 1; 80, 2; 85, 3; 90, 4; 95, 5];%

输出中的百分号表示终端输出结束。

使用方法2:操作图片上面的某个点。

在后续介绍中在说。


OpenCV入门教程01.09:常用类
https://blog.jackeylea.com/opencv/opencv-useful-class/
作者
JackeyLea
发布于
2025年1月11日
许可协议