1、创建图像
声明一个表示图像的变量,在OpenCV2中,这个变量是cv::Mat类型,该类是用于保存图像以及其他矩阵数据的数据结构。默认情况下它们的尺寸为0。
cv::Mat image; //这句话将创建一个宽高都为0的图像;
通过调用cv::Mat 的size()方法可以获取该图像的尺寸,该方法的返回值是一个结构体,包含着宽度和高度;
std::cout<<"size:"<<image.size().height<<","<<image.size().width<<std::endl;
cv::Mat类是用于保存图像以及其他矩阵数据的数据结构。默认情况下它们的尺寸为0,但是也可以指定初始尺寸:
cv::Mat ima(240,320,CV_8U,cv::Scalar(100));
同时,你需要指定矩阵中元素的类型,这里的CV_8U对应的是单字节的像素图像。字母U意味着无符号的(Unsigned).也可以使用字母S声明带符号的(Signed)类型。对于彩色图像,需要指定3个通道(CV_8UC3)。也可以声明16位或32位的(无符号的或带符号的)整数图像,如CV_16SC3。也可声明32位或64位的浮点数,如CV_32F。
补充:Mat的声明:
Mat m=Mat(rows, cols, type);
Mat m=Mat(Size(width,height), type);
type指矩阵中元素的类型,可以使CV_8U(无符号单字节像素),CV_8S(有符号单字节像素),CV_8UC3(3通道每个通道是无符号单字节),CV_16SC3(3通道,每个通道是16位有符号),CV_32F(单通道,32位浮点数)等等。。
如Mat m=Mat(240, 320,CV_8U,cv::Scalar(100)); //cv::Scalar(100)表示将单通道图像每个像素值初始化设为100
2、获取图像
一个简单的读取函数将进行文件读取、解码以及内存的分配。
image = cv::imread("img.jpg");
在opencv官方文档中原型是Mat imread(const string& filename, int flags=1 );
第一个参数,const string& 类型的filename,填入需要载入图片路径。
第二个参数,int型的flags,为载入标识,它指定一个加载图像的颜色类型。默认值为1,调用时可以忽略,标识载入3通道的彩色图像。
flags>0,返回一个3通道的彩色图像;
flags=0,返回灰度图像;
flags<0,返回包含Alpha通道的加载图像。
Mat image0=imread(“1.jpg”,2|4);//表示无损的原图像
Mat image1=imread(“1.jpg”,0);//表示载入灰度图
Mat image2=imread(“1.jpg”,199);//表示3通道的彩色图像
在使用该图像前需要先检查图像是否已经被正确读取,如果文件不存在、文件损坏或者格式无法识别,将会出现错误。检验方法如下:
if(!image.data)
{
cout << "Fail to load image!!" << endl;
system("pause");
return -1;
}
此处的成员变量data事实上是指向已分配的内存块的指针,包括图像数据。当不存在数据时,它被简单设置为0.
彩色图是三通道的(B,G,R),但是彩色图像的三通道的值相同时它也是灰色的。
3、显示图像
OpenCV的highgui模块实现了该功能。首先定义一个需要进行图像显示的窗口,接着指定需要显示的图像:
cv::namedWindow("Original Image"); //定义显示图像的窗口,参数为窗口名
cv::imshow("Original Image",image); //显示图像
4、将图像水平反转
OpenCV中的多个图像变换可以在原地进行,即不创建新的图像,直接修改输入图像的内容。flip函数便是其中一种,然而,也可以创建另外一个矩阵来保存输出结果。
cv::Mat result;
cv::flip(image,result,1); //正数表示水平反转,0表示垂直反转,负数表示既有水平也有垂直反转
结果显示在另一个窗口中:
cv::namedWindow("Output Image");
cv::imshow("Output Image",result);
由于这是个控制台窗口,它会在main函数的结尾处终止,因此我们添加额外的highgui函数使得程序退出前不停等待用户的按键输入:
cv::waitKey(0);
5、保存图像
将处理后的图像保存在磁盘上,通过下面的highgui函数得到实现:
cv::imwrite("output.bmp",result);
文件的后缀名决定了图像保存时的编码格式。
6、复制(可参考上一篇转载的博文)
在这里“=”运算符使得两个图像共享同一个数据,如果想要创建一个图像并复制原图像的数据到新的内存区域,则需要调用成员函数copyTo()。
cv::Mat image2, image3;
image2= result; // the two images refer tothe same data
result.copyTo(image3); // a new copy iscreated
所以我们可以放心地用函数返回一幅图像:
cv::Mat function() {
// create image
cv::Matima(240,320,CV_8U,cv::Scalar(100));
// return it
return ima;
}
在main函数中我们调用function():
// get a gray-level image
cv::Mat gray= function();
则gray与ima共享的是同一数据。
7.转化为灰度图
cvtColor(image, resImage, CV_RGB2GRAY);//把图片转化为灰度图
cvtColor第一个参数为原图片
第二个参数为目的图片
第三个参数为转化的掩码,表示转化的方向
附上总的程序:
/*****************************************************
** 第二讲 图像读取、显示、保存等基本操作
*****************************************************/
#include "cv.h"
#include "highgui.h"
#include <iostream>
using namespace std;
using namespace cv;
int main(int argc, char * argv[])
{
Mat image; //定义一个图像对象
image = imread("D:/1.png"); //读取图像
if (!image.data) //判断图像载入是否成功
{
cout << "Fail to load image!!" << endl;
system("pause");
return -1;
}
Mat src1;
image.copyTo(src1); //将图像image深拷贝到src1中
flip(src1, src1, 1); //对图像进行翻转
//namedWindow("翻转后的图像"); //创建窗口src1
imshow("翻转后的图像", src1); //在窗口src1中显示翻转后的图像
//namedWindow("my"); //创建窗口My
imshow("原图", image); //在窗口my中显示image图像
int key = waitKey(0); //等待按键的输入
imwrite("my.jpg", image); // 将image图像保存为my.jpg
cout << "Size of image is: " << image.size().height << ", " << image.size().width << endl;
cout << "ASCII of the key is: " << key << endl;
system("pause");
return 0;
}