Opencv的数据结构

发布于:2025-09-01 ⋅ 阅读:(25) ⋅ 点赞:(0)

1. 基本数据类型

  OpenCV基本数据类型可分为三大类

  1.基本数据类型:该类型直接由C++的数据类型(int或float等)组装起来,包括简单的向量和矩阵;
  2.助手对象:这些对象表示更抽象的概念,如垃圾收集指针类等,用于表示切片的范围对象,以及对某些算法终止条件的抽象等。
  3.大型数组类型:包括cv::Mat、cv::Vec、cv::Point、cv::Scalar、cv::Size和cv::Rect、cv::RotatedRect等等,不同类型有不同的构造方式和操作

1.1 cv::Vec向量

  1.固定向量类,需要提前知道变量长度
  2.模板,可以存储任意数据类型
  3.存在多种预定义的类型(其他数据类型也有相关特性)

  除cv::Vec类外,还有固定维度的向量类cv::Matx
  cv::Matx类可用来处理固定大小的小维度矩阵运算。在计算机视觉中,有许多2×2、3×3和少量4×4的矩阵,以及用于各类变换的矩阵,都可以使用cv::Matx类来表示。
  值得注意的是,无论cv::Vec类,还是cv::Matx类,在编译时都需要知道变量的长度,这使得计算变得十分高效。

1.1.1 cv::Vec类可以定义任意类型的向量

cv::Vec<double3>myVector;//定义一个存放3个double型变量的向量
cv::Vec3d v3d(x0,x1x2);

1.1.2 cv::Vec类也可以使用以下预定义的类型:

  cv::Vec<T, cn> 是 OpenCV 中的一个模板类,用于表示固定长度的向量,常用于图像处理和计算机视觉中的坐标、颜色、法线等数据的存储。

template<typename _Tp, int cn>
class Vec;

_Tp:元素类型,如 uchar、int、float、double 等;
cn:元素个数(通道数),比如 RGB 就是 3,RGBA 就是 4。

// 源码中的预定义
/** @name Shorter aliases for the most popular specializations of Vec<T,n>
  @{
*/
typedef Vec<uchar, 2> Vec2b;2个uchar 类型的元素
typedef Vec<uchar, 3> Vec3b; 常用于存储图像中的 RGB/BGR 颜色。
typedef Vec<uchar, 4> Vec4b; 常用于存储带有 Alpha 通道的 RGBA/BGRA 颜色。

typedef Vec<short, 2> Vec2s;
typedef Vec<short, 3> Vec3s;
typedef Vec<short, 4> Vec4s;

typedef Vec<ushort, 2> Vec2w;
typedef Vec<ushort, 3> Vec3w;
typedef Vec<ushort, 4> Vec4w;

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;
typedef Vec<int, 6> Vec6i;
typedef Vec<int, 8> Vec8i;

typedef Vec<float, 2> Vec2f;  常用于存储二维坐标或二维向量。
typedef Vec<float, 3> Vec3f;  常用于存储三维坐标或三维向量。
typedef Vec<float, 4> Vec4f;
typedef Vec<float, 6> Vec6f;

typedef Vec<double, 2> Vec2d;
typedef Vec<double, 3> Vec3d;
typedef Vec<double, 4> Vec4d;  4double,可用于RGBA
typedef Vec<double, 6> Vec6d;
/** @} */

1.1.3 cv::Vec类支持的运算

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.1.4 cv::Vec类初始化与基本运算示例代码

#include<iostream>
// #include "stdafx.h"
#include <opencv2/opencv.hpp>

using namespace std;
int main(){
    cv::Vec<int, 3> myVec;
    for(int i = 0; i<3;i++)
        myVec[i] = i;
    cv::Vec3i v3i(0,1,2);
    cv::Vec2d v2d(1.2,2.4);
    cv::Vec2d v2d_1(v2d);

    cout<< "myVec[0] = " << myVec[0]  <<endl;
    cout<< "myVec[1] = " << myVec[1]  <<endl;
    cout<< "myVec[2] = " << myVec[2]  <<endl;

    cout << "v3i[0] = " << v3i[0] <<endl;
    cout << "v3i[1] = " << v3i[1] <<endl;
    cout << "v3i[2] = " << v3i[2] <<endl;
    
    cout << "v2d[0] = " << v2d[0] << endl; 
    cout << "v2d[1] = " << v2d[1] << endl;

    cout << "v2d_1[0] = " << v2d_1[0] << endl; 
    cout << "v2d_1[1] = " << v2d_1[1] << endl; 

    cv::Vec3f v1(1,0,0);
    cv::Vec3f v2(1,1,0);
    cv::Vec3f v3;

    cout << "v1:" << v1 << endl;
    cout << "v2:" << v2 << endl;

    cout << "v1·v2:" << v1.dot(v2) << endl;
    cout << "v1×v2:" << v1.cross(v2) <<endl;

    cout << "v1-v2:" << v1-v2 << endl;
    cout << "v1*v2:" << v1*v2 << endl;

    cout << "v1==v2:" << (v1==v2) << endl;
    cout << "v1!=v2:" << (v1!=v2) << endl;

    // system("PAUSE");
    return 0;

}                                                                                                                                                                              

  运行后屏幕输出如下:
在这里插入图片描述

1.1.5 实际应用示例

  示例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.2. cv::Matx<>尺寸矩阵

  注:cv::Matx类是cv:Vec类的基类
  cv::Matx<> 是 OpenCV 提供的一个固定尺寸矩阵模板类,用于数学运算中表示小型矩阵(比如 2×2、3×3、4×4、6×6 等),适合做变换矩阵(如旋转、缩放、投影),在图像几何变换、相机标定、三维重建等领域广泛使用。

1.2.1模板定义

template<typename _Tp, int m, int n>
class Matx;

_Tp:元素类型,如 float、double 等;
m:行数;
n:列数;

1.2.2 常见类型别名

在这里插入图片描述
  也可以自定义别名:

typedef cv::Matx<float, 2, 3> Matx23f;

1.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();   // 单位矩阵

  访问元素

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(); // 逆矩阵(如果可逆)

1.3 cv::Point类

  cv::Point 是OpenCV 中用于表示二维坐标点的结构,适用于图像处理中的像素坐标、点的位置、几何形状的顶点等场景,是使用非常广泛的基础数据结构之一。

  1.与固定向量类密切相关的是cv::Point类(点类),它是一个用来存放2个或3个int或float等基本类型值的容器。
  2.cv::Point类是从它们自己的模板中派生的,并非来自固定向量类。

在这里插入图片描述

1.3.1 模板定义

template<typename _Tp> class Point_;
// 预定义
typedef Point_<int> Point;      // cv::Point 是 int 类型
typedef Point_<float> Point2f;  // 浮点型点
typedef Point_<double> Point2d; // 双精度点
typedef Point_<int> Point2i;
typedef Point_<int64> Point2l;

typedef Point3_<int> Point3i;
typedef Point3_<float> Point3f;
typedef Point3_<double> Point3d;

1.3.2 常见类型

在这里插入图片描述

cv::Point类支持的构造方式与示例

在这里插入图片描述

1.3.3 创建与初始化

cv::Point pt1(100, 50);         // 整数坐标点
cv::Point2f pt2(100.5f, 50.2f); // 浮点坐标点
cv::Point2d pt3 = cv::Point2d(200.1, 300.6); // double 坐标

1.3.4 成员变量

cv::Point pt(10, 20);
int x = pt.x;
int y = pt.y;

1.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

1.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);

1.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);

1.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);

1.3.9 cv:Point类操作示例

#include<iostream>
#include "opencv.hpp"

using namespace std;
int main()
{    
    cv::Point p1(1,2);
    cv::Point p2(3, 4);
    cout << "p1 = " << "(" << p1.x << ", " << p1.y << ")" <<  endl;
    cout << "p2 = " << "(" << p2.x << ", " << p2.y << ")" <<  endl << endl;

    cv::Point3f p3(1.1, 2.4, 3.6);
    cout << "p3.x = " << p3.x << endl;  
    cout << "p3.y = " << p3.y << endl;
    cout << "p3.z = " << p3.z << endl<<endl;

    cv::Point3f p4(p3);
    cout << "p4.x = " << p4.x << endl;
    cout << "p4.y = " << p4.y << endl;
    cout << "p4.z = " << p4.z << endl<<endl;

    //计算
    cv::Point p = p1 + p2;
    cout << "p1 + p2 =  " << "(" << p.x << ", " << p.y << ")" << endl;
    cout << "p1 . p2 = " << p1.dot(p2) << endl;
    cout << "p3×p4 = " << p3.cross(p4) << endl << endl;

    cv::Rect2i rect(0,0,3,3);
    cout << "rect" << rect << endl;
    cout << "p1.inside(rect)  = " << p1.inside(rect) << endl;
    cout << "p2.inside(rect)  = " << p2.inside(rect) << endl;
    // system("PAUSE");
    return 0;
}

  示例输出结果如下:
在这里插入图片描述

1.4 cv::Scalar类

  cv::Scalar类(标量类)实际上是一个四维双精度向量类。有一些特殊的成员函数与计算机视觉中使用的4分量向量相关。用途如下:

1.4.1 模板定义

template<typename _Tp> class Scalar_;
typedef Scalar_<double> Scalar;

  cv::Scalar 实际上是 cv::Scalar_ 的别名,因此所有值默认是 double 类型。它可以表示一个最多包含 4 个元素的向量:

  而cv::Scalar类定义如下:

cv::Scalar(double v0 = 0, double v1 = 0, double v2 = 0, double v3 = 0)

在这里插入图片描述

cv::Scalar(v0);             // 1 通道
cv::Scalar(v0, v1);         // 2 通道
cv::Scalar(v0, v1, v2);     // 3 通道
cv::Scalar(v0, v1, v2, v3); // 4 通道

1.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。

在这里插入图片描述

1.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];

1.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)

1.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]);

1.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;

1.5 cv::Size类

  cv::Size 是 OpenCV 中的一个轻量级类,用于表示二维尺寸(宽度和高度),常用于:

表示图像或窗口大小
表示矩形区域的尺寸(宽×高)
图像缩放、创建等操作中的参数传递

在这里插入图片描述

1.5.1 模板定义

template<typename _Tp> class Size_;
typedef Size_<int> Size;         // 默认整型
typedef Size_<float> Size2f;     // 浮点型尺寸
typedef Size_<double> Size2d;    // 双精度尺寸

  所以 cv::Size 实际上是 cv::Size_ 的别名,使用最多。

1.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),第一个参数是宽度,第二个是高度。

1.5.3 成员变量

cv::Size sz(100, 50);
int w = sz.width;
int h = sz.height;

1.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)

1.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);

1.6 cv::Rect类

  cv::Rect 是 OpenCV 中用于表示矩形区域的核心数据结构,广泛应用于图像处理中的:

1.ROI(感兴趣区域)选取
2.矩形绘制
3.人脸、物体检测框表示
4.区域相交、包含判断等几何操作

  1.cv::Rect类(矩形类)包括cv::Point类的成员x和y(表示矩形的左上角)以及cv::Size类的成员width和height(表示矩形的大小)。
  2.矩形类不从cv::Pointcv::Size类继承,因此也不会继承它们相应的运算。

1.6.1 模板定义

template<typename _Tp> class Rect_;
typedef Rect_<int> Rect;        // 默认整型坐标(像素)
typedef Rect_<float> Rect2f;    // 浮点型矩形
typedef Rect_<double> Rect2d;   // 双精度矩形

1.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 表示尺寸。

1.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)); // 从点和尺寸构造

1.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); // 红框

1.6.5 矩形运算符重载

在这里插入图片描述

cv::Rect类支持的重载操作与示例
  而cv::Rect类的重载操作示例如下:
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
int main(){
    cv::Mat I,B, temp;
    I = cv::Mat::zeros(300,400,CV_8UC3);  // 创建一个黑色的画布
    B = I.clone();
    cv::Rect r1 = cv::Rect(60,60,200,100);  // 赋值构造
    cv::Rect r2 = cv::Rect(cv::Point(140,120),cv::Size(200,100));   // 通过点和高宽构造
    cv::rectangle(I, r1, cv::Scalar(0,255,0),2);                    // 在画布I上显示r1,颜色为(0,255,0),线宽为2
    cv::rectangle(I, r2, cv::Scalar(0,0,255), 2);
    cv::imshow("rectangle",I);
    cv::waitKey();

    temp = I.clone();
    cv::Rect r3 = r1 & r2;  // 交集
    cv::rectangle(temp, r3, cv::Scalar(255,0,0),2);
    cv::imshow("Intersection", temp);
    cv::waitKey();

    temp = I.clone();
    cv::Rect r4 = r1 | r2;  // 并集
    cv::rectangle(temp, r4, cv::Scalar(255,0,0),2);
    cv::imshow("Minimum area rectangle", temp);
    cv::waitKey();

    temp = B.clone();
    cv::Rect rs(r1);  
    rs += cv::Size(-30,60); // 增大
    cv::rectangle(temp, r1, cv::Scalar(0,255,0),2);
    cv::rectangle(temp, rs, cv::Scalar(255,0,0),2);
    cv::imshow("Enlarge", temp);
    cv::waitKey();    

    temp = B.clone();
    cv::Rect rt(r1);  
    rt += cv::Point(30,60); // 平移
    cv::rectangle(temp, r1, cv::Scalar(0,255,0),2);
    cv::rectangle(temp, rt, cv::Scalar(255,0,0),2);
    cv::imshow("Translate", temp);
    cv::waitKey();    

    cv::Point p(80,80);
    cv::Point q(20,20);
    cout << "r1:" << r1 << endl;
    cout << "r2:" << r2 << endl;
    cout << "r1 == r2:" << (r1 == r2) << endl;
    cout << "r1 contains p:" << r1.contains(p) << endl;
    cout << "r1 contains q:" << r1.contains(q) << endl;

    return 0;
}

  示例代码运行结果如下图:
在这里插入图片描述
  而示例代码输出结果如下图:
在这里插入图片描述

1.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));

1.6.7 常用函数

在这里插入图片描述

1.7 cv::RotatedRect类

  1.有向矩形类,包含一个名为center的Point2f变量,一个名为size的cv::Size2f变量,以及一个名为angle的浮点数变量,表示矩形围绕中心的旋转。
  2.与cv::Rect的区别:cv::RotatedRect类的位置相对于其center,而cv::Rect类的位置相对于其左上角。
在这里插入图片描述

cv::RotatedRect类支持的构造方式与示例

1.7.1 基本操作示例

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;

// RotatedRect的位置在center,Rect位置在左上角

int main(){
    cv::Mat I;
    I = cv::Mat(300,400,CV_8UC3, cv::Scalar(255,255,255)); // 白色画布
    cv::Point2f center(200, 150);
    cv::Size2f size(180, 120);  //W, H
    float angle = 30.0;
    cv::RotatedRect rRect(center, size, angle);
    cout<< "center" << rRect.center <<endl; // 其余成员同理
    cv::Point2f vertices[4];
    rRect.points(vertices);     // 获取4个角点
    for(int i = 0; i<4; i++){   // 逐条边绘制
        cv::line(I, vertices[i], vertices[(i+1)%4], cv::Scalar(255,0,0),2);
    } 
    cv::circle(I,center,2,cv::Scalar(0,0,0),2);     // 原点,第三个参数是半径
    cv::Rect boundingRect = rRect.boundingRect();   // 获取外接矩形
    cv::rectangle(I, boundingRect, cv::Scalar(0,0,255),2);
    cv::imshow(" rotated rectangle", I);
    cv::waitKey(0);
    return 0;
}

  示例代码运行效果如下图:
在这里插入图片描述

1.8 cv::Mat类型

  图像像素数据本身也是有数据类型的, 图像像素的数据类型可能是字节型、 整型、 浮点型等。 而图像的深度又与图像数据类型息息相关。 Mat对象提供了如下两个方法分别用于获取图像的类型与深度。

1.8.1 图像数据类型

  type()返回的是OpenCV支持的图像枚举类型, OpenCV中支持的图像数据类型如下图:
在这里插入图片描述
  每个类型以“CV_”开头, 中间的字母表示数据类型, 字母前面的数字表示该数据的长度, 字母后面的数字表示该图像的通道数目。
  这里以CV_8UC3为例进行解释: 8表示数据长度为8位; UC表示数据类型为无符号字节型; 3表示三通道,

1.8.2 图像深度类型

  depth()返回OpenCV支持的图像深度类型, OpenCV中支持的图像数据深度类型如下图:
在这里插入图片描述

1.8.3 基本操作示例

#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;

int main(){
    // 非赋值构造
    Mat a(Size(4,3),CV_8UC1, Scalar(255)); // 单通道
    Mat b = Mat(Size(4,3), CV_8UC3, Scalar(0,1,2)); // 三通道
    cout << "a=" << endl << a << endl << endl;
    cout << "b=" << endl << b << endl << endl;
    Mat mz = Mat::zeros(cv::Size(2,2), CV_8UC1);    //全零矩阵
    Mat mo = Mat::ones(Size(2,2), CV_8UC1);     // 全1矩阵
    Mat me = Mat::eye(Size(4,3), CV_32FC1);     // 对角线为1的矩阵
    cout << "mz=" << endl << mz << endl << endl;
    cout << "mo=" << endl << mo << endl << endl;
    cout << "me=" << endl << me << endl << endl;
    // system("pause");
    Mat m0 = Mat::ones(Size(3,3), CV_8UC1);     // 全1矩阵
    Mat m1 = Mat::eye(3,3, CV_8UC1);     // 全1矩阵

    cout << "m0=" << endl << m0 << endl << endl;
    cout << "m1=" << endl << m1 << endl << endl;
    cout << "m0+m1=" << endl << m0+m1 << endl << endl;
    cout << "m0.*m1" << endl << (m0.mul(m1)) << endl << endl;
    cout << "m0./m1" << endl << (m0/m1) << endl << endl;
    cout << "m0<m1" << endl << (m0 < m1) << endl << endl;
    cout << "m0<=m1" << endl << (m0 <= m1) << endl << endl;

    Mat image = imread("D:/workspaces/opencv/opencv-learning/1.jpg",1);
    Rect roi(Point(80,80),Size(120,160));
    Mat mat_roi(image, roi);
    Mat mat_range(image, Range(80, 80+160),Range(80, 80+120));

    namedWindow("image",WINDOW_NORMAL);

    imshow("image", image);
    
    imshow("roi", mat_roi);
    imshow("mat_range", mat_range);
    waitKey();
    return 0;
}

示例代码运行结果如下图所示。
在这里插入图片描述

  而安装Image Watch插件后,可以看到内存中的图,便于调试程序,用Image Watch插件查看图像如下图:
在这里插入图片描述

2.参考链接

  1.了解OpenCV的数据类型
  2.OpenCV4机器学习算法原理与编程实战—书中代码解析
  3.cv::Scalar()


网站公告

今日签到

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