Opencv中文网

OpenCV的点、颜色、尺寸、矩形

学习 OpenCV 时,必须要掌握基础数据结构(如 Point、Size、Scalar),但还需要了解更广泛的核心概念和工具。以下是 OpenCV 的基础知识框架,涵盖常用类、函数和关键模块:

类型作用示例
cv::Point表示 2D/3D 点(整数或浮点坐标)Point pt(10, 20);
cv::Size表示尺寸(宽度和高度)Size sz(640, 480);
cv::Rect表示矩形区域(原点 + 宽高)Rect roi(10, 10, 100, 100);
cv::Scalar表示颜色或四维向量(BGR/RGB)Scalar color(0, 255, 0);(绿色)
cv::Mat存储图像/矩阵数据(核心类)Mat img = imread("image.jpg");
cv::Vec固定长度的数值向量(如像素值)Vec3b pixel = img.at<Vec3b>(y, x);

一、Point类(点)

Point类表示二维平面坐标系中的点,即由图像坐标x和y指定的点。Point是Point2i的别称,而Point2i又是Point_<int>的别称。由此可见,Point类所表示的点的x和y的数据类型是整型。

Point_类是采用C++定义的一个模板类。于是,Point_<int64>就表示长整型的点坐标,Point_<float>表示单精度的点坐标,Point_<double>表示双精度的点坐标。

定义一个点的用法如下

Point point;
point.x = 99;
point.y = 99;

或者

Point point = Point(99, 99);

二、Size类(尺寸)

Size类同样也是一个模板类,表示图像的尺寸(宽和高)或矩形区域的大小。而模板类的名字叫Size_,主要有两个重要的成员,即width和height。能过Size_模板类,又定义了下面这些尺寸类型。

typedef Size_<int> Size2i;
typedef Size_<int64> Size2l;
typedef Size_<float> Size2f;
typedef Size_<double> Size2d;
typedef Size2i Size;

Size类的常用操作如下所示。

Size size(320, 240);
int w = size.width;   // 获取宽度
int h = size.height;  // 获取高度
size.width = 800;     // 修改宽度
size.height = 800;     // 修改高度
int area = size.area(); // 返回 width * height(800*800=640000)
bool isEmpty = size.empty(); // 当 width <= 0 或 height <= 0 时返回 true
Size sz(100, 200);
Point pt = sz;  // Size 可隐式转换为 Point(pt.x=100, pt.y=200)

在了解Size的用法之后,我们再来了解它的实际应用,通常,Size类在定义图像尺寸、调整图像大小、定义感兴趣区域(ROI)或定义滤波核大小都经常用到。

Mat img(Size(640, 480), CV_8UC3); // 创建640x480的3通道图像
resize(src, dst, Size(300, 300)); // 缩放图像到300x300
Rect roi(Point(10, 10), Size(100, 100)); // 定义一个100x100的矩形区域
Mat cropped = img(roi); // 裁剪图像
GaussianBlur(img, dst, cv::Size(5, 5), 0); // 5x5高斯核

三、Rect类(矩形)

感兴趣区域(ROI)那一节中我们提到Rect类。Rect 是一个矩形类,用于表示图像或矩阵中的矩形区域。它通过左上角坐标(x, y)和宽度(width)、高度(height)定义一个矩形,是处理图像 ROI(Region of Interest)、目标检测、裁剪等任务的核心工具。

它的定义如下

typedef Rect_<int> Rect2i;// 默认使用整数坐标
typedef Rect2i Rect;

它是由Rect_这个模板类定义而来的,从定义上看,Rect类的成员是int型。另外还有两种类型的矩形类,如下所示

typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;

Rect的成员主要有4个:

  • x:矩形左上角的 x 坐标(列索引)
  • y:矩形左上角的 y 坐标(行索引)
  • width:矩形的宽度
  • height:矩形的高度

下面是它的创建和常用使用方法

//创建方式
Rect rect1;                          // rect1: x=0, y=0, width=0, height=0
Rect rect2(10, 20, 100, 50);         // (x=10, y=20, w=100, h=50)
Rect rect3(Point(10, 20), Point(110, 70)); // 等价于rect2
Rect rect4(Point(10, 20), Size(100, 50)); // 等价于rect2

//常用方法
int x = rect.x;          // 获取x坐标
rect.width = 200;        // 修改宽度
int area = rect.area();  // 返回 width * height
bool inside = rect.contains(cv::Point(50, 30)); // 检查点(50,30)是否在rect内
Rect rectA(10, 10, 100, 100);
Rect rectB(50, 50, 100, 100);
Rect intersection = rectA & rectB; // 交集
Rect union_ = rectA | rectB;      // 并集
rect += Point(10, 10);  // 将矩形平移(10,10)
rect -= Point(5, 5);    // 反向平移
rect += Size(20, 20);   // 宽度和高度各增加20

从上面的代码不难看出,Rect可以轻松实现成员的访问和修改、计算Rect的面积、判断某个点坐标是否在矩形内、计算矩形的交集和并集、将矩形进行平移和缩放。

注意,OpenCV使用左上角为原点(0,0)的坐标系,x向右为增长,y向下为增长。若矩形超出图像范围,访问像素时会引发错误,一定要做好边界检查工作。

rect = rect & Rect(0, 0, img.cols, img.rows); // 确保矩形在图像内

在上面的代码中,如果rect的范围不在img图像中,两者相“与”后,rect的x、y、width、height为零。

四、Scalar类(颜色)

Scalar 是一个四维向量类,主要用于表示颜色(BGR/RGB)或存储多通道数值。它是模板类 Scalar_ 的别名,默认使用 double 类型,但在图像处理中通常用于传递 8 位无符号整数(0~255) 的颜色值。

基本定义

typedef Scalar_<double> Scalar;  // 默认双精度浮点,但常用于存储颜色

访问4个成员变量分别用scalar[0]、scalar[1]、scalar[2]、scalar[3]表示。由于OpenCV中的图像在通道排列上是BGR或BGRA,所以scalar[0]表示Blue,scalar[1]表示Green,scalar[2]表示Red,scalar[3]表示Alpha(可选)。

在多通道数据中,存储各通道的值,如 HSV 图像的 H、S、V。

示例

cv::Scalar s1;                // [0, 0, 0, 0]
cv::Scalar s2(255);           // [255, 0, 0, 0]
cv::Scalar s3(0, 0, 255);     // B=0, G=0, R=255(红色)
cv::Scalar s4(0, 255, 0, 0);  // B=0, G=255, R=0(绿色),Alpha=0

Scalar类的常用操作有访问和修改成员的值,颜色转换,标量运算等。下面是它的使用示例。

Scalar color(0, 255, 0);  // 绿色
double blue = color[0];       // 获取蓝色分量
color[2] = 0;                // 修改红色分量为0(变为青色)

 //将图像某个像素的颜色值提取出来
 Vec3b pixel = img.at<cv::Vec3b>(y, x);//从 Vec3b 转换(如像素值)
 Scalar color2(pixel[0], pixel[1], pixel[2]);  // BGR 转 Scalar

//标量计算
Scalar s1(10, 20, 30);
Scalar s2(1, 2, 3);
Scalar s3 = s1 + s2;  // [11, 22, 33, 0]
Scalar s4 = s1 * 2;   // [20, 40, 60, 0]

Scalar类用在许多实际应用场景中,如绘制图形时指定颜色,图像填充或初始化颜色,多通道图像的操作,阈值处理等。

//在img图像中画矩形
rectangle(img, Point(10, 10), Point(100, 100), Scalar(0, 255, 0), 2); 

// 全蓝色图像
Mat img(480, 640, CV_8UC3, cv::Scalar(255, 0, 0));  

// 将图像的绿色通道设为0
Mat bgrChannels[3];
split(img, bgrChannels);
bgrChannels[1] = Scalar(0);  // 绿色通道置零
merge(bgrChannels, 3, img);

// 阈值化时 Scalar(255) 表示最大值
threshold(img, img, 128, 255, cv::THRESH_BINARY);  

在上面的示例中,出现了许多未见过的函数,如rectangle()表示绘制矩形,split()表示分割通道,merge()表示合并通道,threshold()表示对图像进行二值化处理,这些函数将在后面的章节中详细讲解。我们只关注其中使用到Scalar类的地方。

五、Mat类(图像)

Mat(Matrix 的缩写)是最核心的类,用于存储和操作图像、矩阵或多维数据。它是 OpenCV 进行图像处理的基础,支持高效的数学运算、内存管理和像素级操作。

它有几个核心的特性,首先支持多维数组,如1维、2维和3维,自动内存管理,支持多种类型的图像数据,如uchar(8位图)、float(32位图)、double(64图)。可存单通道(灰色)或多通道(BGR、BGRA等)数据。

有关Mat类的基本知识,请参考《创建Mat图像》一节。

有关Mat类的图像类型,常用的有CV_8U、CV_32F和CV_64F,而Mat类的通道数则分为CV_8UC1、CV_8UC3和CV_32FC4。

下表是Mat类的常用成员或函数

成员或函数说明
rowscols获取行数(高度)和列数(宽度)
channels()返回通道数
total()返回总像素数(rows × cols)
empty()检查矩阵是否为空
convertTo()转换数据类型(如 CV_8U → CV_32F
reshape()改变通道数或维度(不复制数据)

对于多通道操作,可使用cv::split() 和 cv::merge() 分离或合并通道。

六、Vec类(向量)

Vec是一个模板类,在OpenCV中表示向量,如数学向量或像素值向量。由它定义了许多常用预定义类型,如下所示:

typedef Vec<uchar, 2> Vec2b;
typedef Vec<uchar, 3> Vec3b;
typedef Vec<uchar, 4> Vec4b;

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

typedef Vec<int, 2> Vec2i;
typedef Vec<int, 3> Vec3i;
typedef Vec<int, 4> Vec4i;

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;
typedef Vec<double, 6> Vec6d;

最常用的就是访问3通道图像的像素值。如下所示:

// 全蓝色图像
Mat img(480, 640, CV_8UC3, Scalar(255, 0, 0))
Vec3b pixel = img.at<Vec3b>(1, 1);
uchar blue = pixel[0];//读蓝色通道值
uchar green = pixel[1];//读蓝色通道值
uchar red = pixel[2];//读蓝色通道值
pixel[0] = 255 - blue;//修改
pixel[1] = 255 - green;//修改
pixel[2] = 255 - red;//修改

在几何运算中,Vec2f和Vec3f分别表示2D/3D点或向量。

Vec3f a(1, 2, 3), b(4, 5, 6);
Vec3f c = a + b;        // 向量加法
Vec3f d = a * 2;        // 标量乘法
float dot = a.dot(b);   // 点积
Vec3f cross = a.cross(b); // 叉积(仅适用于3维向量)

——重庆教主 2025年5月15日

copyright @重庆教主 WPF中文网 联系站长:(QQ)23611316 (微信)movieclip (QQ群).NET小白课堂:864486030 | 本文由WPF中文网原创发布,谢绝转载 渝ICP备2023009518号-1