#include <cxcore.h> #include <cv.h> #include <highgui.h> #define WINDOW_AUTOSIZE 1 //CV_WINDOW_AUTOSIZE 这个宏是存在的 using namespace cv;
//read Mat image; image =imread("1.png",1); if (image.data==0) //读数据失败 //write imwrite( "../../images/Gray_Image.jpg", gray_image ); //show namedWindow( "color image", CV_WINDOW_AUTOSIZE ); imshow( "color image", image ); //convert BGR to Gray //颜色转换函数 :从源image,到目gray_image, 宏CV_BGR2GRAY规定了颜色变换方法 cvtColor( image, gray_image, CV_BGR2GRAY );
//reference Mat A, C; // creates just the header parts A = imread(argv[1], CV_LOAD_IMAGE_COLOR); // here we'll know the method used (allocate matrix) Mat B(A); // Use the copy constructor C = A; // Assignment operator //如上A,B,C都是指向同一个数据matrix,操做其中一个,同时会影响其它的数据 //可是A,B,C有不一样的header,因此 这些不一样的header能够指向matrix中的一个子数据集 //ROI:region of interest //以下,截取一张图片中的一部分数据 的方法 Mat D (A, Rect(10, 10, 100, 100) ); // using a rectangle Mat E = A(Range::all(), Range(1,3)); // using row and column boundaries //copy Mat F = A.clone(); Mat G; A.copyTo(G); /* 注意:图片的容器使用了Mat对象,Mat对象由header和data组成 header是图片的信息:size and address pointer部分 data是图片的颜色信息 */
//加载显示 IplImage* img = cvLoadImage("13.png", 1); Mat mtx(img); // convert IplImage* -> Mat namedWindow("Display Image", WINDOW_AUTOSIZE ); //将image图片在Display Image这个窗口中显示 imshow("Display Image", mtx); cvWaitKey(0);//wait for ur enter press on the picture
图片就是一个平面矩阵,因此只要知道了行列坐标,就能够读 写对应位置的像素值了,
若是是灰度图像,每一个位置坐标上就只有一个值(用来表示灰度颜色)
若是是多通道的图像,每一个位置上,就有BGR三个值(用来表示彩色图像的三个份量)函数
当在图像数据加载到内存中时:因为内存地址是线性连续的,因此图像的存储方式也变成了线性的,线性存储也有利于快速的访问颜色数据(一个接一个的访问,确实会快点)优化
面使用image.isContinuous();这个函数来肯定图像数据的存储在内存中是否是连续的。 Mat image=imread(argv[1],1); if (image.data==0) { cerr<<"invalid image file to read!"<<endl; return 0; } //获得颜色数据在内存空间中存放时,是否 线性是连续的 image.isContinuous(); // 1:连续 0:不连续
if(image.depth()==CV_8U) //查看图像中,每一个通道的颜色数据 的深度, //如咱们经常使用的 BGR三通道,每一个通道的值的范围为0-255,那么就说颜色深度为8位 颜色深度就是表示 每一个通道颜色的数据用了多少位,用以下几个宏表示: CV_8U CV_16U CV_8S CV_16S CV_32S CV_32F CV_64F CV_Assert(image.depth() == CV_8U);//保证传入数据为true才能进行下面操做,不然会退出程序,并且会有下面的报错,而且显示在源程序中哪一行出错!很是好的debug函数 OpenCV Error: Assertion failed
下面的方法中,5,6,7,都是能够灵活的操做每一个通道的数据,用的比较多的是方法5,效率也高点!
//方法1: Mat image=imread("1.png",1); CV_Assert(image.depth() == CV_8U); //0==0 int channels=image.channels(); //获得图像有多少个颜色通道 int rows=image.rows; //获得图像有多少行 int cols=image.cols; //获得图像有多少列 cols=cols*channels; //列数xchannel数,才是更底层的图像的真实列数 unsigned char *pt; //用来指向 每一个颜色通道的 指针,用这个指针来读到每一个像素的颜色值,固然改变像素值也是写这个指针指向的数值 for (int i=0;i<rows;i++) { pt=image.ptr<unsigned char>(i); for (int j=0;j<cols;j++) { pt[j]=tables[pt[j]]; } } //小技巧:加快程序读写数据的速度 if (image.isContinuous())//若是颜色数据在内存中存放时,是连续存放的 { rows=1; //row=0 cols=cols*rows; //cols=0 ...一直到最后一个像素的颜色数据位置 } //注意 :必定不要把 cols=cols*channels;这一条忘记了,很是重要。 //方法2: if (image.isContinuous()) { uchar* p = image.data;//获得data数据的首地址, for( unsigned int i =0; i < ncol*nrows; ++i) { *p= table[*p]; p++; } }
// accept only char type matrices CV_Assert(I.depth() == CV_8U); const int channels = I.channels(); switch(channels) { case 1: { MatIterator_<uchar> it, end; for( it = I.begin<uchar>(), end = I.end<uchar>(); it != end; ++it) *it = table[*it]; break; } case 3: { MatIterator_<Vec3b> it, end; for( it = I.begin<Vec3b>(), end = I.end<Vec3b>(); it != end; ++it) { (*it)[0] = table[(*it)[0]];//能够方便的对每一个像素,三个通道进行操做 (*it)[1] = table[(*it)[1]]; (*it)[2] = table[(*it)[2]]; } } }
// accept only char type matrices CV_Assert(I.depth() == CV_8U); const int channels = I.channels(); switch(channels) { case 1: { for( int i = 0; i < I.rows; ++i) for( int j = 0; j < I.cols; ++j ) I.at<uchar>(i,j) = table[I.at<uchar>(i,j)]; break; } case 3: { Mat_<Vec3b> _I = I; //注意这里的新对象为 Mat_ (有下划线哦) for( int i = 0; i < I.rows; ++i) for( int j = 0; j < I.cols; ++j ) { _I(i,j)[0] = table[_I(i,j)[0]]; _I(i,j)[1] = table[_I(i,j)[1]]; _I(i,j)[2] = table[_I(i,j)[2]]; } I = _I; break; } }
Mat lookUpTable(1, 256, CV_8U); uchar* p = lookUpTable.data; for( int i = 0; i < 256; ++i) p[i] = table[i]; //把咱们以前的tables写到 Mat类型的对象中 LUT(I, lookUpTable, J); //I是输入的图像,J是改变后的图像, //不能地每一个通道作灵活的操做 //LUT的操做过程就是使用 原始图像的 颜色值做为 index,在lookuptable中查到新的颜色值, //注意 :这种方法OpenCV,作过优化,因此是最快的方法。