- 一. 输入/输出
- ① 从一个文件中加载一个图像
- ② 写入图像到一个文件中
- 二. 图像的基本操作
- ① 访问像素强度值
- 三. 内存管理和引用计数
- 四. 原始操作
- 五. 可视化图像
Mat img = imread(filename);
如果你想读取一个jpg图像,默认会创建一个3通道的图像.如果你需要一个灰度图像,使用:
Mat img = imread(filename,IMREAD_GRAYSCALE);
注意:
② 写入图像到一个文件中文件的格式由其内容(前几个字节)决定. 将图像保存到文件.
imwrite(filename,img);
注意:
文件的格式由其扩展名决定.使用cv::imdecode和cv::imencode从内存中读取和写入图像,而不是文件.
为了得到像素的强度值,你必须知道图像的类型和通道的数量.下面是一个单通道灰度图像(类型 8UC1)和像素坐标x和y的示例:
Scalar intensity = img.at(Point(x,y));
现在让我们考虑一个BGR颜色排序的3通道图像(imread返回的默认格式):
Vec3b intesity = img.at(y,x); uchar blue = intesity.val[0]; uchar green = intesity.val[1]; uchar red = intesity.val[2];
你可以对浮点类型的图像使用相同的方法(例如,可以通过3通道图像上运行Soble来获得这样的图像)(仅限C++):
Vec3f intensity = img.at(y,x); float blue = intensity.val[0]; float green = intensity.val[1]; float red = intensity.val[2];
同样的方法可以用来改变像素强度:
img.at(y,x) = 128;
Opencv中的有一些函数,特别是来自calib3d模块的函数,比如cv::projectPoints,以Mat的形式获取二维或者三维点的数组.矩阵应该恰好包含一列,每一行对应一个点,对应的矩阵类型应该是32FC2或者32FC3.这样的矩阵可以很容易地从std::vector中构造(仅限C++):
vectorpoints; // ... fill the array Mat pointsMat = Mat(points);
你可以使用相同的方法访问这个矩阵中的一个点Mat::at(仅限C++):
Point2f point = pointsMat.at三. 内存管理和引用计数(i,0);
Mat是这样一中结构体,它保存了矩阵/图像特征(行数和列数,数据类型等)和一个指向数据的指针.因此,没有什么可以阻止我们拥有多个对应相同数据的Mat实例.Mat保持了一个引用计数,当特定的Mat实例被销毁的时候,它告诉数据是否必须被释放.下面是一个在不复制数据的情况下创建两个矩阵的示例(仅限C++):
std::vectorpoints; // .. fill the array Mat pointsMat = Mat(points).reshape(1);
结果,我们得到一个三列的32FC1矩阵,而不是1列的32FC3矩阵.pointsMat使用来自points的数据,销毁时不会释放内存.但是,在这个特殊的例子中,开发人员必须确保points的声明周期比pointsMat长.我们如果需要复制数据,可以使用cv::Mat::copyTo或者cv::Mat::clone()来完成.
Mat img = imread("image.jgp");
Mat img1 = img.clone();
可以为每个函数提供空的输出Mat.每个市县对目标矩阵调用Mat::create.如果矩阵为空,则此方法为其分配数据.如果它不是空的,并且具有正确的大小和类型,则该方法不执行任何操作.但是,如果大小或者类型与输入参数不同,则释放(或丢失)数据,并分配新数据.例如:
Mat img = imread("image.jgp");
Mat sobelx;
Sobel(img,sobelx,CV_32F,1,0);
四. 原始操作
矩阵上定了许多方便的运算符.例如,下面展示了我们如何从现有的灰度图像img中生成黑色图像
img = Scalar(0);
选择感应区的区域
Rect r(10,10,100,100); Mat smallImg = img(r);
将图像从彩色图像转换为灰度图像
Mat img = imread("image.jpg"); // loading a 8UC3 image
Mat gray;
cvtColor(img,gray,COLOR_BGR2GRAY);
将图像的数据类型从8UC1转换为32FC1:
src.convertTo(dst,CV_32F);五. 可视化图像
在开发的过程中查看算法的中间结果是非常有用的.Opencv提供了一种方便的可视化图像的方法.一个8U的图像可以显示使用:
Mat img = imread("image.jpg");
nameWindow("image",WINDOW_AUTOSIZE);
imshow("image",img);
waitKey();
通过调用waitKey()启动一个循环接收消息,等待图像串口的点击键盘.一个32F的图像需要转换为8U的类型,例如:
Mat img = imread("image.jgp");
Mat gray;
cvtColor(img,gray,COLOR_BGR2GRAY);
Mat sobelX;
Sobel(gray,sobelX,CV_32F,1,0);
double minVal,maxVal;
minMaxLoc(sobelX,&minVal,&maxVal);// find minimum and maximum intensities
Mat draw;
sobelx.convertTo(draw,CV_8U,255.0 / (maxVal - minVal),-minVal * 255.0 / (maxVal - minVal));
nameWindow("image" WINDOW_AUTOSIZE);
imshow("image",draw);
waitKey();
注意:
这里的cv::nameWindow不是必要的,因为它后面紧跟着cv::imshow,它可以用于更该窗口属性或者使用cv::createTrackbar时的时候使用.



