OpenCv图像处理之常用工具Point、Scalar、Size、Rect和cvtColor介绍

OpenCv图像处理之常用工具Point、Scalar、Size、Rect和cvtColor介绍

cv::Point操作

Opencv中的数据类型大多由模板类进行创建,为了描述图像中的点(点的坐标等信息),提供了二维点模板类Point_三维点模板类Point3_。由于点类的开销很小,故源码中没有点定义太多的成员函数,Point_可以在平面(二维)中获取x,y的坐标来确定点的位置,Point_3则是通过获取三维空间中x,y,z坐标来确定点的位置。常用的数据(坐标点)类型有int,double,float类型。
下面来看一下源码中Point_和Point3_中对于数据类型的定义

	//Point_
    typedef Point_<int> Point2i;
    typedef Point_<int64> Point2l;
    typedef Point_<float> Point2f;
    typedef Point_<double> Point2d;
    typedef Point2i Point;
    //Ponit3_
        typedef Point3_<int> Point3i;
    typedef Point3_<float> Point3f;
    typedef Point3_<double> Point3d;

上述是我从源码库中复制的关于二维点模板类的定义,可以清楚的看到Point_<int>,Point_<int64>,Point_<float>,Point_<double>这些数据类型都使用了typedef关键字定义,即给他们分别起了一个别名,比如Point_<int>和Point2i表示的是同一个含义,同理可得,Point3_中的数据类型也是如此。这样做的好处是在实例化对象的时候非常方便。如以下代码

#include <iostream>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main() {
    
    

    Point2d point2D;
    point2D.x = 3.0;
    point2D.y = 5.0;
    Point3i point3I;
    point3I.x = 10;
    point3I.y = 20;
    point3I.z = 30;
    Point2i point2I = Point2i(50, 60);
    cout << "point2I.x:" << point2I.x << endl
         << "point2I.y:" << point2I.y << endl;
    return 0;
}
输出:
point2I.x:50
point2I.y:60

我们还可以对其进行某些运算操作(三维点可以进行向量和比较操作),这里展示下二维的相加操作

#include <iostream>
#include <opencv2/highgui.hpp>

using namespace std;
using namespace cv;

int main() {
    
    

    Point2i point2I_zero(10, 20), point2I_one(30, 50);
    Point2d point2D = point2I_one + point2I_zero;
    cout << "add_x:" << point2D.x << endl
         << "add_y:" << point2D.y << endl;
    return 0;
}
输出:
add_x:40
add_y:70
基本操作 示例
默认构造方法 cv::Point2i point2I_zero;
拷贝构造方法 cv::Point2i point2I_zero(point2I_one);
带初始化值的构造方法 cv::Point2d point2D_zero(x,y);
转换到固定向量类 (cv::Vec3f) p;
成员访问 point2I_zero.x; point2I_zero.y;
点积操作 float x = point2I_zero.dot(point2I_one)
双精度点积操作 double x = point2I_zero.ddot(point2I_one)
矢量积操作 point3I_zero.cross(point3I_one)(只针对3维point)
判断point是否在矩阵A中 point2I_one.inside(A)(只针对2维point)

cv::Scalar操作

Scalar(B,G,R,A)是对通道数进行处理的函数,具体操作看下面的程序

#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    
    
    Mat frame;
    frame = cv::imread("D:/cat.jpg", 3);
    //BGR-A A是透明度,(0,0,255)是红色
    Scalar scalar(0, 0, 255, 0);
    //height*width(rows*cols) MatSize size
    cout << "frame.shape:" << frame.size << endl;
    rectangle(frame, Rect(373 / 2, 372 / 2, 350, 350), scalar);
    imshow("draw_rectangle_frame", frame);
    waitKey(0);

}

效果显示在这里插入图片描述

cv::Size操作

Size模版类与对应的Point模版类类似,可以互相转换。他们的区别在于Size模版类中的两个成员变量分别是width,height,而Point模版类中的俩个成员变量分别是x,y。下面看一下源码中Size模版类对于数据类型的定义

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

和Point_,Point3_一样,都是使用typedef定义的别名,方便实例化。
下面使用一个例子来感受一下Size的用法

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    
    
    Mat frame = imread("D:/cat.jpg", 3);
    int width = frame.cols;
    int height = frame.rows;
    Size size(width, height);
    cout << "size.width:" << size.width << endl
         << "size.height:" << size.height << endl;
    return 0;
}
输出:
size.width:746
size.height:745

cv::Rect操作

和上述工具类一样Rect也是模板类,下面看一下源码中对于Rect成员的定义

//template<typename _TP>
Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height);
_Tp x; //!< x coordinate of the top-left corner
_Tp y; //!< y coordinate of the top-left corner
_Tp width; //!< width of the rectangle
_Tp height; //!< height of the rectangle
typedef Rect_<int> Rect2i;
typedef Rect_<float> Rect2f;
typedef Rect_<double> Rect2d;
typedef Rect2i Rect;

需要注意的是,当Rect()配合其他截取函数使用时,(x+width)<=img.cols,(y+height)<=img.rows

函数 简介
size() 返回Size类型
area() 返回矩形的面积
contains(Point) 判断点是否包含在此矩形内
tl() 返回左上角点的坐标
br() 返回右下角点的坐标

cv::cvtColor操作

先看一下源码中的函数原型

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

参数:
src输入图像类型cv::Mat
dst输出图像类型cv::Mat
code颜色空间转换标识符,从原颜色空间转向目标颜色空间
dstCn颜色通道数,输出的图像与输入的图像通道数一致

上面参数中提到了颜色空间,那么什么是颜色空间呢?
我们的世界是五彩缤纷的,通过不同的颜色,带给我们不同的视觉盛宴。其实这些不同的颜色,都是可以由基本的颜色组成的,比如我们经常说的光学三原色、颜料三原色,我们可以通过三种颜色的配比,得到不同种各式各样的颜色。我们可以构建一个三维的空间,当每个方向取不同的值,我们就能得到不同的颜色,这个就是颜色空间。
常见的颜色空间有BGR,灰度空间,HSV等等.

BGR

最常见的就是BGR系列了,其中:

B表示blue,蓝色;

G表示green,绿色;

R表示red,红色;

我们可以通过不同的组合得到不同的颜色;每个取值范围都是0-255,如果用16进制表示就是 0-FF。

BGR系列表示有一定的问题:

1.RGB 颜色空间利用三个颜色分量的线性组合来表示颜色,任何颜色都与这三个分量有关。
2.自然界中,由于光照等问题的影响,颜色发生变化,而是哪个颜色分量和光照都有关,所以图像亮度改变,三个通道的颜色都会改变。
3.人眼睛对不同颜色的敏感程度不同,有时候难以对一个颜色进行区分。
4.适用于图像显示,不适用于图像处理。

灰度空间

灰度空间算是简化的BGR空间,BGR有三个通道,分别表示三个像素分量,灰度空间只有一个通道,取值范围也是0-255,值越大,颜色越趋向于白色,值越小,颜色越趋向于黑色。

HSV

除了BGR系列,我们最常见的是HSV系列了,其中:

1.H表示Hue,色调;用角度度量,取值范围为0°~360°,从红色开始按逆时针方向计算,红色为0°,绿色为120°,蓝色为240°。它们的补色是:黄色为60°,青色为180°,紫色为300°;
2.S表示Saturation,饱和度;一种颜色,可以看成是某种光谱色与白色混合的结果。其中光谱色所占的比例愈大,颜色接近光谱色的程度就愈高,颜色的饱和度也就愈高。饱和度高,颜色则深而艳。光谱色的白光成分为0,饱和度达到最高。通常取值范围为0%~100%,值越大,颜色越饱和。
3.V表示Value,明度;明度表示颜色明亮的程度,对于光源色,明度值与发光体的光亮度有关;对于物体色,此值和物体的透射比或反射比有关。通常取值范围为0%(黑)到100%(白)。

下面看个程序

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    
    
    Mat frame = imread("D:/cat.jpg", 3);
    //BGR2HSV
    cvtColor(frame, frame, COLOR_HSV2RGB_FULL);
    imshow("cvtColor_frame", frame);
    waitKey(0);
    return 0;
}

在这里插入图片描述

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main() {
    
    
    Mat frame = imread("D:/cat.jpg", 3);
    //BGR2GRAY
    cvtColor(frame, frame, COLOR_BGR2GRAY);
    imshow("cvtColor_frame", frame);
    waitKey(0);
    return 0;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35140742/article/details/119868409