其实在看到Mat类的时候,感觉总是怎么那么多功能,没办法就是那么头疼,不过功能多,那么用法也就多,相对的会在图像处理中有很大的重要,所以后面不知不觉中就会回去看看他,这里用ROI来进步说一下Mat,看看实例的应用,这样更舒服一些。
然后再说一下颜色转化,因为在图像中,我们会看到彩色图像和灰度图像,他们有处理的共同的方法,也有自己的方法,每种类型都有自己的特征,所以在他们之间的转化是很重要的,这里用彩色和灰度转化,其他的看函数定义也是一样的,注意opencv的彩色是BGR不是RGB,这里在下一节的图像遍历中会用实例来说明。
最后是显示图像的升级,可以在一个窗口显示多张图片并保存输出,和工程代码、结果图像
一、Mat_ROI
Mat(int _rows, int _cols, int _type, constScalar& _s);
这个构造函数。
IplImage*是C语言操作OpenCV的数据结构,在当时C操纵OpenCV的时候,地位等同于Mat,OpenCV为其提供了一个接口,很方便的直接将IplImage转化为Mat,即使用构造函数
Mat(const IplImage* img, boolcopyData=false);
上面程序中的第二种方法就是使用的这个构造函数。
关于Mat数据复制:前面说过Mat包括头和数据指针,当使用Mat的构造函数初始化的时候,会将头和数据指针复制(注意:只是指针复制,指针指向的地址不会复制),若要将数据也复制,则必须使用copyTo或clone函数
再来一张图更好的理解
二、cvtcolor
CV_EXPORTS_W void cvtColor( InputArray src, OutputArray dst, int code, int dstCn=0 );
第一个参数是输入图像,第二个是输出图像,第三个是颜色空间转换的标识符,第四个是参数为目标图像的通道
下面是颜色空间种类,很多
COLOR_BGR2BGRA =0,
COLOR_RGB2RGBA =COLOR_BGR2BGRA,
COLOR_BGRA2BGR =1,
COLOR_RGBA2RGB =COLOR_BGRA2BGR,
COLOR_BGR2RGBA =2,
COLOR_RGB2BGRA =COLOR_BGR2RGBA,
COLOR_RGBA2BGR =3,
COLOR_BGRA2RGB =COLOR_RGBA2BGR,
COLOR_BGR2RGB =4,
COLOR_RGB2BGR =COLOR_BGR2RGB,
COLOR_BGRA2RGBA =5,
COLOR_RGBA2BGRA =COLOR_BGRA2RGBA,
COLOR_BGR2GRAY =6,
COLOR_RGB2GRAY =7,
COLOR_GRAY2BGR =8,
COLOR_GRAY2RGB =COLOR_GRAY2BGR,
COLOR_GRAY2BGRA =9,
COLOR_GRAY2RGBA =COLOR_GRAY2BGRA,
COLOR_BGRA2GRAY =10,
COLOR_RGBA2GRAY =11,
COLOR_BGR2BGR565 =12,
COLOR_RGB2BGR565 =13,
COLOR_BGR5652BGR =14,
COLOR_BGR5652RGB =15,
COLOR_BGRA2BGR565 =16,
COLOR_RGBA2BGR565 =17,
COLOR_BGR5652BGRA =18,
COLOR_BGR5652RGBA =19,
三、多图显示和保存
CV_EXPORTS_W bool imwrite( const string& filename, InputArray img,
const vector<int>& params=vector<int>());
第一个参数是文件名,第二个参数mat类型的图像数据,第三个暗示表示特定格式保存的参数编码
四、工程代码和结果展示
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include<iostream>
#include<opencv2\imgproc\imgproc.hpp>
using namespace cv;
using namespace std;
void showManyImages( const std::vector<cv::Mat> &srcImages)
{
int nNumImages = srcImages.size();
cv::Size nSizeWindows;
nSizeWindows = cv::Size(2,2);
int nShowImageSize = 200;
int nSplitLineSize = 15;
int nAroundLineSize = 50;
const int imagesHeight = nShowImageSize * nSizeWindows.width+
nAroundLineSize + (nSizeWindows.width - 1) *
nSplitLineSize;
const int imagesWidth = nShowImageSize*nSizeWindows.height +
nAroundLineSize + (nSizeWindows.height - 1) *
nSplitLineSize;
std::cout << imagesWidth << " " << imagesHeight << std::endl;
cv::Mat showWindowImages(imagesWidth, imagesHeight,
CV_8UC3,cv::Scalar(0,0,0));
int posX = (showWindowImages.cols-(nShowImageSize*
nSizeWindows.width+(nSizeWindows.width-1)*
nSplitLineSize))/2;
int posY = (showWindowImages.rows-(nShowImageSize*
nSizeWindows.height+(nSizeWindows.height-1)*
nSplitLineSize))/2;
std::cout << posX << " " << posY << std::endl;
int tempPosX = posX;
int tempPosY = posY;
for(int i=0; i < nNumImages; i++)
{
if(( i % nSizeWindows.width == 0) && ( tempPosX != posX ))
{
tempPosX = posX;
tempPosY += (nSplitLineSize + nShowImageSize);
}
cv::Mat tempImage = showWindowImages(cv::Rect(tempPosX,
tempPosY , nShowImageSize, nShowImageSize));
resize(srcImages[i], tempImage,
cv::Size( nShowImageSize , nShowImageSize));
tempPosX += (nSplitLineSize + nShowImageSize);
}
cv::imshow("showWindowImages", showWindowImages);
}
int main( )
{
Mat image_lena;
image_lena=imread("lena.jpg",CV_LOAD_IMAGE_COLOR);
namedWindow("原图",CV_WINDOW_AUTOSIZE);
imshow("原图",image_lena);
//这段可以选择不看
if (image_lena.empty()) { // error handling
std::cout << "Error reading image..." << std::endl;
return 0;
}
//显示出来看一下图像的大小,这样后面就好设置ROI的大小
//如果看了上一篇的image watch 它可以自动告诉你就不用写下面的话了
std::cout << "This image is " << image_lena.rows << " x "
<< image_lena.cols << std::endl;
//显示图像左上角1/4
Mat imagelenaROI = image_lena(Rect(0,0,image_lena.cols/2,image_lena.rows/2));
namedWindow("ROI图");
imshow("ROI图",imagelenaROI);
Mat graylena_image;
cvtColor( imagelenaROI, graylena_image, CV_BGR2GRAY );
//保存
imwrite("ROI灰度图片.jpg",graylena_image);
imwrite("ROI图.jpg",imagelenaROI);
std::vector<cv::Mat> srcImages(3);
srcImages[0] = cv::imread("lena.jpg");
srcImages[1] = cv::imread("ROI图.jpg");
srcImages[2] = cv::imread("ROI灰度图片.jpg");
showManyImages(srcImages);
waitKey();
return 0;
}
结果图像:
五、辅助Matlab
matlab中的图像格式转化也是类似的,提供了很多的函数
%数据类型
im2uint8()%将图像转化成uint8类型
im2uint16()%将图像转化成uint16类型
Im2double()%将图像转化成double类型
gray2ind()%灰度图转索引图
im2bw()%图像阈值转二值图
rgb2gray()%彩色转灰度
[I,MAP]=rgb2gray()%其中X是图像的数据,MAP是颜色表
写入函数的定义:
imwrite(A,FILENAME,FMT);
- FILENAME参数指定文件名
- FMT参数指定保存所采用的格式