1.传统的lplImage * -------> Mat格式
IplImage* img = cvLoadImage("greatwave.png", 1);
Mat mtx(img); // IplImage* ->Mat 共享数据
2、Mat -----> IplImage:
(1)将Mat类型转换到 IplImage *类型
Mat image1;
IplImage *image2 = (&(IplImage)image1); //同样只是创建图像头,而没有复制数据。
cvsaveimage("c:\\image2.jpg",image2);//保存下来
(2)将Mat类型转换到 IplImage类型
只是创建图像头,而没有复制数据。
例:
IplImage ipl_img = img; // Mat -> IplImage
3、将CvMat类型转换为Mat类型
与IplImage的转换类似,可以选择是否复制数据。
Mat b = Mat(const CvMat* a, true);
//使用Mat的构造函数:Mat::Mat(const CvMat* m, bool copyData=false); 默认情况下copyData为false CvMat* a; //注意:以下三种效果一致,均为浅拷贝 Mat b(a); //a "copy" to b Mat b(a, false); //a "copy" to b Mat b = a; //a "copy" to b //注意:当将参数copyData设为true后,则为深拷贝(复制整个图像数据) Mat b = Mat(a, true); //a copy to b
4、将Mat类型转换为CvMat类型
与IplImage的转换类似,不复制数据,只创建矩阵头。
例:// 假设Mat类型的imgMat图像数据存在
CvMat cvMat = imgMat; // Mat -> CvMat
//注意:浅拷贝 Mat a; CvMat b = a; //a "copy" to b //注意:深拷贝 Mat a; CvMat *b; CvMat temp = a; //转化为CvMat类型,而不是复制数据 cvCopy(&temp, b); //真正复制数据 cvCopy使用前要先开辟内存空间
Mat之间的复制
//注意:浅拷贝 - 不复制数据只创建矩阵头,数据共享(更改a,b,c的任意一个都会对另外2个产生同样的作用) Mat a; Mat b = a; //a "copy" to b Mat c(a); //a "copy" to c //注意:深拷贝 Mat a; Mat b = a.clone(); //a copy to b Mat c; a.copyTo(c); //a copy to c
CvMat之间的复制
//注意:深拷贝 - 单独分配空间,两者相互独立 CvMat* a; CvMat* b = cvCloneMat(a); //copy a to b
5、 (1)IplImage转Cvmat
或者:Cvmat matObj;
* mat=cvGetmat(src,&matObj);
(2)Cvmat转IplImage
cvSaveImage("rice1.bmp",pImg);
4.1 IplImage与IplImage*
IplImage* imgTemp = cvCreateImage(cvSize(s_size, s_size), 8, 3);
IplImage temp = imgRGB.rowRange(rangeL, rangeR).colRange(valL, valR);
cvResize(&temp, imgTemp);
//to Mat
CxImage img;
img.Load(
"C:\\f.jpg"
);
uint8_t *buf=NULL;
int32_t
len=0;
bool
rs =img.Encode(buf,len,CXIMAGE_FORMAT_BMP);
cv::Mat temp2;
vector<uchar> buff2;
buff2.resize(len);
memcpy
(&buff2[0],buf,len);
temp2= cv::imdecode(buff2,1);
delete []buf; //要释放buf,这个buf在函数里分配了内存
cv::imshow(
"111"
,temp2);
cv::waitKey();
//to Cximage
vector<uchar> buff;
cv::imencode(
".bmp"
,temp2,buff);
CxImage img2(&buff[0],buff.size(),CXIMAGE_FORMAT_BMP);
img2.Blt(GetDlgItem(IDC_STATIC_P)->GetDC()->GetSafeHdc());
6、OpenCV2CXimage.h
- #pragma once
- /*
- * 类说明:OpenCV图像与CXimage图像互转
- * 用于OpenCV的图像与CXimage图像格式互转进行封装。 OpenCV的图像位数必须是大等于8的整数倍,支持BMP,JPG图像格式;CXimage的图像位数可以是1、2、4、8、、24,支持BMP,JPG,TIF,PNG,GIF图像格式。
- */
- #include <stdio.h>
- #include "h/ximage.h"
- #include <opencv2/opencv.hpp>
- #pragma comment(lib,"lib/cximage.lib")
- #pragma comment(lib,"lib/Jpeg.lib")
- #pragma comment(lib,"lib/libpsd.lib")
- #pragma comment(lib,"lib/png.lib")
- #pragma comment(lib,"lib/zlib.lib")
- #pragma comment(lib,"lib/tiff.lib")
- #pragma comment(lib,"lib/jasper.lib")
- #pragma comment(lib,"lib/libdcr.lib")
- #pragma comment(lib,"lib/jbig.lib")
- #pragma comment(lib,"lib/mng.lib")
- using namespace cv;
- using namespace std;
- #include <opencv2/opencv.hpp>
- #ifdef _DEBUG
- #pragma comment(lib, "opencv_core249d.lib")
- #pragma comment(lib, "opencv_highgui249d.lib")
- #pragma comment(lib, "opencv_imgproc249d.lib")
- #else
- #pragma comment(lib, "opencv_core249.lib")
- #pragma comment(lib, "opencv_highgui249.lib")
- #pragma comment(lib, "opencv_imgproc249.lib")
- #endif
- class OpenCV2CXimage
- {
- public:
- OpenCV2CXimage(void);
- ~OpenCV2CXimage(void);
- /*
- 功能说明: 获取黑点标记的方式
- 参数说明: cxImage 图像处理类
- 返回值: 黑点标记
- */
- static int OpenCV2CXimage::GetBlackColor(CxImage cxImage);
- /*
- 功能说明: 获取白点标记的方式
- 参数说明: cxImage 图像处理类
- 返回值: 黑点标记
- */
- static int OpenCV2CXimage::GetWhiteColor(CxImage cxImage);
- /*
- *功能说明:转换Cximage到IplImage(注:由于IplImage结构不支持图像像数非8位格式,所以强制转换成8位整数倍)
- *参数说明:src,表示原始Cximage图像;dst,[out] 表示Opencv图像IplImage结构
- *返回值:bool类型。true,表示成功;flase,表示失败。
- */
- bool Cximage2IplImage(CxImage *src,IplImage **dst);
- /*
- *功能说明:转换IplImage到Cximage
- *参数说明:src,表示Opencv图像IplImage结构;dst,[out] 表示输出Cximage图像;nBpp,表示输出Cximage图像位数占多少位[一个像数占多少位](1,8,24);
- *返回值:bool类型。true,表示成功;flase,表示失败。
- */
- bool IplImage2Cximage(IplImage *src,CxImage *dst,long nBpp=8);
- /*
- *功能说明:图象格式转换
- *参数说明:src,表示输入Cximage图像;dst,[out] 表示输出Cximage图像;imagetype,表示图象类型
- *返回值:bool类型。true,表示成功;flase,表示失败。
- */
- bool CxImageFormatConvert(CxImage *src,CxImage *dst,long imagetype = CXIMAGE_FORMAT_BMP);
- protected:
- RGBQUAD *m_pPal;//调色版
- int m_nPalatteCount;
- };
OpenCV2CXimage.cpp
- #include "StdAfx.h"
- #include "OpenCV2CXimage.h"
- #include <map>
- using namespace std;
- OpenCV2CXimage::OpenCV2CXimage(void)
- {
- m_pPal = NULL;
- m_nPalatteCount = 0;
- }
- OpenCV2CXimage::~OpenCV2CXimage(void)
- {
- if(m_pPal!=NULL)
- {
- delete []m_pPal;
- m_pPal = NULL;
- }
- }
- //函数名: GetBlackColor
- //功能: 获取黑点标记的方式
- //参数: cxImage 图像处理类
- //返回值: 黑点标记
- int OpenCV2CXimage::GetBlackColor(CxImage cxImage)
- {
- long i;
- int iBlackFlag = 0;
- RGBQUAD *pData = cxImage.GetPalette();
- long nPaletteSize = cxImage.GetPaletteSize()/sizeof(RGBQUAD);
- for(i=0;i<nPaletteSize;i++)
- {
- if(pData[i].rgbBlue==0 && pData[i].rgbGreen==0 && pData[i].rgbRed==0)
- {
- iBlackFlag = i;
- break;
- }
- }
- return iBlackFlag;
- }
- //函数名: GetWhiteColor
- //功能: 获取白点标记的方式
- //参数: cxImage 图像处理类
- //返回值: 黑点标记
- int OpenCV2CXimage::GetWhiteColor(CxImage cxImage)
- {
- long i;
- int iWhiteFlag = 255;
- RGBQUAD *pData = cxImage.GetPalette();
- long nPaletteSize = cxImage.GetPaletteSize()/sizeof(RGBQUAD);
- for(i=0;i<nPaletteSize;i++)
- {
- if(pData[i].rgbBlue==255 && pData[i].rgbGreen==255 && pData[i].rgbRed==255)
- {
- iWhiteFlag = i;
- break;
- }
- }
- return iWhiteFlag;
- }
- /*
- *功能说明:转换Cximage到IplImage
- *参数说明:src,表示原始Cximage图像;dst,[out] 表示Opencv图像IplImage结构
- *返回值:bool类型。true,表示成功;flase,表示失败。
- */
- bool OpenCV2CXimage::Cximage2IplImage(CxImage *src,IplImage **dst)
- {
- bool bRet = true;
- if(!src || !src->IsValid())
- {
- bRet = false;
- return bRet;
- }
- m_nPalatteCount = src->GetPaletteSize()/sizeof(RGBQUAD);;
- m_pPal = src->GetPalette();
- int iBackColor = GetBlackColor(*src);
- long i = 0,j = 0;
- long nImageWidth = 0,nImageHeight = 0;
- nImageWidth = src->GetWidth();
- nImageHeight = src->GetHeight();
- long nBitCunt = src->GetBpp();
- if(nBitCunt<=1)
- {
- *dst = cvCreateImage(cvSize(nImageWidth,nImageHeight),IPL_DEPTH_8U,1);
- cvZero(*dst);
- //转换Cximage to IplImage
- for(j=0;j<nImageHeight;j++)
- {
- for(i=0;i<nImageWidth;i++)
- {
- if(src->GetPixelIndex(i,j)==iBackColor)
- {
- CV_IMAGE_ELEM(*dst,uchar,nImageHeight-1-j,i) = 0;
- }
- else
- {
- CV_IMAGE_ELEM(*dst,uchar,nImageHeight-1-j,i) = 255;
- }
- }
- }
- }
- else if(nBitCunt<=8)
- {
- *dst = cvCreateImage(cvSize(nImageWidth,nImageHeight),IPL_DEPTH_8U,1);
- cvZero(*dst);
- //对应图像调色版与标准调色版的关系
- map<int,int> mapPalatte;
- RGBQUAD szSystemPal[256];
- int k = 0;
- for(k=0;k<256;k++)
- {
- szSystemPal[k].rgbBlue = k;
- szSystemPal[k].rgbGreen = k;
- szSystemPal[k].rgbRed = k;
- szSystemPal[k].rgbReserved = 0;
- }
- int m = 0;
- for(m=0;m<m_nPalatteCount;m++)
- {
- for(k=0;k<256;k++)
- {
- if(m_pPal[m].rgbBlue==szSystemPal[k].rgbBlue && m_pPal[m].rgbGreen==szSystemPal[k].rgbGreen && m_pPal[m].rgbRed==szSystemPal[k].rgbRed)
- {
- mapPalatte.insert(make_pair(m,k));
- break;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- //转换Cximage to IplImage
- map<int,int>::iterator iter;
- BYTE btIndex = 0;
- for(j=0;j<nImageHeight;j++)
- {
- for(i=0;i<nImageWidth;i++)
- {
- btIndex = src->GetPixelIndex(i,j);
- iter = mapPalatte.find(btIndex);
- if(iter!=mapPalatte.end())
- {
- btIndex = iter->second;
- }
- CV_IMAGE_ELEM(*dst,uchar,nImageHeight-1-j,i) = btIndex;
- }
- }
- }
- else if(nBitCunt<=16)
- {
- *dst = cvCreateImage(cvSize(nImageWidth,nImageHeight),IPL_DEPTH_16U,1);
- (*dst)->origin = 1;//底—左结构 (Windows bitmaps 风格)
- cvZero(*dst);
- //转换Cximage to IplImage
- for(j=0;j<nImageHeight;j++)
- {
- for(i=0;i<nImageWidth;i++)
- {
- BYTE *pSrc = src->GetBits(j) + 2*i;
- CV_IMAGE_ELEM(*dst,ushort,j,i) = (*pSrc) + (*(pSrc+1))*256;
- }
- }
- }
- else //24色
- {
- *dst = cvCreateImage(cvSize(nImageWidth,nImageHeight),IPL_DEPTH_8U,3);
- (*dst)->origin = 1;//底—左结构 (Windows bitmaps 风格)
- cvZero(*dst);
- //转换Cximage to IplImag
- memcpy((*dst)->imageData,src->GetBits(0),src->GetSize());
- }
- return bRet;
- }
- /*
- *功能说明:转换IplImage到Cximage
- *参数说明:src,表示Opencv图像IplImage结构;dst,[out] 表示输出Cximage图像;nBpp,表示输出Cximage图像位数占多少位[一个像数占多少位]
- *返回值:bool类型。true,表示成功;flase,表示失败。
- */
- bool OpenCV2CXimage::IplImage2Cximage(IplImage *src,CxImage *dst,long nBpp)
- {
- bool bRet = true;
- if(src==NULL || dst==NULL)
- {
- return false;
- }
- if(!(nBpp==1 || nBpp==8 || nBpp==24))
- {
- return false;
- }
- long i = 0,j = 0;
- CvSize csImageSize = cvGetSize(src);
- CxImage ciTmp;
- ciTmp.Create(csImageSize.width,csImageSize.height,src->depth,CXIMAGE_FORMAT_BMP);
- if(src->depth== IPL_DEPTH_8U)//灰度
- {
- ciTmp.SetStdPalette();
- BYTE gray = 0;
- for(j=0;j<csImageSize.height;j++)
- {
- for(i=0;i<csImageSize.width;i++)
- {
- gray = CV_IMAGE_ELEM(src,uchar,csImageSize.height-1-j,i);
- COLORREF color = 0;
- color |= gray;
- color |= gray << 8;
- color |= gray << 16;
- ciTmp.SetPixelColor(i,j,color);
- }
- }
- }
- else //彩色
- {
- //转换IplImag to Cximage
- memcpy(ciTmp.GetBits(0),src->imageData,src->imageSize);
- }
- //转换成需要的目标图像
- dst->Create(csImageSize.width,csImageSize.height,nBpp,CXIMAGE_FORMAT_BMP);
- if(nBpp==ciTmp.GetBpp())
- {
- dst->Copy(ciTmp);
- dst->Save("dst.bmp",CXIMAGE_FORMAT_BMP);
- }
- else
- {
- if(nBpp==1)//二值
- {
- //对应图像调色版与标准调色版的关系
- map<int,int> mapPalatte;
- RGBQUAD szSystemPal[256];
- int k = 0;
- for(k=0;k<256;k++)
- {
- szSystemPal[k].rgbBlue = k;
- szSystemPal[k].rgbGreen = k;
- szSystemPal[k].rgbRed = k;
- szSystemPal[k].rgbReserved = 0;
- }
- int m = 0;
- for(k=0;k<256;k++)
- {
- for(m=0;m<m_nPalatteCount;m++)
- {
- if(m_pPal[m].rgbBlue==szSystemPal[k].rgbBlue && m_pPal[m].rgbGreen==szSystemPal[k].rgbGreen && m_pPal[m].rgbRed==szSystemPal[k].rgbRed)
- {
- mapPalatte.insert(make_pair(k,m));
- break;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- byte btValue = 0;
- map<int,int>::iterator iter;
- long nImageWidth = 0;
- long nImageHeight = 0;
- if(ciTmp.GetBpp()>8)
- {
- ciTmp.GrayScale();
- }
- if(m_nPalatteCount==2) //表示原始的图象为二值图象
- {
- dst->SetPalette(m_pPal,m_nPalatteCount);
- btValue = 0;
- nImageWidth = ciTmp.GetWidth();
- nImageHeight = ciTmp.GetHeight();
- for(j=0;j<nImageHeight;j++)
- {
- for(i=0;i<nImageWidth;i++)
- {
- btValue = ciTmp.GetPixelIndex(i,j);
- iter = mapPalatte.find(btValue);
- if(iter!=mapPalatte.end())
- {
- btValue = iter->second;
- }
- dst->SetPixelIndex(i,j,btValue);
- }
- }
- }
- else
- {
- ciTmp.Threshold(128);
- dst->Copy(ciTmp);
- }
- }
- else if(nBpp==8)
- {
- //对应图像调色版与标准调色版的关系
- map<int,int> mapPalatte;
- RGBQUAD szSystemPal[256];
- int k = 0;
- for(k=0;k<256;k++)
- {
- szSystemPal[k].rgbBlue = k;
- szSystemPal[k].rgbGreen = k;
- szSystemPal[k].rgbRed = k;
- szSystemPal[k].rgbReserved = 0;
- }
- int m = 0;
- for(k=0;k<256;k++)
- {
- for(m=0;m<m_nPalatteCount;m++)
- {
- if(m_pPal[m].rgbBlue==szSystemPal[k].rgbBlue && m_pPal[m].rgbGreen==szSystemPal[k].rgbGreen && m_pPal[m].rgbRed==szSystemPal[k].rgbRed)
- {
- mapPalatte.insert(make_pair(k,m));
- break;
- }
- }
- }
- //////////////////////////////////////////////////////////////////////////
- byte btValue = 0;
- map<int,int>::iterator iter;
- long nImageWidth = 0;
- long nImageHeight = 0;
- if(ciTmp.GetBpp()!=8)
- {
- ciTmp.GrayScale();
- }
- if(m_nPalatteCount==8) //表示原始的图象为灰度图象
- {
- dst->SetPalette(m_pPal,m_nPalatteCount);
- btValue = 0;
- nImageWidth = ciTmp.GetWidth();
- nImageHeight = ciTmp.GetHeight();
- for(j=0;j<nImageHeight;j++)
- {
- for(i=0;i<nImageWidth;i++)
- {
- btValue = ciTmp.GetPixelIndex(i,j);
- iter = mapPalatte.find(btValue);
- if(iter!=mapPalatte.end())
- {
- btValue = iter->second;
- }
- dst->SetPixelIndex(i,j,btValue);
- }
- }
- }
- else
- {
- dst->Copy(ciTmp);
- }
- }
- else
- {
- if(ciTmp.GetBpp()==24)
- {
- dst->Copy(ciTmp);
- }
- else
- {
- byte btValue = 0;
- COLORREF clValue;
- map<int,int>::iterator iter;
- long nImageWidth = 0;
- long nImageHeight = 0;
- bRet = ciTmp.IncreaseBpp(24);
- dst->Copy(ciTmp);
- }
- }
- }
- return bRet;
- }
- //图象格式转换
- bool OpenCV2CXimage::CxImageFormatConvert(CxImage *src,CxImage *dst,long imagetype)
- {
- bool bRet = true;
- if(src==NULL || dst==NULL)
- {
- return false;
- }
- if(!(imagetype>0 && imagetype<=19))
- {
- return false;
- }
- if(src->GetType()==imagetype)
- {
- dst->Copy(*src);
- }
- else
- {
- dst->Create(src->GetWidth(),src->GetHeight(),src->GetBpp(),imagetype);
- src->SetType(imagetype);
- dst->Copy(*src);
- }
- return true;
- }
main函数:
- // OpencvtoCximg.cpp : 定义控制台应用程序的入口点。
- //
- #include "stdafx.h"
- #include "OpenCV2CXimage.h"
- int _tmain(int argc, _TCHAR* argv[])
- {
- // cvNamedWindow("img",CV_WINDOW_AUTOSIZE);
- //Cximage--->IplImage
- IplImage *img;
- OpenCV2CXimage o2i;
- CxImage cimg("gimg.bmp",CXIMAGE_FORMAT_BMP);
- CxImage *cimg1 = new CxImage();
- cimg1->Load("gimg.bmp",CXIMAGE_FORMAT_BMP);
- o2i.Cximage2IplImage(cimg1 ,&img);
- cvSaveImage("img.jpg",img);
- //cvShowImage("img",img);
- //cvWaitKey(0);
- //IplImage-->Cximage
- CxImage *cimg2 = new CxImage();
- IplImage *img1;
- img1=cvLoadImage("gimg.bmp",0);
- o2i.IplImage2Cximage(img1,cimg2,8);
- cimg2->Save("test2.bmp",CXIMAGE_FORMAT_BMP);
- //CxImage合并图片
- CxImage im1,im2,im3;
- int h1,w1,h2,w2,h3,w3,bpp;
- im1.Load("E:\\2.jpg");
- im2.Load("E:\\1.jpg");
- h1=im1.GetHeight();
- w1=im1.GetWidth();
- h2=im2.GetHeight();
- w2=im2.GetWidth();
- h3=h1;
- w3=w1+w2;
- bpp=im1.GetBpp();
- im3.Create(w3,h3,bpp);
- im3.MixFrom(im1,0,0);
- im3.MixFrom(im2,w1,0);
- im3.Save("e:\\3.jpg",CXIMAGE_FORMAT_JPG);
- //用CxImage给图片加上文字水印
- CxImage imagesy;
- if( !imagesy.Load("E:\\1.jpg", CXIMAGE_FORMAT_JPG))
- {
- return TRUE;
- }
- if (imagesy.IsValid())
- {
- CxImage::CXTEXTINFO textword;
- imagesy.InitTextInfo( &textword );
- _stprintf( textword.lfont.lfFaceName, _T("Times New Roman"));
- textword.lfont.lfCharSet = GB2312_CHARSET ;
- textword.lfont.lfWeight = 8 ;
- textword.lfont.lfItalic = 0 ;
- textword.lfont.lfUnderline = 0 ;
- textword.fcolor = RGB( 255,255,160 );
- textword.bcolor = RGB( 0, 80,160 );
- textword.opaque = 1; //背景
- textword.b_opacity = (float)(0)/(float)200.; //透明度
- textword.b_round = (BYTE) 10 ; //四舍五入为背景矩形半径
- textword.smooth = (BYTE)1; //平滑选项的文本
- _stprintf( textword.text, _T("水印文字") );
- imagesy.DrawStringEx(0,0,100,&textword);
- imagesy.Save("e:\\z2_sy.jpg",CXIMAGE_FORMAT_JPG);
- }
- return 0;
一.Mat基础(如果加了using namespace cv ,以下的cv:: 都可以省略)
cv::Mat a ;
//创建矩阵头
a = cv::imread(
"f:\\psb.jpg"
);
//读入图像
cv::Mat b = a ;
//复制
|
cv::Mat c = a.clone(); cv::Mat d ; a.copyTo(d);
- OpenCV中的内存分配是自动完成的(不是特别指定的话)
- 使用OpenCV的C++ 接口时不需要考虑内存释放问题
- Mat的赋值运算和拷贝构造函数只会拷贝矩阵头,仍然共同同一个矩阵
- 如果要复制矩阵数据,可以使用clone和copyTo函数
2.Mat存储方法
Mat的创建
cv::Mat img(2,2,CV_8UC3,cv::Scalar(0,0,255));
构造函数的前两个参数指定了矩阵的行和列
第三个参数指定矩阵元素的数据类型以及通道数,
Create方法
img.create(4,4,CV_8UC(2));
cv::Mat e = cv::Mat::eye(4,4,CV_64F); cv::Mat z = cv::Mat::ones(2,2,CV_32F); cv::Mat o = cv::Mat::zeros(3,3,CV_8UC1);
小矩阵的初始化
Mat c =(Mat_<double>(3,3)<<1,2,3,0,-1,0,4,5,6);
3.Mat的输入输出
使用imread函数,向Mat对象中写入一个图像。
a = cv::imread("f:\\psb.jpg");//读入图像
cv::Mat imread(const string& filename,int flags=1)
filename指定要读取图像的位置
使用imwrite函数,将Mat对象保存到指定的文件中。
imwrite的函数原型如下:
bool imwrite(const string& filename,InputArray img,constvector<int>& params=vector<int>())
bool imwrite(const string& filename,InputArray img,constvector<int>& params=vector<int>())
- JPEG,params用来指定图像的质量(0到100),默认的是95. CV_IMWRITE_JPEG_QUALITY
- PNG,params用来指定图像的压缩级别(0到9),压缩级别越高图像占用的空间越小,保存图像所用的时间越久。默认值是3. CV_IMWRITE_PNG_COMPRESSION
- PPM,PGM,PBM,params是一个标记(0或者1),默认的是1.CV_IMWRITE_PXM_BINARY
- #include <iostream>
- #include <opencv2/core/core.hpp>
- #include <opencv2/highgui/highgui.hpp>
- using namespace std;
- using namespace cv;
- Mat src;
- Mat image;
- string str = "./";
- /*创建alpha表,整体偏红色,左上角到右下角呈现从完全透明到完全不透明变化趋势*/
- void createAlphaMat(Mat &mat)
- {
- for (int i = 0; i < mat.rows; ++i) {
- for (int j = 0; j < mat.cols; ++j) {
- Vec4b& rgba = mat.at<Vec4b>(i, j);
- rgba[0] = UCHAR_MAX; //r分量一直最大,所以整体偏红
- rgba[1] = saturate_cast<uchar>((float (mat.cols - j)) / ((float)mat.cols) * UCHAR_MAX);
- rgba[2] = saturate_cast<uchar>((float (mat.rows - i)) / ((float)mat.rows) * UCHAR_MAX);
- rgba[3] = saturate_cast<uchar>(0.5 * (rgba[1] + rgba[2]));
- }
- }
- }
- int main()
- {
- /*采用默认参数进行图片的保存*/
- src = imread("test.jpg");
- imwrite(str+"原图.jpg", src); //c版本中的保存图片为cvSaveImage()函数,c++版本中直接与matlab的相似,imwrite()函数。
- imshow("src", src);
- Rect rect(src.cols/4, src.rows/4, src.cols/2, src.rows/2);
- image = src(rect);
- imwrite(str+"截取原图中的一部分区域小图.jpg", image);
- imshow("image", image);
- /*采用自己设置的参数来保存图片*/
- Mat mat(480, 640, CV_8UC4);
- createAlphaMat(mat);
- vector<int> compression_params;
- compression_params.push_back(CV_IMWRITE_PNG_COMPRESSION);
- compression_params.push_back(9); //png格式下,默认的参数为3.
- try {
- imwrite("alpha.png", mat, compression_params);
- }
- catch (runtime_error& ex) {
- fprintf(stderr, "Exception converting image to PNG format: %s\n", ex.what());
- return 1;
- }
- fprintf(stdout, "Saved PNG file with alpha data.\n");
- waitKey(0);
- return 0;
- }
生成的alpha表图像显示如下:
OpenCV提供了用以窗口的形式显示图片的方法,代码如下:
- Mat img = imread("f:\psb.jpg");
- const string name ="Hu";
- namedWindow(name);
- imshow(name,img);
- waitKey();
Mat矩阵中数据元素的地址计算公式:
addr(Mi0,i1,…im-1) = M.data + M.step[0] * i0 + M.step[1] * i1 + … + M.step[m-1] * im-1 。
其中 m = M.dims 是指M的维度
i. data:Mat对象中的一个指针,指向内存中存放矩阵数据的一块内存 (uchar* data).
ii. row: 行;col:列;rows:行数;cols:列数。
iii. dims :Mat所代表的矩阵的维度,如 3 * 4 的矩阵为 2 维,3 * 4 * 5 的为3维.
iv. channels:通道,矩阵中的每一个矩阵元素拥有的值的个数,比如说 3 * 4 矩阵中一共 12 个元素,如果每个元素有三个值,那么就说这个矩阵是 3 通道的,即 channels = 3。常见的是一张彩色图片有红、绿、蓝三个通道。但是opencv用imread(opencv读图的函数)读进来的图像,三通道存放顺序为B、G、R。
v. depth:深度,即每一个像素的位数(bits),在opencv的Mat.depth()中得到的是一个 0 – 6 的数字,分别代表不同的位数:enum { CV_8U=0, CV_8S=1, CV_16U=2, CV_16S=3, CV_32S=4, CV_32F=5, CV_64F=6 }; 可见 0和1都代表8位, 2和3都代表16位,4和5代表32位,6代表64位;
vi. step:是一个数组,定义了矩阵的布局,具体见下面图片分析,另外注意 step1 (step / elemSize1),M.step[m-1] 总是等于 elemSize,M.step1(i)返回的是第i维的步长,因此M.step1(m-1)总是等于 channels,m是M的维度;这里是解释步长step[k]的,步长也可以看作是与第k维的存储单位,在2维的矩阵中,因为存储是按照行的顺序存储的,整个矩阵存储为一个平面,所以第k=0维的步长也就是单位肯定就是一行所占的字节数;如果是3维的话,第0维是按照面为单位来存储的,第1维是按照行为单位来存储的,第2维是按照元素类型为单位存储的,每个元素类型是基本类型(即uchar,float,short等等)与通道数的乘积...;也就是基本数据类型与通道数组成元素,多个元素组成了行,多行组成了面,多个面组成了3维体,多个3维体 组成4维超体。。。以此类推,如此看来某一维的步长应该等于高一维的步长step*低一维的大小size 。
vii. elemSize : 矩阵中每一个元素的数据大小,如果是n通道,就是(n*数据类型)。如果Mat中的数据的数据类型是 CV_8U 那么 elemSize = 1,CV_8UC3 那么 elemSize = 3,CV_16UC2 那么 elemSize = 4;记住另外有个 elemSize1 表示的是矩阵中数据类型的大小,即 elemSize / channels 的大小。
像素位深度是指每个像素所用的位数(bit),像素位深度决定了彩色图像的每个像素可能有的颜色数,或者确定灰度图像的每个像素可能有的灰度级数。例如,一幅彩色图像的每个像素用R、G、B三个分量来表示,若每个分量用8位,那么一个像素共用24位表示,就说像素的深度为24位,每个像素可以是224,即16777216〔千万级〕种颜色中的一种。在这个意义上, 往往把像素的位深度说成是图像深度。表示一个像素的位数越多,它能表达的颜色数目就越多, 而它的深度就越深。虽然像素位深度或图像深度可以很深,但由于设备本身的限制,加上人眼自身分辨率的局限,一般情况下,一味追求特别深的像素深度没有意义。因为,像素深度越深,数据量越大,所需要的传输带宽及存储空间就越大。相反,如果像素深度太浅,会影响图像的质量,图像看起来让人觉得很粗糙而不自然。
提示:假如像素位深度是8(bit),那么以虚线框中4个像素点而言,以4 :2:0格式为例,釆样总共为6个采样点(4个亮度分量加2个色度分量),总共需要6×8=48比特,平均每个像素48/4=12比特,这就是为什么有些情况下4 :2:0采样格式也被称为“12比特每像素采样”的原因。