序:之前了解openCV的概念和HighGUI,但是都是辅助与后面继续的更深入学习,从opencv的数据结构开始,才是学习openCV真正开始
数字图像存储的概念
我们的各种设备借助摄像头,扫描仪等可以从现实世界中获取到数字的图像,那么真正的数字图像是怎么样?
从图中看到是图片是像素点矩阵, 即图像在数码设备中的表现是矩阵
Mat 结构及使用
Mat是C++的一个类,由两份组成 :
1)矩阵头 :矩阵尺寸,存储方法,存储地址等信息
2)和指向一个所有像素值得矩阵的之后只能
class CV_EXPORTS Mat { public: //... int flags; //Mat的标识、数据是否连续、深度、通道数目 int dims;//矩阵的维数,取值应该大于或等于2 int rows, cols;//矩阵的行数和列数,如果矩阵超过2维,这两个变量的值都为-1 uchar* data;//指向引用计数的指针,如果数据是由用户分配的,则为NULL … //! interaction with UMat UMatData* u; //数据,矩阵 ... };
当程序中传递图像并创建副本时,大的开销是由矩阵造成的,openCV为了为了解决图像这个问题,计数机制,其思路
时每个Mat对象都有自己的信息头,但是共享同一个矩阵。
如:三个A,B,C共用
Mat A,C; A=imread("1.jpg",CV_LOAD_IMAGE_COLOR); Mat B(A);//拷贝函数 C=A;//赋值函数
若是任然想复制矩阵本身,则可以用clone 和copyTo
像素值的存储方法
存储像素值,需要指定颜色空间和数据类型。
颜色系统很多,各有优势,如下:
RGB 是最常见,采用与人眼相似的工作机制,他也是被显示设备所采用。
红、绿、蓝三个颜色通道每种色各分为255阶亮度,在0时“灯”最弱——是关掉的,而在255时“灯”最亮。当三色灰度数值相同时,产生不同灰度值的灰色调,即三色灰度都为0时,是最暗的黑色调;三色灰度都为255时,是最亮的白色调。(百度)
HSV和HLS 把颜色分解成色调,饱和度和亮度/明度,这是颜色描述跟自然的方式,比如可以通过抛弃最后一个元素,使算法对输入图像的光照条件不明感。
具体介绍这里有个文章写得很详细:http://www.360doc.com/content/13/1105/14/10724725_326803150.shtml
YCrCb是在JPEG图像中广泛使用
YCrCb即YUV, “Y”表示明亮度,也就是灰阶值,而 “U”和 “V” 表示的则是色度,作用是描述影像色彩及饱和度,用于指定像素的颜色。“色度”则定义了颜色的两个方面─色调与饱和度,分别用Cr和Cb来表示。 与 RGB相比,可以节省存储空间,且对视频编解码有利。(百度)
CIE L*a*b 是一种在感知上均匀的颜色空间,适合度量两个颜色间的距离。
创建Mat对象的7中方法
1)直接使用Mat构造函数
先来看看构造函数们:
Mat::Mat(int rows, int cols, int type) //创建行数为rows,列数为cols,类型为type的图像; Mat::Mat(Size size, int type) //创建大小为size,类型为type的图像; Mat::Mat(int rows, int cols, int type, const Scalar& s) //创建行数为rows,列数为cols,类型为type的图像,并将所有元素初始化为值s; Mat::Mat(Size size, int type, const Scalar& s) //创建大小为size,类型为type的图像,并将所有元素初始化为值s; Mat::Mat(const Mat& m) //将m赋值给新创建的对象,此处不会对图像数据进行复制,m和新对象共用图像数据; //Size类:尺寸的表示 Size(width, height) //Scalar类:是个short型的向量,能使用指定的定制化值来初始化矩阵,可以用于表示颜 色 Scalar(b,g,r)
eg:
Mat M(2,2,CV_8UC3,Scalar(1,1,255));
对于2维多通道图像,首先定义尺寸(行列数),然后指定存储元素的数据类型,及每个矩阵点的通道数,便有了下面的 规则多种定义:
CV_[The number of bits per item][Signed or Unsigned][Type Prefix]C[The Channel][number]
如CV_8UC3表示 8位无符号char型,每个矩阵点通道为3
2.C\C++中通过构造函数进行初始化
int sz[3]={2,2,2}//指定了数组的指针(数组名),包含了每个维度的尺寸! Mat L(3.sz,CV_8UC,Scalar:all(0));//三维矩阵。
3.利用Create函数
M.create(4,4,CV_8UC(2)); //此方法不能为矩阵设初值(像素点为 (255,255,255)),只是在改变尺寸是,重新为矩阵数据开辟内存而已。
4.采用Matlab式的初始化方式
Matlab初始化方式有 :zeros(),ones(),eye() 如:
Mat E=Mat::eye(4,4,CV_64F); Mat O=Mat::ones(2,2,CV_32F); Mat Z=Mat::zeros(3,3,CV_8UC1);
5.对小矩阵使用逗号分格式初始化函数
Mat C=(Mat_<double>(3,3) <<0,1,0,-1,5,-1,0,1,0);
6,为已存在的对象创建信息头
Mat RowClone =C.row(1).clone();
7,为已存在的Ipllmage 指针创建信息头
IplImage *img =cvLoadImage("1.jpeg",1); Mat mtx(img);//转换IplImage 为Mat
常用数据结构和类.
1.Point类:表示2维坐标系下的点
用法:Point p =Point(10,8);与Point2i,Point_<int> 等价,Point_<float>与Point2f等价。
2.Scalar类
具有四个元素组成,openCV中大量用于传递像素值。若只想写三个参数,openCV认为只表示三个参数
如Scalar(a,b,c); abc代表RGB三个颜色分量
3.Size类
尺寸的表示,Size(5,5) ;表示构造出来的size宽高为5
4.Rect类
成员变量为x,y,width,heigh 分别为左上角的坐标和矩形宽高
常用Size,area 返回矩形的size和面积,
若进行矩阵的交集和并集,进行平移
Rect r1= rect1 & rect2
Rect r2 = rect1 | rect2
Rect rectShift = rect +point ;
5 颜色空间转换cvtColar()函数
颜色空间转换函数看,可以实现RGB颜色向HSV,HSI等颜色空间的转换,也可以转换为灰度图。
Void cvtColor(InputArrau src, OutputArray dst,int code,int detcn=0) //第三个参数为颜色转换的标识图(具体查表cvtColar()函数标示符),第四个参数为颜色的通道值
基本图形绘制
line 绘制直线
ellipse 绘制椭圆
rectangle 绘制矩形
circle 绘制园
fillPoly 绘制填充多边形