作为初学者,我对于Opencv的学习总是比较迷茫,还好可以借鉴别人的博客。
Mat类的内容比较多,这次我也只是对它有个基础、浅层的认识,在以后的学习和应用中我会根据需要和实例再不断补充学习。
一 背景
在Opencv1.X时代,数据类型为 IpIImage;
在Opencv2.X时代,数据类型为Mat.现在Mat更为常见。
二 用途
Mat类最重要的用途是作为存储图像的数据结构。至于Mat类如何存储图像(灰度图/彩色图),我参考的是别人的一篇博客。
http://lib.csdn.net/article/opencv/42000
暂且知道Mat由矩阵头(包含矩阵的大小、存储方法等)和一个指向矩阵的指针构成。
三 Mat如何读取图像的内容
在此主要介绍两种方法(借鉴别人的博客写了个例程供自己学习)
方法一:at操作(操作对象:灰度图像)
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("D:\\Tencent\\test.jpg"); //存放自己图像的路径
//namedWindow("Show");//在这里加不加这条语句,效果一样
imshow("Show", image);
waitKey(0);
resize(image, image, Size(375, 500));//resize为500*375的图像
cvtColor(image, image, CV_RGB2GRAY);//转为灰度图
imshow("image_ori", image);
waitKey(0);
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
image.at<uchar>(i, j) = i + j;
}
}
imshow("image_res",image);
waitKey(0);
return 0;
}
以上是对于灰度图像的处理,对于彩色图像的处理只需要把at<类型>中的类型改为Vec3b即可
例程如下:
#include <opencv2/opencv.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main()
{
Mat image = imread("D:\\Tencent\\test.jpg"); //存放自己图像的路径
/*namedWindow("Show");*/
imshow("Show", image);
resize(image, image, Size(375, 500));//resize为500*375的图像
//cvtColor(image, image, CV_RGB2GRAY);//转为灰度图
//imshow("image_ori", image);
for (int i = 0; i < image.rows; i++)
{
for (int j = 0; j < image.cols; j++)
{
/*image.at<uchar>(i, j) = i + j;*/
//iamge.at<Vec3b>(i, j)[0] = 255;//对于蓝色通道进行操作
image.at<Vec3b>(i, j)[1] = 255;//对于绿色通道进行操作
//img.at<Vec3b>(i, j)[2] = 255;//对于红色通道进行操作
}
}
imshow("image_res",image);
waitKey(0);
return 0;
}
方法二:采用指针对图像进行访问
以下给出对彩色图像操作的例程
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:\\Tencent\\test.jpg");
int rows = img.rows;//矩阵行
int cols = img.cols * img.channels();//彩色图像的列
if (img.isContinuous())//判断是否在内存中连续
{
cols = cols * rows;
rows = 1;//如果连续,则为一行
}
imshow("ori", img);
for (int i = 0; i<rows; i++)//控制行
{
//调取存储图像内存的第i行的指针
uchar *pointer = img.ptr<uchar>(i);
for (int j = 0; j<cols; j += 3)
{
//pointer[j] = 255;//对蓝色通道进行操作
//pointer[j+1] = 255;//对绿色通道进行操作
pointer[j + 2] = 255;//对红色通道进行操作
}
}
imshow("result", img);
waitKey();
return 0;
}
四 Mat类中常用的变量参数(Mat的声明在core.hpp中)
Mat类中有很多的变量参数,先熟悉以下几个:
- size(cols,rows) cols-列数,rows-行数
- CV_8UC3 其中8U表示8位无符号整数,C后为通道数
- Mat M1(3,2,cv_8uc3,scalar(0,0,225)); 定义Mat类的M为一个3行,2列,每列由3个元素(0,0,225)构成的 矩阵,其中的scalar()完成对每个元素的赋值。
- Mat M2(size(3,2),cv_8uc3,scalar(1,2,3));
- Mat M3(M2);
- step1(i)表示的是Mat中的每一维的通道数
- step[i]表示Mat中的每一维的大小(以字节为单位)
- size[i]表示Mat中元素的个数
- elemSize()表示每个元素的大小(以字节为单位)
通过实例理解上面定义对象的含义
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\core\core.hpp>
#include <iostream>
#include <time.h>
using namespace cv;
using namespace std;
int main()
{
Mat img = imread("D:\\Tencent\\test.jpg");
cout << "img.rows: " << img.rows <<endl<< " img.cols: " << img.cols <<endl<< " img.channels(): " << img.channels() << endl;
cout << "**********************" << endl;
cout << "img.step1(0): " << img.step1(0) << endl;
cout << "img.step1(1): " << img.step1(1) << endl;
cout << "img.step[0]: " << img.step[0] << endl;
cout << "img.step[1]: " << img.step[1] << endl;
cout << "img.size[0]: " << img.size[0] << endl;
cout << "img.size[1]: " << img.size[1] << endl;
cout << "img.elemSize(): " << img.elemSize() << endl;
cout << "img.elemSize1(): " << img.elemSize1() << endl;
uchar response;
cin >> response;
return 0;
}
由于刚学者用博客,只会加载图片,还不知道咋加载运行窗口,所以目前所有的实例都没有上传运行结果,但亲测无误。博客是一个很好的平台,写博客对自己的知识是一种归练,对别人也是一种帮助,我会紧跟大神步伐不断完善的。