您的位置:首页 > 运维架构

Opencv图像识别从零到精通(5)-----Mat_ROI、颜色转换、多图显示、保存输出

2016-07-14 16:22 711 查看
其实在看到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参数指定保存所采用的格式

对于matlab中查看数据,比较方便,一个是数据会显示,另外可以用whos I(I=imread('lena.jpg')),还可以用imfinfo()函数读取图像文件中的某些属性信息,比如修改日期、大小、格式、高度、宽度、色深、颜色空间、存储方式等



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: