1--本节我们讲解如何存储像素,存储像素值,需要指定:
1--颜色空间
2--数据类型
2--其中,颜色空间是指针对一个给定的颜色,如何组合颜色以其编码。
3--最简单的颜色空间是----灰度级空间----只需要处理:黑色和白色,对它们进行组合便可以产生不同程度的灰
色(256灰度级)
4--对于彩色方式---则有更多种类的颜色空间,但不论那种方式,都是把颜色分成:三个或者四个---基元素,通过
组合基元素,就可以产生所有的颜色
1--RGB颜色空间是最常用的一种颜色空间,这归功于它也是人眼内部构成颜色的方式,它的基色是--红色,绿色
蓝色,有时为了表示透明颜色,也会加入第四个元素alpha(A)
2--彩色转灰度的公式:
Gray = R*0.299 + G*0.587 + B*0.114
5--颜色系统有很多,它们各有优势:
1--RGB是最常见的,这是因为人眼采用了相似的工作机制,它被显示设备所采用
2--HSV和HLS把颜色分解为--色调,饱和度,亮度和明度,这是描述颜色最自然的方式
1--每个组成元素都有自己的定义域,而定义域的大小取决于其数据类型,如何存储一个元素决定了我们在其定义
域上能够控制的---精度
2--最小的数据类型是---char,占一个字节8位,可以使有符号型(-127--127),也可以是无符号型(0--255)
3--尽管使用三个char型已经可以表示1600万种坑的颜色(RGB)颜色空间,但是若使用float(4字节32位)或者
double(8字节64位),则能够更加精细的描述颜色分辨率的能力。但是,同时,图片所占用的存储空间也会
成倍的增加
1--源代码的具体位置位于---core.hpp文件中:
2--比如说我的OpenCv安装在C盘中,那么它所对应的目录就是:
C:\Program Files\opencv\build\include\opencv2\core
/********************************************************************************************* 程序功能: OpenCv2.4.8之Mat类--OpenCv源代码解读 OpenCv2.4.8+VS2010 地点时间: 陕西师范大学 2016.4.21 作者信息: 九月 **********************************************************************************************/
//【1】这是OpenCv源代码中,Mat类的定义部分
//【2】CV_EXPORTS--这个修饰符,我们先不探究它是什么
//【3】我们先重点看一下Mat都有哪些:
1--构造函数
2--成员方法(或者说成员函数)
3--数据成员
//【4】class Mat{};----标准的C++类定义,大家在这块注意一下,C++中类定义完成的最后有一个分号";",
在java语言中,类的定义是没有的,而且C++中类的定义没有用public修饰,而C++默认的修饰符是private,
结构体默认的修饰符是public(这也是C++中结构体与类类型的最主要的区别)
//【5】Mat类的--声明
class CV_EXPORTS Mat
{
public:
//! default constructor
//【1】Mat类默认的构造函数
Mat();
//! constructs 2D matrix of the specified size and type
// (_type is CV_8UC1, CV_64FC3, CV_32SC(12) etc.)
//【2】通过指定一个矩阵的rows行和cols列以及类型,来构造一个指定大小的2维矩阵
Mat(int rows, int cols, int type);
//【3】和上面的一样,这里只不过是把二维矩阵的rows行和cols列封装在一个Size这样的类,用它来指定一个大小的
确定的二维矩阵(确定宽和高的图像)
//【4】这里的Size其实是一个类模板,具体是什么,大家可以去分析源代码
Mat(Size size, int type);
//! constucts 2D matrix and fills it with the specified value _s.
//【5】构造一个指定大小和类型的Mat对象,并且用指定的Scalar颜色去填充它
Mat(int rows, int cols, int type, const Scalar& s);
Mat(Size size, int type, const Scalar& s);
//【6】构造一个N维的矩阵
//! constructs n-dimensional matrix
Mat(int ndims, const int* sizes, int type);
Mat(int ndims, const int* sizes, int type, const Scalar& s);
//! copy constructor
//【7】C++中的复制构造函数---特点:只有单个形参,而且该形参是对本类类型对象的应用常量,这类构造函数称为--
复制构造函数
//【8】此块Mat类重载了一个Mat的复制构造函数
Mat(const Mat& m);
//! constructor for matrix headers pointing to user-allocated data
//【9】构造一个指定大小和类型的Mat信息头,并且指向用户已经分配的数据
Mat(int rows, int cols, int type, void* data, size_t step=AUTO_STEP);
Mat(Size size, int type, void* data, size_t step=AUTO_STEP);
Mat(int ndims, const int* sizes, int type, void* data, const size_t* steps=0);
//! creates a matrix header for a part of the bigger matrix
//【10】构造一个大矩阵一部分的信息头
Mat(const Mat& m, const Range& rowRange, const Range& colRange=Range::all());
Mat(const Mat& m, const Rect& roi);
Mat(const Mat& m, const Range* ranges);
//! converts old-style CvMat to the new matrix; the data is not copied by default
//【11】这个构造函数用于老式的cvMat矩阵和Mat类对象的转换
Mat(const CvMat* m, bool copyData=false);
//! converts old-style CvMatND to the new matrix; the data is not copied by default
Mat(const CvMatND* m, bool copyData=false);
//! converts old-style IplImage to the new matrix; the data is not copied by default
Mat(const IplImage* img, bool copyData=false);
//! builds matrix from std::vector with or without copying the data
template<typename _Tp> explicit Mat(const vector<_Tp>& vec, bool copyData=false);
//! builds matrix from cv::Vec; the data is copied by default
template<typename _Tp, int n> explicit Mat(const Vec<_Tp, n>& vec, bool copyData=true);
//! builds matrix from cv::Matx; the data is copied by default
template<typename _Tp, int m, int n> explicit Mat(const Matx<_Tp, m, n>& mtx, bool copyData=true);
//! builds matrix from a 2D point
template<typename _Tp> explicit Mat(const Point_<_Tp>& pt, bool copyData=true);
//! builds matrix from a 3D point
template<typename _Tp> explicit Mat(const Point3_<_Tp>& pt, bool copyData=true);
//! builds matrix from comma initializer
template<typename _Tp> explicit Mat(const MatCommaInitializer_<_Tp>& commaInitializer);
//! download data from GpuMat
explicit Mat(const gpu::GpuMat& m);
//【12】C++类中很重要的一个部分---析构函数
//! destructor - calls release()
~Mat();
//! assignment operators
//【13】Mat类中的运算符重载
Mat& operator = (const Mat& m);
Mat& operator = (const MatExpr& expr);
//! returns a new matrix header for the specified row
Mat row(int y) const;
//! returns a new matrix header for the specified column
Mat col(int x) const;
//! ... for the specified row span
Mat rowRange(int startrow, int endrow) const;
Mat rowRange(const Range& r) const;
//! ... for the specified column span
Mat colRange(int startcol, int endcol) const;
Mat colRange(const Range& r) const;
//! ... for the specified diagonal
// (d=0 - the main diagonal,
// >0 - a diagonal from the lower half,
// <0 - a diagonal from the upper half)
Mat diag(int d=0) const;
//! constructs a square diagonal matrix which main diagonal is vector "d"
static Mat diag(const Mat& d);
//! returns deep copy of the matrix, i.e. the data is copied
//【14】Mat类中的---深复制----的一个函数
//【15】Mat A=B.clone()--将对象B的信息头,矩阵指针以及矩阵体全部复制给对象A
Mat clone() const;
//! copies the matrix content to "m".
// It calls m.create(this->size(), this->type()).
//【16】也是深复制B.copyTo(A),作用同Mat A=B.clone()
void copyTo( OutputArray m ) const;
//! copies those matrix elements to "m" that are marked with non-zero mask elements.
void copyTo( OutputArray m, InputArray mask ) const;
//! converts matrix to another datatype with optional scalng. See cvConvertScale.
void convertTo( OutputArray m, int rtype, double alpha=1, double beta=0 ) const;
void assignTo( Mat& m, int type=-1 ) const;
//! sets every matrix element to s
//【17】将图片中(矩阵)的每一个像素颜色设置为颜色s
Mat& operator = (const Scalar& s);
//! sets some of the matrix elements to s, according to the mask
//【18】根据掩膜设置图片的颜色
Mat& setTo(InputArray value, InputArray mask=noArray());
//! creates alternative matrix header for the same data, with different
// number of channels and/or different number of rows. see cvReshape.
Mat reshape(int cn, int rows=0) const;
Mat reshape(int cn, int newndims, const int* newsz) const;
//! matrix transposition by means of matrix expressions
MatExpr t() const;
//! matrix inversion by means of matrix expressions
MatExpr inv(int method=DECOMP_LU) const;
//! per-element matrix multiplication by means of matrix expressions
MatExpr mul(InputArray m, double scale=1) const;
//! computes cross-product of 2 3D vectors
Mat cross(InputArray m) const;
//! computes dot-product
double dot(InputArray m) const;
//! Matlab-style matrix initialization
//【19】Matlab风格的矩阵初始化函数,指定矩阵的大小和类型
static MatExpr zeros(int rows, int cols, int type);
static MatExpr zeros(Size size, int type);
static MatExpr zeros(int ndims, const int* sz, int type);
static MatExpr ones(int rows, int cols, int type);
static MatExpr ones(Size size, int type);
static MatExpr ones(int ndims, const int* sz, int type);
static MatExpr eye(int rows, int cols, int type);
static MatExpr eye(Size size, int type);
//! allocates new matrix data unless the matrix already has specified size and type.
// previous data is unreferenced if needed.
void create(int rows, int cols, int type);
void create(Size size, int type);
void create(int ndims, const int* sizes, int type);
//! increases the reference counter; use with care to avoid memleaks
void addref();
//! decreases reference counter;
// deallocates the data when reference counter reaches 0.
void release();
//! deallocates the matrix data
void deallocate();
//! internal use function; properly re-allocates _size, _step arrays
void copySize(const Mat& m);
//! reserves enough space to fit sz hyper-planes
void reserve(size_t sz);
//! resizes matrix to the specified number of hyper-planes
void resize(size_t sz);
//! resizes matrix to the specified number of hyper-planes; initializes the newly added elements
void resize(size_t sz, const Scalar& s);
//! internal function
void push_back_(const void* elem);
//! adds element to the end of 1d matrix (or possibly multiple elements when _Tp=Mat)
template<typename _Tp> void push_back(const _Tp& elem);
template<typename _Tp> void push_back(const Mat_<_Tp>& elem);
void push_back(const Mat& m);
//! removes several hyper-planes from bottom of the matrix
void pop_back(size_t nelems=1);
//! locates matrix header within a parent matrix. See below
void locateROI( Size& wholeSize, Point& ofs ) const;
//! moves/resizes the current matrix ROI inside the parent matrix.
Mat& adjustROI( int dtop, int dbottom, int dleft, int dright );
//! extracts a rectangular sub-matrix
// (this is a generalized form of row, rowRange etc.)
Mat operator()( Range rowRange, Range colRange ) const;
Mat operator()( const Rect& roi ) const;
Mat operator()( const Range* ranges ) const;
//! converts header to CvMat; no data is copied
operator CvMat() const;
//! converts header to CvMatND; no data is copied
operator CvMatND() const;
//! converts header to IplImage; no data is copied
operator IplImage() const;
template<typename _Tp> operator vector<_Tp>() const;
template<typename _Tp, int n> operator Vec<_Tp, n>() const;
template<typename _Tp, int m, int n> operator Matx<_Tp, m, n>() const;
//! returns true iff the matrix data is continuous
// (i.e. when there are no gaps between successive rows).
// similar to CV_IS_MAT_CONT(cvmat->type)
bool isContinuous() const;
//! returns true if the matrix is a submatrix of another matrix
bool isSubmatrix() const;
//! returns element size in bytes,
// similar to CV_ELEM_SIZE(cvmat->type)
//【21】返回图像中每一个像素元素的大小
size_t elemSize() const;
//! returns the size of element channel in bytes.
size_t elemSize1() const;
//! returns element type, similar to CV_MAT_TYPE(cvmat->type)
//【22】返回元素的类型
int type() const;
//! returns element type, similar to CV_MAT_DEPTH(cvmat->type)
int depth() const;
//! returns element type, similar to CV_MAT_CN(cvmat->type)
int channels() const;
//! returns step/elemSize1()
size_t step1(int i=0) const;
//! returns true if matrix data is NULL
bool empty() const;
//! returns the total number of matrix elements
//【23】返回整幅图片中元素的---像素点的---总数
//【24】一幅图片中像素点的总数=图片的高度*图片的宽度=rows*cols
size_t total() const;
//! returns N if the matrix is 1-channel (N x ptdim) or ptdim-channel (1 x N) or (N x 1); negative number otherwise
int checkVector(int elemChannels, int depth=-1, bool requireContinuous=true) const;
//! returns pointer to i0-th submatrix along the dimension #0
//【25】这几个函数用在----变量图像中的每一个像素的时候
//【26】用于操作一副图片中的每一个像素
//【27】后面将会用一节具体的讲解
uchar* ptr(int i0=0);
const uchar* ptr(int i0=0) const;
//! returns pointer to (i0,i1) submatrix along the dimensions #0 and #1
uchar* ptr(int i0, int i1);
const uchar* ptr(int i0, int i1) const;
//! returns pointer to (i0,i1,i3) submatrix along the dimensions #0, #1, #2
uchar* ptr(int i0, int i1, int i2);
const uchar* ptr(int i0, int i1, int i2) const;
//! returns pointer to the matrix element
uchar* ptr(const int* idx);
//! returns read-only pointer to the matrix element
const uchar* ptr(const int* idx) const;
template<int n> uchar* ptr(const Vec<int, n>& idx);
template<int n> const uchar* ptr(const Vec<int, n>& idx) const;
//! template version of the above method
template<typename _Tp> _Tp* ptr(int i0=0);
template<typename _Tp> const _Tp* ptr(int i0=0) const;
template<typename _Tp> _Tp* ptr(int i0, int i1);
template<typename _Tp> const _Tp* ptr(int i0, int i1) const;
template<typename _Tp> _Tp* ptr(int i0, int i1, int i2);
template<typename _Tp> const _Tp* ptr(int i0, int i1, int i2) const;
template<typename _Tp> _Tp* ptr(const int* idx);
template<typename _Tp> const _Tp* ptr(const int* idx) const;
template<typename _Tp, int n> _Tp* ptr(const Vec<int, n>& idx);
template<typename _Tp, int n> const _Tp* ptr(const Vec<int, n>& idx) const;
//! the same as above, with the pointer dereferencing
template<typename _Tp> _Tp& at(int i0=0);
template<typename _Tp> const _Tp& at(int i0=0) const;
template<typename _Tp> _Tp& at(int i0, int i1);
template<typename _Tp> const _Tp& at(int i0, int i1) const;
template<typename _Tp> _Tp& at(int i0, int i1, int i2);
template<typename _Tp> const _Tp& at(int i0, int i1, int i2) const;
template<typename _Tp> _Tp& at(const int* idx);
template<typename _Tp> const _Tp& at(const int* idx) const;
template<typename _Tp, int n> _Tp& at(const Vec<int, n>& idx);
template<typename _Tp, int n> const _Tp& at(const Vec<int, n>& idx) const;
//! special versions for 2D arrays (especially convenient for referencing image pixels)
template<typename _Tp> _Tp& at(Point pt);
template<typename _Tp> const _Tp& at(Point pt) const;
//! template methods for iteration over matrix elements.
// the iterators take care of skipping gaps in the end of rows (if any)
template<typename _Tp> MatIterator_<_Tp> begin();
template<typename _Tp> MatIterator_<_Tp> end();
template<typename _Tp> MatConstIterator_<_Tp> begin() const;
template<typename _Tp> MatConstIterator_<_Tp> end() const;
enum { MAGIC_VAL=0x42FF0000, AUTO_STEP=0, CONTINUOUS_FLAG=CV_MAT_CONT_FLAG, SUBMATRIX_FLAG=CV_SUBMAT_FLAG };
/*! includes several bit-fields: - the magic signature - continuity flag - depth - number of channels */
int flags;
//! the matrix dimensionality, >= 2
//【28】这是Mat类的数据成员--------第四部分重要的内容----数据成员----成员属性
//【29】用于记录矩阵(图片)的维数
int dims;
//! the number of rows and columns or (-1, -1) when the matrix has more than 2 dimensions
//【30】用于记录矩阵的rows行和cols列
//【31】rows---nHeight----图形的高度
//【32】cols---nWidth-----图像的宽度
int rows, cols;
//! pointer to the data
uchar* data;
//! pointer to the reference counter;
// when matrix points to user-allocated data, the pointer is NULL
int* refcount;
//! helper fields used in locateROI and adjustROI
uchar* datastart;
uchar* dataend;
uchar* datalimit;
//! custom allocator
MatAllocator* allocator;
struct CV_EXPORTS MSize
{
MSize(int* _p);
Size operator()() const;
const int& operator[](int i) const;
int& operator[](int i);
operator const int*() const;
bool operator == (const MSize& sz) const;
bool operator != (const MSize& sz) const;
int* p;
};
struct CV_EXPORTS MStep
{
MStep();
MStep(size_t s);
const size_t& operator[](int i) const;
size_t& operator[](int i);
operator size_t() const;
MStep& operator = (size_t s);
size_t* p;
size_t buf[2];
protected:
MStep& operator = (const MStep&);
};
//【33】一行含有的字节数
MSize size;
MStep step;
protected:
void initEmpty();
};