三、了解OpenCV的数据类型

发布于:2025-07-20 ⋅ 阅读:(15) ⋅ 点赞:(0)

一、类型 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));

6.7 常用函数

在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到