Mat 简介:##### Mat 用于管理图像在内存中的存储,在Opencv 3 中由于使用了内存自动管理机制,所以不必像最早的Opencv一样需要手动分配和释放内存空间,Mat是由两个部分组成的。一个图像数据矩阵头包括(矩阵尺寸、存储方法、存储地址等信息),另一个是指向存储图像所有像素值的矩阵空间的指针。
在Mat的实现中使用了引用计数机制,每次Mat对象的信息头被复制了,都会增加矩阵的引用次数加1;反之,当一个Mat的信息头被释放后,引用计数就会被减1;当计数被减到0时,矩阵就会被释放。
上述的方式我们可以知道这种情况下矩阵数据是共享的,任何一个函数改动都会影响到这个矩阵,但是有时候我们需要独立的矩阵空间,这时候可以使用clone和 copyTo。通过clone和copyTo创建的Mat,都有自己的矩阵,修改其中一个的矩阵不会对其他的造成影响。
Mat 属性:##### 
data  uchar型的指针。就是上面提到的指向矩阵数据的指针。
 
 type
 
  depth 色彩深度
 
Mat 创建和初始化:##### cv ::Mat img(20 ,20 ,CV_8UC3,cv::Scalar(255 ,255 ,255 ));
上述代码创建了一个20行20列的矩阵,矩阵元素使用8位无符号char类型保存,具有3通道,每个像素的初始值是(255,255,255)黑色,这里需要注意Scalar的表示顺序为BGR
img .create (20 ,20 ,CV_8UC(3 ));该方法不能为矩阵设置初始值 
特殊矩阵的创建:
cv:: Mat e = cv:: Mat:: eye(20 ,20 ,CV_64F) cv:: Mat z = cv:: Mat:: ones(20 ,20 ,CV_32F) cv:: Mat o = cv:: Mat:: zeros(20 ,20 ,CV_8UC3) 
小矩阵的创建:
Mat  c =(Mat_<double>(3 ,3 )<<1 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,1 );
矩阵的直观表示:##### 
颜色空间缩减:##### 将现有的颜色空间进行映射,以获得较少的颜色数,目的是为了加快部分算法的处理速度
矩阵的遍历:##### #include  <QCoreApplication> #include  <opencv2/highgui/highgui.hpp> #include  <opencv2/core/core.hpp> #include  <opencv2/imgproc/imgproc.hpp> void changeImageUsePointer(cv ::Mat& sourceImage ,cv ::Mat& dstImage ,uchar  radio )  {     dstImage = sourceImage.clone() ;     int  rows = dstImage.rows;     int  cols = dstImage.cols *  dstImage.channels() ;     for (int  rowindex = 0  ;rowindex < rows ;rowindex++) {         uchar *element = dstImage.ptr<uchar>(rowindex);         for (int  colindex = 0 ; colindex < cols;colindex++) {             element[colindex ]  = static_cast<uchar>(element[colindex ] /radio)*radio;         }     } } void changeImageByIterator(cv ::Mat& sourceImage ,cv ::Mat& dstImage ,uchar  radio )  {     dstImage = sourceImage.clone() ;     cv::MatIterator_<cv::Vec3b> beginIterator = dstImage.begin <cv::Vec3b>() ;     cv::MatIterator_<cv::Vec3b> endIterator = dstImage.end <cv::Vec3b>() ;     cv::MatIterator_<cv::Vec3b> iterator;     for (iterator = beginIterator ;iterator != endIterator; ++iterator) {         (*iterator)[0 ]  = ((*iterator)[0 ] /radio)*radio;         (*iterator)[1 ]  = ((*iterator)[1 ] /radio)*radio;         (*iterator)[2 ]  = ((*iterator)[2 ] /radio)*radio;     } } void changeImageByLocation(cv ::Mat& sourceImage ,cv ::Mat& dstImage ,uchar  radio )  {     dstImage = sourceImage.clone() ;     int  cols = dstImage.cols;     int  rows = dstImage.rows;     for (int  row = 0 ;row < rows;row++) {         for (int  col = 0 ;col < cols;col++) {             uchar b = dstImage.at<cv::Vec3b>(row,col)[0 ] ;             dstImage.at<cv::Vec3b>(row,col)[0 ]  = (b/radio)*radio;             uchar g = dstImage.at<cv::Vec3b>(row,col)[1 ] ;             dstImage.at<cv::Vec3b>(row,col)[1 ]  = (g/radio)*radio;             uchar r = dstImage.at<cv::Vec3b>(row,col)[2 ] ;             dstImage.at<cv::Vec3b>(row,col)[2 ]  = (b/radio)*radio;         }     } } int  const PROCESS_TIME = 10 ;int  const COLOR_REDUCE = 10 ;int  main(int  argc, char  *argv[] ) {    cv::Mat srcImage = cv::imread("/home/jimmy/QtOpenCV/image/test_access.png" );     if (!srcImage.data) {         return -1 ;     }     cv::Mat dstImage;     dstImage.create(srcImage.rows,srcImage.cols,srcImage.type () );     int64  startTime = cv::getTickCount() ;     for (int  i = 0 ;i< PROCESS_TIME; i++) {         changeImageUsePointer(srcImage ,dstImage ,COLOR_REDUCE) ;     }     int64  endTime = cv::getTickCount() ;     qDebug("Consume Time by Pointer= %f" ,(endTime -startTime ) /cv::getTickFrequency() /PROCESS_TIME);     startTime = cv::getTickCount() ;     for (int  i = 0 ;i< PROCESS_TIME; i++) {         changeImageByIterator(srcImage ,dstImage ,COLOR_REDUCE) ;     }     endTime = cv::getTickCount() ;     qDebug("Consume Time by Pointer= %f" ,(endTime -startTime ) /cv::getTickFrequency() /PROCESS_TIME);     startTime = cv::getTickCount() ;     for (int  i = 0 ;i< PROCESS_TIME; i++) {         changeImageByLocation(srcImage ,dstImage ,COLOR_REDUCE) ;     }     endTime = cv::getTickCount() ;     qDebug("Consume Time by Pointer= %f" ,(endTime -startTime ) /cv::getTickFrequency() /PROCESS_TIME);     cv::namedWindow("Test Access SRC" ) ;     cv::namedWindow("Test Access Dest" ) ;     cv::imshow("Test Access SRC" ,srcImage);     cv::imshow("Test Access Dest" ,dstImage);     int  keycode = cv::waitKey(0) ;     if (keycode ==  27 ) {         cv::destroyAllWindows() ;     } }