OpenCV3学习(1)——基本数据类型

OpenCV3的数据类型比较多,主要分为:

基本数据类型(basic data types): 包括c++对应的基础类,如int、float等;简单的容器、数组和矩阵类;简单的例如点、矩形、尺寸等的几何概念类。
帮助类(helper objects): 这一类表示一些抽象的概念。例如碎片处理的点类、切片使用的范围类、终止条件类等。
大型数组类(large array types): 这一类通常包含很多其他类型,最具代表性的是 cv::Mat 类。
OpenCV3除了这些类型还极度使用c++的STL,其中vector类和模板的使用尤多。

一:基本数据类型

1 cv::Vec<>

cv::Vec<> 是一个模板类,主要用于存储数值向量。
cv::Vec<>的组织类型可以为:cv::Vec{2,3,4,6}{b,w,s,i,f,d} ,例如cv::Vec2i、cv::Vec4d等。

可用它来定义任意类型的向量

Vec<double, 4> myVector; // 定义一个存放4个double型变量的向量
myVector[0]=0;             //使用[]访问Vec向量成员

//可使用以下预定义的类型
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;

2 cv::Point<>

cv::Point<>和cv::Vec<>类型很相似,它们的不同在于:Point类型由命名的变量关联(mypoint.x,mypoint.y等),而vector类型则由下标访问(myvec[1]等)。 
cv::Point<>的组织类型可以为:cv::Point{2,3}{i,f,d} ,例如cv::Point2i、cv::Point3f等。

常用于表示2维坐标(x,y)。

//对图像而言,我们可以这样定义:

cv::Point pt;
pt.x = 10;
pt.y = 8;

//或者
cv::Point pt =  Point(10, 8);

//或者
cv::Point pt(10,8);


//设置坐标点
	cv::Point pt;
	pt.x = 278;
	pt.y = 269;
	//或者
	//cv::Point  pt (278,269);
	cv::Scalar pix = pImg.at<Vec3b>(pt);//读取pImg图像中pt坐标处的像素值
	cout<<"pix("<<pt.x<<","<<pt.y<<") = "<<pix<<endl;

注意:Point(x, y)代表的是坐标,对于图像而言,坐标系的建立是一图像左上角为原点,沿列向右为x轴,沿行向下为y轴。以Point(10,8)为例,它表示的是,图像第8行第10列的位置。

Point类的操作:

默认构造    Point2i p1;Point3f p2;
拷贝构造    Point3f p2(p1);
数值初始化  Point2i p1(x0,x1);Point3f p2(x0,x1,x2);
转换到Vector类型  (Vec3f) p;
成员访问   p.x; p.y;
点积运算   float x = p1.dot(p2);
双精度点积 double x = p1.ddot(p2);
向量积(仅适用三维)     p1.cross(p2);
查询是否在某区域(rectangle)内(仅适用二维)     p.inside(r);
注意: C++Point类转换成C语言结构CvPoint需要注意浮点型数据直接转换为CvPoint会自动四舍五入(CvPoint默认类型为int);

3 cv::Scalar<>

cv::Scalar用于表示四维的点,Scalar是一个从Vec类引出的模板类,是一个可存放4个元素的向量,广泛用于传递和读取彩色图像中的像素值。

C语言 CvScalar结构体:内部存储了四个double型的值,分别为val[0],val[1],val[2],val[3],我们通常用的是前三个,val[0],val[1],val[2]的含义分别是彩色照片的三个通道BGR。R是红色分量,G是绿色分量,B是蓝色分量,a是alpha;

图像存储的矩阵大小依赖于色彩空间的选用,更准确的说取决于所使用的通道数,在灰度图像中在内存描述如下:

  

对于多通道图像,列包含与通道数量一样多的子列。例如,在BGR颜色系统的情况下:

  

//可使用[]访问Scalar值。或使用如下方式定义BGR三个通道的值。

cv:: Scalar( B, G, R )

//示例代码1
cv::Scalar myScalar;
	myScalar = cv::Scalar(0,255,0);
	cout<<"myScalar = "<<myScalar<<endl;
	system("pause");

//示例代码2
cv::Mat pImg = cv::imread("img.jpg",1);//"1"表示读取彩色信息
	if(!pImg.data)
		return 0;
	int x = 100, y = 100;
	cv::Scalar pixel=pImg.at<Vec3b>(x,y);
	cout<<"B chanel of pixel is = "<<pixel.val[0]<<endl;
	cout<<"G chanel of pixel is = "<<pixel.val[1]<<endl;
	cout<<"R chanel of pixel is = "<<pixel.val[2]<<endl;
	system("pause");

运行结果:

                   

4 cv::Size<>

cv::Size<>和cv::Point<>很相似,但它一般用于表示尺寸,因此相关的命名变量为 width 和 height ,而不是 x 和 y。 

模板类Size可表示一幅图像或一个矩形的大小。它包含宽、高2个成员:width , height还有一个有用的面积函数area()。
cv::Size<>组织类型可以为:cv::cvSize、cv::Size2i和cv::Size2f

cv::Size size(int w, int h);
//或者
cv::Size size;
size.width = 10;   //矩阵的列数
size.height = 8;   //矩阵的行数


1 默认构造   Size sz;Size2i sz; Size2f p2;
2 拷贝构造   Size sz2(sz1);
3 数值初始化   Size sz(w,h);
4 成员访问   sz.width; sz.height;
5 计算区域面积   sz.area();

//示例代码
	cv::Size size1(6,3);
	cv::Size size2;
	size2.width = 4;
	size2.height = 2;
	cv::Mat mat1(size1,CV_8UC1,cv::Scalar(0));
	cv::Mat mat2(size2,CV_8UC3,cv::Scalar(1,2,3));
	cout<<"mat1 = "<<endl<<mat1<<endl;
	cout<<endl<<"mat2 = "<<endl<<mat2<<endl;
	system("pause");

运行结果:

                                     

5 cv::Rect

cv::Rect 既包含x和y分量(左上角点),又包含width和height分量(大小)。Rect可以用来定义图像的ROI区域。

Rect是另一个用于定义2维矩形的模板类。它由两个参数定义:

矩形左上角坐标: (x,y)

矩形的宽和高: width, height

默认构造   Rect r;
拷贝构造   Rect r2(r1);

cv::Rect rect(x, y, width, height);//值构造函数

cv::Point p(x,y);
cv::Size sz(width,height);
cv::Rect( p, sz );//从Point和Size构造

cv::Point p1(x1,y1);
cv::Point p2(x2,y2);
cv::Rect( p1, p2 );//从一对Point构造	

//成员访问	
r.x; 
r.y; 
r.width; 
r.height;
//计算面积	
r.area();
//提取左上角	
r.tl();
//提取右下角	
r.br();
//判断点p是否在矩形内	
r.contains( p );


重载操作符对象间的运算:
矩形1与矩形2的交集              Rect r3 = r1 & r2;
包含矩形1与矩形2的最小矩形   Rect r3 = r1 | r2;
平移左上角坐标矩形大小不变    Rect r2 = r1 + p;
放大或缩小矩形大小,左上角点不变 Rect r2 = r1 + sz;
判断两个矩形是否相等  bool eq = ( r1 == r2);bool ne = ( r1 != r2);

6 cv::RotatedRect

cv::RotatedRect是OpenCV3中少数的不基于模板的类,通过中心点,宽度和高度和旋转角度来表示一个旋转的矩形。cv::RotatedRect与它中心的位置相关,而cv::Rect与它左上角位置相关。cv::RotatedRect包括:

center:中心点坐标Point2f类型

size:矩形的宽度和高度,Size2f类型

angle:顺时针方向的旋转角度(单位°),float类型

  

1 默认构造     RotatedRect rr();
2 拷贝构造     RotatedRect rr2(rr1);
3 数值初始化   RotatedRect rr(p,sz,theta);
4 两点初始化   RotatedRect rr(p1,p2);
5 成员访问     rr.center; rr.size; rr.angle;
6 返回4角点坐标 rr.points(pts[4]);


cv::RotatedRect( p1, p2 );//从两个角点构造
cv::RotatedRect rr( p, sz, theta ) ;//值构造;包含一个点,一个尺寸,一个角度
rr.center; rr.size; rr.angle;//成员访问

//RotatedRect实例
	cv::Point2f center(100,100);
	cv::Size2f size(100,50);
	float angle = 45;// try 10, 30, 45
 
	RotatedRect rRect(center, size,  angle);
	cv::Mat image(200,200,CV_8UC3,cv::Scalar(0));
 
	Point2f vertices[4];
	rRect.points(vertices);
	for (int i = 0; i < 4; i++)
		line(image, vertices[i], vertices[(i+1)%4], Scalar(0,255,0));
 
	Rect brect = rRect.boundingRect();
	rectangle(image, brect, Scalar(255,0,0));
 
	imshow("rectangles", image);
	waitKey(0);

 运行结果:

   


二、帮助类

1 cv::TermCriteria class
很多算法都有一些终止条件,比如何时结束或者接近什么情况时结束。cv::TermCriteria标识了这些结束条件,并且很容易传递给OpenCV3的算法。它包含三个成员变量:type、maxCount和epsilon 。 
type可以被设置为:

cv::TermCriteria::COUNT——在maxCount迭代后结束;
cv::TermCriteria::EPS——在收敛速度低于ε时候结束;
cv::TermCriteria::COUNT | cv::TermCriteria::EPS——在两种条件下结束。
2 cv::Range class
cv::Range类被用来指定一段连续的整数值,它包含 start和end 成员变量。通常情况下cv::Range包含start值但不包含end值,例如:cv::Range rng(0,4)包含0,1,2,3但不包含4。 
使用 size() 成员函数可以获得range包含的数目,例如上例rng.size() 为4;

使用 empty() 可以判断range是否为空;

all() 包含Range的所有范围。

3 cv::Ptr 模板和垃圾回收
c++中的智能指针采用引用计数的方式来标识指针的被引用次数,当引用增加时计数会加1,引用减小时计数会减1;当引用计数为0即指针不再需要时,就会被销毁。OpenCV3中的cv::Ptr<>与c++智能指针的作用相同。 
使用时需要让Ptr包裹想要创建的指针类型,例如:

cv::Ptr<Matx33f> p(new cv::Matx33f);
cv::Ptr<Matx33f> p = makePtr<cv::Matx33f>();

4 cv::Exception 类和异常处理
 OpenCV3继承STL的 std::exception 异常定义了自己的 cv::Exception 异常类。cv::Exception 包含以下几个变量: code, err, func, file和line ,通过这几个变量可以很快定位和查询异常信息。 
使用以下方式可以定义自己的异常:

CV_Error( errorcode, description );
CV_Error_( errorcode, printf_fmt_str, [printf-args] );
CV_Assert( condition );    // Condition test
CV_DbgAssert( condition );    // Condition test

5 cv::DataType<>

cv::DataType<>用于给基础类型提供说明描述,在c++中这种技术称为类特性。简言之,也就是记录某种数据类型深度多少,有几个通道,格式是什么等。定义如下:

template<typename _Tp> class DataType
{
    typedef _Tp value_type;
    typedef value_type work_type;
    typedef value_type channel_type;
    typedef value_type vec_type;
    enum {
        generic_type = 1,
        depth = -1,
        channels = 1,
        fmt = 0,
        type = CV_MAKETYPE(depth, channels)
    };
};


//为了更好地理解,我们来看来自core.hpp的两个示例:
// Defination for float
template<> class DataType<float>
{
public:
    typedef float value_type;
    typedef value_type work_type;
    typedef value_type channel_type;
    typedef value_type vec_type;
    enum {
        generic_type = 0,
        depth = DataDepth<channel_type>::value,
        channels = 1,
        fmt = DataDepth<channel_type>::fmt,
        type = CV_MAKETYPE(depth, channels)
    };
};

其中,value_type是float类型,work_type, channel_type和vec_type同样也是float类型;generic_type设置为0,且在core.hpp中的所有类型都被设置为0; depth由cv::DataDepth::value 定义,它的值为CV_32F;channels为1,因为float为单独的一个数;fmt 由cv::DataDepth::fmt 定义,它的值为f;type由CV_MAKETYPE(CV_32F,1) 确定为CV_32FC1 。这样,对于float类型,DataType可以为它提供很好的解释。 


6 cv::InputArray和cv::OutputArray
            cv::InputArray和cv::OutputArray代指所有的数组类型,使用它们可以简化输入输出而不需要关心具体的类型,更像是一种数组容器。cv::InputArray默认是const的,即只读的;而cv::OutputArray则无此限制。当无需输入或输出时,可以使用 cv::noArray() 。

from:https://blog.csdn.net/iracer/article/details/51292349

from:http://www.cnblogs.com/Shuqing-cxw/p/9217375.html

from:https://blog.csdn.net/yibu_refresh/article/details/79293183#13-cvpoint

猜你喜欢

转载自blog.csdn.net/qq_30815237/article/details/86595979