一、类型 cv::Vec<>
在 OpenCV 中,cv::Vec<> 是一个模板类,用于表示定长向量(fixed-size vector),常用于存储像素值、坐标、颜色等固定数量的值。
1.1 模板定义
template<typename _Tp, int cn>
class Vec;
- _Tp:元素类型,如 uchar、int、float、double 等;
- cn:元素个数(通道数),比如 RGB 就是 3,RGBA 就是 4。
例如:
cv::Vec3b // 表示 uchar 类型的 3 通道向量(比如 RGB 图像的像素)
cv::Vec3f // 表示 float 类型的 3 通道向量(浮点RGB颜色)
cv::Vec4d // 表示 double 类型的 4 通道向量(比如 RGBA)
cv::Vec2i // 表示 int 类型的 2 通道向量(例如二维坐标)
1.2 常见类型列表
1.3 Vec 的基本使用
定义和初始化:
cv::Vec3b color(255, 0, 0); // 红色,uchar 类型
cv::Vec3f colorf = {1.0f, 0.0f, 0.0f}; // 浮点红色
cv::Vec2i pt(10, 20); // 坐标点
访问元素:
cv::Vec3b color(10, 20, 30);
uchar blue = color[0]; // B
uchar green = color[1]; // G
uchar red = color[2]; // R
与 cv::Mat 结合使用(访问像素):
cv::Mat img = cv::imread("test.jpg");
cv::Vec3b pixel = img.at<cv::Vec3b>(100, 200); // 访问100行200列的像素
uchar blue = pixel[0];
uchar green = pixel[1];
uchar red = pixel[2];
支持的操作符:
cv::Vec3f a(1.0f, 2.0f, 3.0f);
cv::Vec3f b(2.0f, 4.0f, 6.0f);
cv::Vec3f c = a + b; // 加法
cv::Vec3f d = b - a; // 减法
cv::Vec3f e = a * 2.0f; // 数乘
float dot = a.dot(b); // 点乘
float len = cv::norm(a); // 求范数(欧几里得长度)
1.4 实际应用示例
示例1:图像反色(按通道逐像素操作)
cv::Mat img = cv::imread("test.jpg");
for (int y = 0; y < img.rows; y++) {
for (int x = 0; x < img.cols; x++) {
cv::Vec3b& pixel = img.at<cv::Vec3b>(y, x);
pixel[0] = 255 - pixel[0]; // B
pixel[1] = 255 - pixel[1]; // G
pixel[2] = 255 - pixel[2]; // R
}
}
示例2:颜色线性变换(加权变换)
cv::Vec3f color(0.1f, 0.2f, 0.3f);
float weight = 2.0f;
cv::Vec3f result = color * weight; // 每个通道乘以权重
1.5 自定义 Vec 类型别名
typedef cv::Vec<uchar, 6> Vec6b; // 自定义 6 通道 uchar 类型向量
typedef cv::Vec<float, 8> Vec8f; // 自定义 8 通道 float 类型向量
二、类型 cv::Matx<>
cv::Matx<> 是 OpenCV 提供的一个固定尺寸矩阵模板类,用于数学运算中表示小型矩阵(比如 2×2、3×3、4×4、6×6 等),适合做变换矩阵(如旋转、缩放、投影),在图像几何变换、相机标定、三维重建等领域广泛使用。
2.1 模板定义
template<typename _Tp, int m, int n>
class Matx;
- _Tp:元素类型,如 float、double 等;
- m:行数;
- n:列数;
2.2 常见类型别名
也可以自定义别名:
typedef cv::Matx<float, 2, 3> Matx23f;
2.3 创建与初始化
构造函数初始化
cv::Matx33f mat1(1, 0, 0,
0, 1, 0,
0, 0, 1); // 单位矩阵
cv::Matx22d mat2(1.5, 2.0,
3.0, 4.5);
使用 zeros()、ones()、eye() 等静态函数
auto m1 = cv::Matx33f::zeros(); // 全 0
auto m2 = cv::Matx22d::ones(); // 全 1
auto m3 = cv::Matx33f::eye(); // 单位矩阵
2.4 基本操作
访问元素
cv::Matx22f mat(1.0f, 2.0f,
3.0f, 4.0f);
float a = mat(0, 1); // 第1行第2列
矩阵乘法
cv::Matx22f A(1, 2, 3, 4);
cv::Matx22f B(5, 6, 7, 8);
cv::Matx22f C = A * B; // 矩阵乘法
与向量相乘
cv::Matx33f R(1, 0, 0,
0, 1, 0,
0, 0, 1);
cv::Vec3f v(1, 2, 3);
cv::Vec3f result = R * v; // 矩阵乘向量
转置与逆
auto R = cv::Matx33f::eye();
auto Rt = R.t(); // 转置
auto Rinv = R.inv(); // 逆矩阵(如果可逆)
三、类型 cv::Point
cv::Point 是 OpenCV 中用于表示二维坐标点的结构,适用于图像处理中的像素坐标、点的位置、几何形状的顶点等场景,是使用非常广泛的基础数据结构之一。
3.1 模板定义
template<typename _Tp> class Point_;
typedef Point_<int> Point; // cv::Point 是 int 类型
typedef Point_<float> Point2f; // 浮点型点
typedef Point_<double> Point2d; // 双精度点
3.2 常见类型
3.3 创建与初始化
cv::Point pt1(100, 50); // 整数坐标点
cv::Point2f pt2(100.5f, 50.2f); // 浮点坐标点
cv::Point2d pt3 = cv::Point2d(200.1, 300.6); // double 坐标
3.4 成员变量
cv::Point pt(10, 20);
int x = pt.x;
int y = pt.y;
3.5 常用操作符
cv::Point 支持常见算术运算和比较运算:
cv::Point a(10, 20);
cv::Point b(5, 8);
cv::Point c = a + b; // (15, 28)
cv::Point d = a - b; // (5, 12)
cv::Point e = a * 2; // (20, 40)
cv::Point f = a / 2; // (5, 10)
bool isEqual = (a == b); // false
3.6 常用函数
距离计算:
cv::Point2f p1(0, 0), p2(3, 4);
float dist = cv::norm(p1 - p2); // 欧几里得距离,结果是 5.0
点是否在图像内
cv::Point pt(100, 50);
cv::Size imgSize = img.size();
bool isInside = (pt.x >= 0 && pt.y >= 0 && pt.x < imgSize.width && pt.y < imgSize.height);
3.7 与图像绘制配合使用
画线:
cv::line(img, cv::Point(10, 10), cv::Point(100, 100), cv::Scalar(0, 255, 0), 2);
画圆:
cv::circle(img, cv::Point(50, 50), 20, cv::Scalar(255, 0, 0), -1); // 实心圆
画多边形:
std::vector<cv::Point> pts = { {10,10}, {100,50}, {50,100} };
cv::polylines(img, pts, true, cv::Scalar(0,0,255), 2);
3.8 与其他类型转换
cv::Point ↔ cv::Vec2i
cv::Point pt(10, 20);
cv::Vec2i vec(pt.x, pt.y);
cv::Point pt2(vec[0], vec[1]);
cv::Point2f ↔ cv::Matx
cv::Point2f pt(1.2f, 3.4f);
cv::Matx21f mat(pt.x, pt.y);
四、类型 cv::Scalar
cv::Scalar 是 OpenCV 中的一个非常常用的数据结构,用于表示多通道数值(最多 4 个通道),常用于:
- 图像处理中的颜色值表示(如 BGR、BGRA)
- 绘图函数的颜色参数
- 多通道数据的简洁表示(如通道加减)
4.1 模板定义
template<typename _Tp> class Scalar_;
typedef Scalar_<double> Scalar;
cv::Scalar 实际上是 cv::Scalar_ 的别名,因此所有值默认是 double 类型。它可以表示一个最多包含 4 个元素的向量:
cv::Scalar(v0); // 1 通道
cv::Scalar(v0, v1); // 2 通道
cv::Scalar(v0, v1, v2); // 3 通道
cv::Scalar(v0, v1, v2, v3); // 4 通道
4.2 常用构造方式
cv::Scalar gray(128); // 单通道灰度值
cv::Scalar bgr(255, 0, 0); // BGR 颜色(蓝色)
cv::Scalar bgra(0, 255, 0, 128); // BGRA 颜色(绿色 + 透明度128)
注意:OpenCV 默认颜色顺序是 BGR,不是 RGB。
4.3 常用场景
设置颜色(用于绘图)
cv::line(img, cv::Point(0, 0), cv::Point(100, 100), cv::Scalar(0, 0, 255), 2); // 红色线
cv::rectangle(img, cv::Rect(50, 50, 100, 100), cv::Scalar(0, 255, 0), -1); // 绿色填充矩形
图像填充
cv::Mat img(300, 300, CV_8UC3, cv::Scalar(100, 150, 200)); // B=100, G=150, R=200
作为返回值,例如 mean() 平均颜色:
cv::Scalar avgColor = cv::mean(img);
double blue = avgColor[0];
double green = avgColor[1];
double red = avgColor[2];
4.4 成员变量和访问方式
cv::Scalar color(10, 20, 30, 40);
double b = color[0]; // 通常是 Blue
double g = color[1]; // Green
double r = color[2]; // Red
double a = color[3]; // Alpha(透明度)
cv::Scalar 也重载了常见的运算符:
cv::Scalar a(10, 20, 30);
cv::Scalar b(1, 2, 3);
cv::Scalar c = a + b; // (11, 22, 33)
cv::Scalar d = a * 2; // (20, 40, 60)
4.5 常见转换
Scalar → Vec3b
cv::Scalar color(255, 100, 50);
cv::Vec3b vec((uchar)color[0], (uchar)color[1], (uchar)color[2]);
Vec3b → Scalar
cv::Vec3b v(100, 150, 200);
cv::Scalar color(v[0], v[1], v[2]);
4.6 实际案例
示例1:设置背景色
cv::Mat bg(200, 200, CV_8UC3, cv::Scalar(200, 100, 50)); // BGR
cv::imshow("Background", bg);
示例2:获取图像区域平均颜色
cv::Rect roi(100, 100, 50, 50);
cv::Mat patch = img(roi);
cv::Scalar meanColor = cv::mean(patch);
std::cout << "Mean BGR: " << meanColor << std::endl;
五、类型 cv::Size
cv::Size 是 OpenCV 中的一个轻量级类,用于表示二维尺寸(宽度和高度),常用于:
- 表示图像或窗口大小
- 表示矩形区域的尺寸(宽×高)
- 图像缩放、创建等操作中的参数传递
5.1 模板定义
template<typename _Tp> class Size_;
typedef Size_<int> Size; // 默认整型
typedef Size_<float> Size2f; // 浮点型尺寸
typedef Size_<double> Size2d; // 双精度尺寸
所以 cv::Size 实际上是 cv::Size_ 的别名,使用最多。
5.2 构造与初始化
cv::Size size1(640, 480); // 宽=640,高=480
cv::Size2f size2f(320.5f, 240); // 浮点尺寸
cv::Size2d size2d(1280.0, 720.0); // 双精度尺寸
注意:cv::Size(width, height),第一个参数是宽度,第二个是高度。
5.3 成员变量
cv::Size sz(100, 50);
int w = sz.width;
int h = sz.height;
5.4 常用操作
面积计算:
int area = sz.area(); // = width * height
尺寸比较:
cv::Size a(640, 480), b(640, 480);
bool same = (a == b); // true
加减乘除(宽和高分别运算):
cv::Size sz1(100, 50);
cv::Size sz2 = sz1 + cv::Size(20, 10); // (120, 60)
cv::Size sz3 = sz1 * 2; // (200, 100)
5.5 常用场景示例
创建指定尺寸的图像
cv::Size imgSize(640, 480);
cv::Mat img(imgSize, CV_8UC3, cv::Scalar(0, 0, 0)); // 黑色图像
图像缩放时指定目标尺寸
cv::Mat img = cv::imread("test.jpg");
cv::Size newSize(320, 240);
cv::Mat resized;
cv::resize(img, resized, newSize);
获取图像尺寸
cv::Mat img = cv::imread("test.jpg");
cv::Size sz = img.size();
int w = sz.width;
int h = sz.height;
将图像缩小为原来的一半
cv::Mat img = cv::imread("test.jpg");
cv::Size halfSize(img.cols / 2, img.rows / 2);
cv::Mat small;
cv::resize(img, small, halfSize);
六、类型 cv::Rect
cv::Rect 是 OpenCV 中用于表示矩形区域的核心数据结构,广泛应用于图像处理中的:
- ROI(感兴趣区域)选取
- 矩形绘制
- 人脸、物体检测框表示
- 区域相交、包含判断等几何操作
6.1 模板定义
template<typename _Tp> class Rect_;
typedef Rect_<int> Rect; // 默认整型坐标(像素)
typedef Rect_<float> Rect2f; // 浮点型矩形
typedef Rect_<double> Rect2d; // 双精度矩形
6.2 成员含义
cv::Rect 中包含四个成员变量:
cv::Rect r;
int x = r.x; // 左上角横坐标
int y = r.y; // 左上角纵坐标
int w = r.width; // 宽度
int h = r.height; // 高度
(x, y) 表示左上角坐标,width、height 表示尺寸。
6.3 构造方式
cv::Rect r1(10, 20, 100, 50); // x=10, y=20, width=100, height=50
cv::Rect r2(cv::Point(10, 20), cv::Size(100, 50)); // 从点和尺寸构造
6.4 常用操作
访问图像中的 ROI
cv::Mat img = cv::imread("test.jpg");
cv::Rect roi(100, 100, 200, 150);
cv::Mat cropped = img(roi); // 直接通过 Rect 提取区域
绘制矩形框
cv::rectangle(img, cv::Rect(50, 50, 100, 100), cv::Scalar(0, 255, 0), 2);
判断点是否在矩形内
cv::Point pt(60, 60);
cv::Rect box(50, 50, 100, 100);
bool inside = box.contains(pt); // true
两个矩形求交集、并集
cv::Rect r1(10, 10, 100, 100);
cv::Rect r2(50, 50, 100, 100);
cv::Rect intersect = r1 & r2; // 求交集
cv::Rect unioned = r1 | r2; // 求并集
防止越界,访问图像 ROI 时,建议先判断是否越界:
cv::Rect roi(100, 100, 300, 200);
roi = roi & cv::Rect(0, 0, img.cols, img.rows); // 裁剪到图像范围内
高亮显示图像中央区域
cv::Mat img = cv::imread("test.jpg");
cv::Rect centerBox(img.cols / 4, img.rows / 4, img.cols / 2, img.rows / 2);
cv::rectangle(img, centerBox, cv::Scalar(0, 0, 255), 2); // 红框
6.5 矩形运算符重载
cv::Rect a(0, 0, 50, 50);
cv::Rect b(10, 10, 30, 30);
cv::Rect c = a & b; // 交集
cv::Rect d = a | b; // 并集
bool equal = (a == b); // 是否相等
6.6 与其他类型配合使用
与 cv::Point 配合
cv::Rect r(10, 10, 100, 100);
cv::Point center = (r.tl() + r.br()) * 0.5; // tl(): 左上角, br(): 右下角
与 cv::Size 配合
cv::Rect roi(cv::Point(20, 30), cv::Size(100, 80));