OPENCV.docx
- 文档编号:7471050
- 上传时间:2023-01-24
- 格式:DOCX
- 页数:13
- 大小:21.92KB
OPENCV.docx
《OPENCV.docx》由会员分享,可在线阅读,更多相关《OPENCV.docx(13页珍藏版)》请在冰豆网上搜索。
OPENCV
四、图像处理
[编辑]
1、图像的内存分配与释放
[编辑]
(1)分配内存给一幅新图像:
IplImage*cvCreateImage(CvSizesize,intdepth,intchannels);
size:
cvSize(width,height);
depth:
像素深度:
IPL_DEPTH_8U,IPL_DEPTH_8S,IPL_DEPTH_16U,
IPL_DEPTH_16S,IPL_DEPTH_32S,IPL_DEPTH_32F,IPL_DEPTH_64F
channels:
像素通道数.Canbe1,2,3or4.
各通道是交错排列的.一幅彩色图像的数据排列格式如下:
b0g0r0b1g1r1...
示例:
//Allocatea1-channelbyteimage
IplImage*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
//Allocatea3-channelfloatimage
IplImage*img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
[编辑]
(2)释放图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
cvReleaseImage(&img);
[编辑]
(3)复制图像:
IplImage*img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
IplImage*img2;
img2=cvCloneImage(img1);//注意通过cvCloneImage得到的图像
//也要用cvReleaseImage释放,否则容易产生内存泄漏
[编辑]
(4)设置/获取感兴趣区域ROI:
voidcvSetImageROI(IplImage*image,CvRectrect);
voidcvResetImageROI(IplImage*image);
CvRectcvGetImageROI(constIplImage*image);
大多数OpenCV函数都支持ROI.
[编辑]
(5)设置/获取感兴趣通道COI:
voidcvSetImageCOI(IplImage*image,intcoi);//0=all
intcvGetImageCOI(constIplImage*image);
大多数OpenCV函数不支持COI.
[编辑]
2、图像读写
[编辑]
(1)从文件中读入图像:
IplImage*img=0;
img=cvLoadImage(fileName);
if(!
img)printf("Couldnotloadimagefile:
%s\n",fileName);
支持的图像格式:
BMP,DIB,JPEG,JPG,JPE,PNG,PBM,PGM,PPM,
SR,RAS,TIFF,TIF
OpenCV默认将读入的图像强制转换为一幅三通道彩色图像.不过可以按以下方法修改读入方式:
img=cvLoadImage(fileName,flag);
flag:
>0将读入的图像强制转换为一幅三通道彩色图像
=0将读入的图像强制转换为一幅单通道灰度图像
<0读入的图像通道数与所读入的文件相同.
[编辑]
(2)保存图像:
if(!
cvSaveImage(outFileName,img))printf("Couldnotsave:
%s\n",outFileName);
保存的图像格式由outFileName中的扩展名确定.
[编辑]
3、访问图像像素
[编辑]
(1)假设你要访问第k通道、第i行、第j列的像素。
[编辑]
(2)间接访问:
(通用,但效率低,可访问任意格式的图像)
对于单通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalars;
s=cvGet2D(img,i,j);//getthe(j,i)pixelvalue,注意cvGet2D与cvSet2D中坐标参数的顺序与其它opencv函数坐标参数顺序恰好相反.本函数中i代表y轴,即height;j代表x轴,即width.
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s);//setthe(j,i)pixelvalue
对于多通道字节型/浮点型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalars;
s=cvGet2D(img,i,j);//getthe(j,i)pixelvalue
printf("B=%f,G=%f,R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s);//setthe(j,i)pixelvalue
[编辑]
(3)直接访问:
(效率高,但容易出错)
对于单通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar*)(img->imageData+i*img->widthStep))[j]=111;
对于多通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+0]=111;//B
((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+1]=112;//G
((uchar*)(img->imageData+i*img->widthStep))[j*img->nChannels+2]=113;//R
对于多通道浮点型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+0]=111;//B
((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+1]=112;//G
((float*)(img->imageData+i*img->widthStep))[j*img->nChannels+2]=113;//R
[编辑]
(4)基于指针的直接访问:
(简单高效)
对于单通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
intheight=img->height;
intwidth=img->width;
intstep=img->widthStep;
uchar*data=(uchar*)img->imageData;
data[i*step+j]=111;
对于多通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
intheight=img->height;
intwidth=img->width;
intstep=img->widthStep;
intchannels=img->nChannels;
uchar*data=(uchar*)img->imageData;
data[i*step+j*channels+k]=111;
对于多通道浮点型图像(假设图像数据采用4字节(32位)行对齐方式):
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
intheight=img->height;
intwidth=img->width;
intstep=img->widthStep;
intchannels=img->nChannels;
float*data=(float*)img->imageData;
data[i*step+j*channels+k]=111;
[编辑]
(5)基于c++wrapper的直接访问:
(更简单高效)
首先定义一个c++wrapper‘Image’,然后基于Image定义不同类型的图像:
template
{
private:
IplImage*imgp;
public:
Image(IplImage*img=0){imgp=img;}
~Image(){imgp=0;}
voidoperator=(IplImage*img){imgp=img;}
inlineT*operator[](constintrowIndx){
return((T*)(imgp->imageData+rowIndx*imgp->widthStep));}
};
typedefstruct{
unsignedcharb,g,r;
}RgbPixel;
typedefstruct{
floatb,g,r;
}RgbPixelFloat;
typedefImage
typedefImage
typedefImage
typedefImage
对于单通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
BwImageimgA(img);
imgA[i][j]=111;
对于多通道字节型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
RgbImageimgA(img);
imgA[i][j].b=111;
imgA[i][j].g=111;
imgA[i][j].r=111;
对于多通道浮点型图像:
IplImage*img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
RgbImageFloatimgA(img);
imgA[i][j].b=111;
imgA[i][j].g=111;
imgA[i][j].r=111;
[编辑]
4、图像转换
[编辑]
(1)字节型图像的灰度-彩色转换:
cvConvertImage(src,dst,flags=0);
src=float/bytegrayscale/colorimage
dst=bytegrayscale/colorimage
flags=CV_CVTIMG_FLIP(垂直翻转图像)
CV_CVTIMG_SWAP_RB(置换R和B通道)
[编辑]
(2)彩色图像->灰度图像:
//UsingtheOpenCVconversion:
cvCvtColor(cimg,gimg,CV_BGR2GRAY);//cimg->gimg
//Usingadirectconversion:
for(i=0;i
gimgA[i][j]=(uchar)(cimgA[i][j].b*0.114+
cimgA[i][j].g*0.587+
cimgA[i][j].r*0.299);
[编辑]
(3)不同彩色空间之间的转换:
cvCvtColor(src,dst,code);//src->dst
code=CV_
e.g.:
CV_BGR2GRAY,CV_BGR2HSV,CV_BGR2Lab
[编辑]
5、绘图指令
[编辑]
(1)绘制矩形:
//在点(100,100)和(200,200)之间绘制一矩形,边线用红色、宽度为1
cvRectangle(img,cvPoint(100,100),cvPoint(200,200),cvScalar(0,0,255),1);
[编辑]
(2)绘制圆形:
//圆心为(100,100)、半径为20.圆周绿色、宽度为1
cvCircle(img,cvPoint(100,100),20,cvScalar(0,255,0),1);
[编辑]
(3)绘制线段:
//在(100,100)和(200,200)之间、线宽为1的绿色线段
cvLine(img,cvPoint(100,100),cvPoint(200,200),cvScalar(0,255,0),1);
[编辑]
(4)绘制一组线段:
CvPointcurve1[]={10,10,10,100,100,100,100,10};
CvPointcurve2[]={30,30,30,130,130,130,130,30,150,10};
CvPoint*curveArr[2]={curve1,curve2};
intnCurvePts[2]={4,5};
intnCurves=2;
intisCurveClosed=1;
intlineWidth=1;
cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);
voidcvPolyLine(CvArr*img,CvPoint**pts,int*npts,intcontours,intis_closed,
CvScalarcolor,intthickness=1,intline_type=8,intshift=0);
img图像。
pts折线的顶点指针数组。
npts折线的定点个数数组。
也可以认为是pts指针数组的大小
contours折线的线段数量。
is_closed指出多边形是否封闭。
如果封闭,函数将起始点和结束点连线。
color折线的颜色。
thickness线条的粗细程度。
line_type线段的类型。
参见cvLine。
shift顶点的小数点位数
[编辑]
(5)绘制一组填充颜色的多边形:
cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));
cvFillPoly用于一个单独被多边形轮廓所限定的区域内进行填充。
函数可以填充复杂的区域,例如,有漏洞的区域和有交叉点的区域等等。
voidcvFillPoly(CvArr*img,CvPoint**pts,int*npts,intcontours,CvScalarcolor,intline_type=8,intshift=0);
img图像。
pts指向多边形的数组指针。
npts多边形的顶点个数的数组。
contours组成填充区域的线段的数量。
color多边形的颜色。
line_type组成多边形的线条的类型。
shift顶点坐标的小数点位数。
[编辑]
(6)文本标注:
CvFontfont;
doublehScale=1.0;
doublevScale=1.0;
intlineWidth=1;
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC,hScale,vScale,0,lineWidth);
cvPutText(img,"Mycomment",cvPoint(200,400),&font,cvScalar(255,255,0));
其它可用的字体类型有:
CV_FONT_HERSHEY_SIMPLEX,CV_FONT_HERSHEY_PLAIN,CV_FONT_HERSHEY_DUPLEX,CV_FONT_HERSHEY_COMPLEX,CV_FONT_HERSHEY_TRIPLEX,CV_FONT_HERSHEY_COMPLEX_SMALL,CV_FONT_HERSHEY_SCRIPT_SIMPLEX,CV_FONT_HERSHEY_SCRIPT_COMPLEX,
五、矩阵处理
[编辑]
1、矩阵的内存分配与释放
[编辑]
(1)总体上:
OpenCV使用C语言来进行矩阵操作。
不过实际上有很多C++语言的替代方案可以更高效地完成。
在OpenCV中向量被当做是有一个维数为1的N维矩阵.
矩阵按行-行方式存储,每行以4字节(32位)对齐.
[编辑]
(2)为新矩阵分配内存:
CvMat*cvCreateMat(introws,intcols,inttype);
type:
矩阵元素类型.
按CV_
CV_8UC1、CV_32SC2.
示例:
CvMat*M=cvCreateMat(4,4,CV_32FC1);
[编辑]
(3)释放矩阵内存:
CvMat*M=cvCreateMat(4,4,CV_32FC1);
cvReleaseMat(&M);
[编辑]
(4)复制矩阵:
CvMat*M1=cvCreateMat(4,4,CV_32FC1);
CvMat*M2;
M2=cvCloneMat(M1);
[编辑]
(5)初始化矩阵:
doublea[]={1,2,3,4,
5,6,7,8,
9,10,11,12};
CvMatMa=cvMat(3,4,CV_64FC1,a);
//等价于:
CvMatMa;
cvInitMatHeader(&Ma,3,4,CV_64FC1,a);
[编辑]
(6)初始化矩阵为单位矩阵:
CvMat*M=cvCreateMat(4,4,CV_32FC1);
cvSetIdentity(M);//doesnotseemtobeworkingproperly
[编辑]
2、访问矩阵元素
[编辑]
(1)假设需要访问一个2D浮点型矩阵的第(i,j)个单元.
[编辑]
(2)间接访问:
cvmSet(M,i,j,2.0);//SetM(i,j)
t=cvmGet(M,i,j);//GetM(i,j)
[编辑]
(3)直接访问(假设矩阵数据按4字节行对齐):
CvMat*M=cvCreateMat(4,4,CV_32FC1);
intn=M->cols;
float*data=M->data.fl;
data[i*n+j]=3.0;
[编辑]
(4)直接访问(当数据的行对齐可能存在间隙时possiblealignmentgaps):
CvMat*M=cvCreateMat(4,4,CV_32FC1);
intstep=M->step/sizeof(float);
float*data=M->data.fl;
(data+i*step)[j]=3.0;
[编辑]
(5)对于初始化后的矩阵进行直接访问:
doublea[16];
CvMatMa=cvMat(3,4,CV_64FC1,a);
a[i*4+j]=2.0;//Ma(i,j)=2.0;
[编辑]
3、矩阵/向量运算
[编辑]
(1)矩阵之间的运算:
CvMat*Ma,*Mb,*Mc;
cvAdd(Ma,Mb,Mc);//Ma+Mb->Mc
cvSub(Ma,Mb,Mc);//Ma-Mb->Mc
cvMatMul(Ma,Mb,Mc);//Ma*Mb->Mc
[编辑]
(2)矩阵之间的元素级运算:
CvMat*Ma,*Mb,*Mc;
cvMul(Ma,Mb,Mc);//Ma.*Mb->Mc
cvDiv(Ma,Mb,Mc);//Ma./Mb->Mc
cvAddS(Ma,cvScalar(-10.0),Mc);//Ma.-10->Mc
[编辑]
(3)向量乘积:
doubleva[]={1,2,3};
doublevb[]={0,0,1};
doublevc[3];
CvMatVa=cvMat(3,1,CV_64FC1,va);
CvMatVb=cvMat(3,1,CV_64FC1,vb);
CvMatVc=cvMat(3,1,CV_64FC1,vc);
doubleres=cvDotProduct(&Va,&Vb);//向量点乘:
Va.Vb->res
cvCrossProduct(&Va,&Vb,&Vc);//向量叉乘:
VaxVb->Vc
注意在进行叉乘运算时,Va,Vb,Vc必须是仅有3个元素的向量.
[编辑]
(4)单一矩阵的运算:
CvMat*Ma,*Mb;
cvTranspose(Ma,Mb);//转置:
transpos
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- OPENCV