您好,欢迎来到华佗健康网。
搜索
您的当前位置:首页OpenCV学习总结

OpenCV学习总结

来源:华佗健康网


一.基础:

IplImage *img=cvLoadImage(argv[1]);

//加载一幅图像至内存。

cvNamedWindow(“example1”,CV_WINDOW_AUTOSIZE);//产生一个窗口。将被现实的图像包含其中。第一个参数为窗口标题,第二个参数可为0或者CV_WINDOW_AUTOSIZE。0则图像不管窗口多大图像大小不变,而CV_WINDOW_AUTOSIZE则自动调整图像大小和窗口一样大。

cvShowImage(“example1”,img)//显示img指向的图像,显示在example1窗口中。

cvWaitKey(0);//在这一点程序暂停,直到某一事件触发,若里面为大于零的值,则等待此值毫秒后程序继续执行。

CvReleaseImage(&img);释放img指向图像的内存,并将img=NULL;

CvDestroyWindow(“Example1”);销毁窗口

二.Opencv基本数据类型

下面类型无说明则在cxtypes。h中定义

typedef struct CvPoint

{

int x;

int y;

}

CvPoint;//一般表示一个点的坐标

typedef struct CvPoint2D32f

{

float x;

float y;

}

CvPoint2D32f;

typedef struct CvPoint3D32f

{

float x;

float y;

float z;

}

CvPoint3D32f;

typedef struct CvPoint2Df

{

double x;

double y;

}

CvPoint2Df;

typedef struct CvPoint3Df

{

double x;

double y;

double z;

}

CvPoint3Df;

typedef struct

{

int width;

int height;

}

CvSize;其中CvSize2D32f不在解释

typedef struct CvScalar

{

double val[4];

}

CvScalar;//表示图像的RGB(A)分量

构造函数inline CvScalar cvScalar( double val0, double val1=0,

double val2=0, double val3=0 );其中val0,1,2依次为blue,green,red

其中CvRect则包含point和size,表示一个矩形

cvRectangle(myImg,cvPoint(5,10),cvPoint(20,20),cvScalar(255,255,255))//可画一个矩形

继承图

typedef struct CvMat

{

int type;

int step;//一行的字节数

/* for internal use only */

int* refcount;

int hdr_refcount;

union

{

uchar* ptr;

short* s;

int* i;

float* fl;

double* db;

} data;

Union//矩阵的行数n

{

int rows;

int height;

};

Union//矩阵的列数m

{

int cols;

int width;

};

}

CvMat;(n*m)

CvMat矩阵的创建与释放:

CvMat* cvCreateMat(int rows,int cols,int type);

cvReleaseMat(CvMat*);

CvMat*cvCloneMat(const cvMat*mat);

Void cvReleaseMat(CvMat**mat);

矩阵的数据的存取:

1.用CV_MAT_ELEM()宏存取矩阵

CvMat*mat = cvCreateMat(5,5,CV_32FC1);

Float element_3_2= CV_MAT_ELEM(*mat,float,3,2)

2.用CV_MAT_ELEM_PTR()设置一个数据

CvMat*mat = cvCreateMat(5,5,CV_32FC1);

Float element_3_2=7.7;

(*(float*) CV_MAT_ELEM_PTR(*mat,3,2))=element_3_2;

3.获取元素

uchar*cvPtr1D(const CvArr* arr,int idx0,int*type=NULL );//返回指向元素的指针,此函数可以通过移动uchar指针,高效的找到临近的元素

uchar*cvPtr2D(const CvArr* arr,int idx0, int idx1, int*type=NULL);

uchar*cvPtr3D(const CvArr* arr,int idx0, int idx1, int idx2, int*type=NULL);

uchar*cvPtrND(const CvArr* arr,int *idx,int*type=NULL,int

create_node=1,unsigned * precalc_hashval=NULL);

double cvGetReal1D(const CvArr* arr,int idx0);//返回元素的值

double cvGetReal2D (const CvArr* arr,int idx0, int idx1);

double cvGetReal3D (const CvArr* arr,int idx0, int idx1, int idx2);

double cvGetRealND(const CvArr* arr,int *idx);

.CvScalar*cvGet1D(const CvArr* arr,int idx0 ); //返回元素的值

CvScalar*cvGet2D (const CvArr* arr,int idx0, int idx1);

CvScalar*cvGet3D (const CvArr* arr,int idx0, int idx1, int idx2);

CvScalar*cvGetND (const CvArr* arr,int *idx);

设置元素:

Void cvSetReal1D(CvArr*arr,int idx0,double value);

Void cvSetReal2D(CvArr*arr,int idx0,int idx1,double value);

Void cvSetReal3D(CvArr*arr,int idx0,int idx1,int idx2,double value);

Void cvSetRealND(CvArr*arr,int* idx,double value);

Void cvSet1D(CvArr*arr,int idx0, CvScalar value);

Void cvSet2D(CvArr*arr,int idx0,int idx1, CvScalar value);

Void cvSet3D(CvArr*arr,int idx0,int idx1,int idx2, CvScalar value);

Void cvSetND(CvArr*arr,int* idx, CvScalar value);

对于单通道的矩阵,我们也可以用下面函数

Double cvmGet(const CvMat * mat,int row,int col);

Void cvmSet(CvMat *mat, int row, int col,double value);

cvmSet(mat,2,2,0.5000)等同于cvSetReal2D(mat,2,2,0.5000);

不同矩阵存放3维的对象的内存图:

:注意3*n(32FC1)的矩阵表示3维的对象。

IplImage数据结构:

typedef struct _IplImage

{

int nSize; /* sizeof(IplImage) */

int ID; /* version (=0)*/

int nChannels; /* Most of OpenCV functions support 1,2,3 or 4 channels */

int alphaChannel; /* ignored by OpenCV */

int depth; /* pixel depth in bits: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16S,

IPL_DEPTH_32S, IPL_DEPTH_32F and IPL_DEPTH_F are supported */

char colorModel[4]; /* ignored by OpenCV */

char channelSeq[4]; /* ditto */

int dataOrder; /* 0 - interleaved color channels, 1 - separate color

channels.

cvCreateImage can only create interleaved images */

int origin; /* 0 - top-left origin,

1 - bottom-left origin (Windows bitmaps style) */

int align; /* Alignment of image rows (4 or 8).

OpenCV ignores it and uses widthStep instead */

int width; /* image width in pixels */

int height; /* image height in pixels */

struct _IplROI *roi;/* image ROI. if NULL, the whole image is selected */

struct _IplImage *maskROI; /* must be NULL */

void *imageId; /* ditto */

struct _IplTileInfo *tileInfo; /* ditto */

int imageSize; /* image data size in bytes

(==image->height*image->widthStep

in case of interleaved data)*/

char *imageData; /* pointer to aligned image data */

int widthStep; /* size of aligned image row in bytes */

int BorderMode[4]; /* ignored by OpenCV */

int BorderConst[4]; /* ditto */

char *imageDataOrigin; /* pointer to very origin of image data

(not necessarily aligned) -

needed for correct deallocation */

}

IplImage;

重要参数:width height depth(表示深度)nchannals(一般取1,2,3,4表示通道) origin(可取IPL_ORIGIN_TL,IPL_ORIGIN_BL ,分别表示坐标原点在的左上角还是左下角)dataOrder(可取IPL_DATA_ORDER_PIXEL和IPL_DATA_ORDER_PLANE,分别表示数据时将像素点按不同的通道交错排列还是把像素同通道的值排在一起,形成通道平面)

widthStep(表示相邻两行同列之间的字节数,不和width相等,因为行末和行初可能有冗余字节) imageData(包含一个指向第一行数据的指针)ROI(感兴趣区域)

ROI操作:

Void cvSetImageROI(IplImage *image,CvRect rect);//设置感兴趣区域

Void cvResetImageROI(IplImage *image);//取消感兴趣区域

CvAddS(IplImage *image,CvScalar cvsca, IplImage *image)用cvsca添加至图像里面

矩阵操作函数:

Void cvabs(const CvArr* src, CvArr*dst)//计算src中的绝对值,将结果写入 dest

Void cvAbsDiff(const CvArr*src1,const CvArr*src2, CvArr*dst)//src1-src2的绝对值写入dst中

void cvAbsDiffS(const CvArr* src,CvScalar value, CvArr*dst)// src1-value的绝对值写入dst

void cvAdd(const CvArr* src1, const CvArr* src2,CvArr* dest, const CvArr* mask=NULL)//将src1+src2结果写入dst

void cvAddS(const CvArr* src,CvScalar value, CvArr* dst , const CvArr*

mask=NULL);

void cvAddWeighted(const CvArr* src1,double alpha, const CvArr* src2,double beta,double gamma ,CvArr*dst)//dst(x,y)=alpha*src1(x,y)+beta*src2(x,y)+gamma,可实现alpha融合,即一个图像和另一个图像的融合alpha属于0-1,beta=1-alpha,则前面方程可转化为标准的aphla融合方程。

CvScalar cvAvg(const CvArr *arr,const CvArr *mask=NULL);//求像素平均值

Void cvCmp(const CvArr *src1, const CvArr src2,CvArr* dst,int cmp_op);

Void cvCmpS(const CvArr *src, double value,CvArr* dst,int cmp_op);

//比较函数,其中cmp_op的取值可为

Int cvCountNonZero(const CvArr* arr)返回数组arr中非零像素的个数

Void cvCvtColor(const CvArr* src, CvArr* dst,int code)// 将源图像从一个颜色通道转换到另一个。Code可取一下值

还有很多取值…….

Double cvDet(const CvArr*mat)//计算矩阵的行列式,次数必须为单通道

CvSize cvGetSize(const CvArr*arr);//返回图像矩阵的大小

Double cvInvert)const CvArr* src,CvArr* dst, int method=CV_LU)//求矩阵的逆矩阵,返回值与所选方法有关

Void cvMinMaxLoc(const CvArr* arr,double * min_val,double* max_val,CvPoint *min_loc=NULL, CvPoint *man_loc=NULL, const CvArr* mask=NULL)求出矩阵的最大最小值,赋予两个double*参数,若两个CvPoint不为空,则将最大最小值的坐标传入,

mask不为空,则只计算非零元素

cvGEMM()//矩阵乘法函数

cvMul()//矩阵对应的元素相乘

cvNot (const CvArr* src,CvArr*dst)//矩阵的每个元素的每一位取反,例如:0X00->0XFF,0X83->0X7C

Void cvRepeat(const CvArr* src,CvArr* dst )将src中的元素复制到dst中,重复直到dst没有多余空间。

void cvSet(CvArr *arr,CvScalar value,const CvArr* mask=Null) 将arr中的值都设置为value

void cvSetIdentity(CvArr*arr)将列数和行数相等的元素设置为1,其余的设置为0;

void cvSplit(const CvArr* src,CvArr* dst0, CvArr* dst1, CvArr* dst2, CvArr* dst3)将src分为dst0123四个通道,如果小于4个通道则不需要的通道设置为NULL。

CvScalar cvSum(CvArr*arr)计算各个通道所有像素的总和

CvScalar cvTrace(const CvArr*mat);//求矩阵的迹,即对角线的元素和

void cvTranspose(const CvArr *src,CvArr * dst)//将src元素复制到dst中行号和列好调换的位置上

void cvXor(const CvArr* src1, const CvArr* src2, CvArr* dst, const CvArr* mask=Null)将src1和src2的每个元素的每个位做异或存入dst中

void cvXorS(const CvArr* src1, CvScalar value, CvArr* dst, const CvArr* mask=Null)将src1和value的每个位做异或存入dst中

void cvZero(CvArr* arr)将所有通道的所有元素赋为0.

画线函数:void cvLine(CvArr* array,CvPoint pt1,CvPoint pt2,CvScalar color,int thickness=1,int connectivity=8)在array指的图像上画一条从pt1-pt2的直线

画矩形函数:void cvRectangle(CvArr* array,CvPoint pt1,CvPoint pt2,CvScalar color,intthickness=1); intthickness若为(CV_FILL)-1则用线颜色填充该区域

画圆函数:void cvCircle (CvArr* array,CvPoint center,int radius,CvScalar color,int thickness =1,int connectivity=8);

画椭圆函数:void cvEllipse(CvArr* img,CvPoint center,CvSize axes,double angle,double start_angle,double end_angle,CvScalar color,int thickness=1,int line_type=8)其中angle指的是椭圆偏离水平多少度,逆时针为正。start_angle, end_angle分别为0,360

时才是一个完整的椭圆

也可用void cvEllipseBox(CvArr* img,CvBox2D box,CvScalar color,int

thickness=1,int line_type=8,int shift=0)画椭圆,其中box是椭圆的外接矩阵,其中

其中

画多边形:voidcvFillPoly()。。。。

输出字符:void cvPutText(CvArr* img,const char *text,CvPoint origin,const CvFont* font,CvScalar color);其中font可用下面函数初始化

void cvInitFont(CvFont* font,int font_face,double hscale,double vscale,fouble shear=0,int thickness =1,int line_type=8);

数据存储:

1.简单读取

cvMat*A=cvCreateMat(5,5,CV_32F);

cvSave(“my_matix.xml”,&A);//保存矩阵到一个XML文件中

cvMat*A1=(CvMat*)cvLoad(“my_matix.xml);//读取矩阵到A1中

2.用storage结构,其中在XML中为树形的结构存储

写入数据:

CvFileStorage*fs=cvOpenFileStorage(“cfg.xml”,0,CV_STORAGE_WRITE);标定CV_STORAGE_WRITE,表示是写入

cvWriteInt(fs,”frame_cout”,10);//写入一个整数,名字为frame_cout,若名字为0,则无名子,值为10

cvStartWriteStruct(fs,”frame_size”,CV_NODE_SEQ);写入一个结构,与下面的endwrite函数中间的为写入的结构体里面的数据

cvWriteInt(fs,0,300);

cvWriteInt(fs,0,200);

cvEndWriteStruct(fs);结束写入,结构体里保存了2个整数

cvWrite(fs,”color_cvt_matrix”,cmatrix);写入了一个矩阵

cvReleaseFileStorage(&fs);释放写入句柄

读出数据:

CvFileStorage*fs=cvOpenFileStorage(“cfg.xml”,0,CV_STORAGE_READ);标定CV_STORAGE_READ,表示是读出

int fra_count=cvReadIntByName(fs,0,”frame_count”,5)读出值按名字,其中5表示默认的值,如果读出错误则赋值为5

CvSeq *s=cvGetFileNodeByName(fs,0,”frame_size”)->data.seq;读结构体

int fram_wid=cvReadInt((CvFileNode*)cvGetSeqElem(s,0));

int fram_hei=cvReadInt((CvFileNode*)cvGetSeqElem(s,1));

CvMat*color_matrix=(CvMat*)cvReadByName(fs,0,”color_cvt_matrix”);读出矩阵

cvReadFileStorage(&fs)

四:HighGUI.H

载入图像:

IplImage *cvLoadImage(const char 的化

取单

* 值通

filename,int 可灰

以度

) 为,

iscolor=CV_LOAD_IMAGE_COLOR);//ISCOLORCV_LOAD_IMAGE_GRAYSCALE(

CV_LOAD_IMAGE_ANYCOLOR(源图像读入),默认为强制转换3通道8位。错误的话返回NULL

保存图像:

int cvSaveImage(const char * filename,const CvArr* image)成功返回1,否则返回0

其他窗口函数:

void cvMoveWindow(const char * name,int x,int y);将窗口移动到左上角X,Y的位置

void cvDestoryAllWindows(void);关闭所有窗口,并释放相关空间

int cvStartWindowThread(void);创建一个线程来自动更新窗口和处理窗口相关事件

鼠标事件:

鼠标事件必须通过回调函数处理,所以先应该创建回调函数,然后在OPENCV中注册此函数

void CvMouseCallback(int event,int x,int y,int flags,coid *param)

其中event表示事件,必须为下面的一个值

第二,三个参数表示鼠标触发的坐标点,坐标代表的是图像中的像素,与窗口无关。

flags的值可取

第四个参数一般为可传递的额外信息

注册函数:

void cvSetMouseCallback(const char * window_name,CvMouseCallback on_mouse,void *param=NULL);

第一个参数为回调函数注册到的窗口,也就是产生事件的窗口,第二个参数为回调函数名,第三个为额外信息

常用函数:IplImage* cvCreateImage( CvSize size, int depth, int channels );

参数说明:

size 图像宽、高.

depth 图像元素的位深度,可以是下面的其中之一:

IPL_DEPTH_8U - 无符号8位整型

IPL_DEPTH_8S - 有符号8位整型

IPL_DEPTH_16U - 无符号16位整型

IPL_DEPTH_16S - 有符号16位整型

IPL_DEPTH_32S - 有符号32位整型

IPL_DEPTH_32F - 单精度浮点数

IPL_DEPTH_F - 双精度浮点数

channels表示通道(1,2,3,4,其中为交叉存储)

见例子DrawBox

创建滑动条(trackbar)

void cvCreateTrackbar(const

*value,int

*char trackbar_name,const * char

window_name,int count,CVTrackbarCallback on_change);其中

trackbar_name为滑动条名字,window_name为附属窗口名字,value为滑动条在拖动时的位置,count为滑动条能拖动的最大值,on_change为回调函数,不需要可置NULL

回调函数CVTrackbarCallback指定的格式如下 void(*callback)(int position)

读取和设滚动条位置的函数:

int cvGetTrackbarPos(const char * trackbar_name,const char* window_name);

void cvSetTrackbarPos(const char* trackbar_name,const char*

window_name,int pos);

视频处理函数:

视频读入函数:CvCpture* cvCreatFileCapture(const char * filename);

CvCpture* cvCreateCameraCpture(int idx); CvCpture结构(视频读入结构)包含与视频相关的信息

idx 表示的是highgui是如何连接摄像机的,若取-1,则会自动弹出窗口选择

读视频函数:int cvGrabFrame(CvCapture *capture)将视频读入到一个余户不可见

的内存里,其中成功返回1,否则返回0;此函数执行一次,下次执行时会自动调用视频的下一帧

IplImage* cvRetrieveFrame(CvCapture*capture);进行图像必须的处理

IplImage* cvQueryFrame(CvCapture *capture);前两个函数的组合

cvReleaseCapture(CvCapture** capture)释放Cvcapture

下面可以对CvCapture 指向的视频进行想属性的读取与设置

double cvGetCaptureProperty(CvCapture* capture ,int property_id);

double cvSetCaptureProperty(CvCapture* capture,int property_id,double value);

o:指向视频的当前位置。以毫秒为单位

1:表示视频当前的位置,以帧为单位

2:用0-1之间的数表示视频的当前位置

3,4:表示当前读取的帧的宽度和高度

5:记录了视频在录入时每秒的帧数

6:表示视频的压缩方法,以4个字节表示

7:表示视频文件的总帧数

注意:其中有些参数时不可以设置的,比如6,而且所有参数都是以double返回,要转化类型在需要时

写视频:

CvVideoWriter* cvCreateVideoWriter(const char* filename,int fourcc,double fps,CvSize frame_size, int is_color=1)建立写入结构,fourcc参数可用宏CV_FOURCC(c0,c1,c2,c3)设置,color表示是否要颜色,默认要

int cvWriteFrame(CvVideoWriter* writer, const IplImage *image);写入帧

void cvReleaseVideoWriter(CvVideoWriter**witer);

一个重要的函数:

void cvConvertImage(const *CvArr src,CvArr* dst, int flags=0);将源图像转化为目标图像,其中目标图像必须时8位单通道或者3通道的,flags表示的是否将图像反转

四:图像处理

平滑处理:一般可减少图像上的噪声和失真

平滑处理函数:

void cvSmooth(const CvArr* src ,CvArr* dst,int smoothtype=CV_GAUSSIAN,int param1=3,int param2=0,double param3=0,double param4=0);

后面4个值由smoothtype决定,smoothtype的取值由下图给出

图像心态学处理

膨胀函数:void cvErode (IplImage * src,IplImage*dst,IplConvKernel* B =null,int iterations=1);此处理就是将B模板所覆盖的图像的像素值的最大值赋予此模板下的参考点,其操作与冈萨雷斯书上原理一样!此操作主要是正对2值图像, B为null时,默认为3*3的模板,参考点在中心。iterations表示膨胀迭代的次数。

腐蚀函数:void cvDilate (IplImage * src,IplImage*dst,IplConvKernel* B =null,int iterations=1); 此处理就是将B模板所覆盖的图像的像素值的最小值赋予此模板下的参考点,其操作与冈萨雷斯书上原理一样!此操作主要是正对2值图像, B为null时,默认为3*3的模板,参考点在中心。iterations表示膨胀迭代的次数。

IplConvKernel *cvCreateStructuringElementEx(int cols,int rows,int anchor_x, int anchor_y,int shape,int * value=NULL);cols(width) rows(height)表示核的大小,anchor_x,anchor_y表示参考点坐标,value表示模版型装。默认为矩形。

IplConvKernel *cvReleaseStructuringElement (IplConvKernel**element);

销毁核窗口

更通用的形态学处理函数

void cvMorphologyEx(const CvArr * src, CvArr * dst,CvArr*

temp,IplConvKernel* element,int operation,int iterations=1);

其中temp参数与源图像大小一样,可能会用到,operation表示操作的类型,可取下面值

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- huatuo0.com 版权所有 湘ICP备2023021991号-1

违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务