OpenCV3学习(1)——基本数据类型
OpenCV3的数据类型比较多,主要分为:基本数据类型(basic data types): 包括c++对应的基础类,如int、float等;简单的容器、数组和矩阵类;简单的例如点、矩形、尺寸等的几何概念类。帮助类(helper objects): 这一类表示一些抽象的概念。例如碎片处理的点类、切片使用的范围类、终止条件类等。大型数组类(large array types): 这一类通常包...
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
更多推荐
所有评论(0)