OpenCV 简介(cxcore, ml)

 

转载:http://www.cnblogs.com/okaimee/archive/2010/09/19/1830801.html

这里简单的记录一些 OpenCV 这个库的使用。这是用 C/C++ 写的一个和 computer vision 相关的库,一共含有 5 个组件:

  • CXCORE 是 OpenCV 里面使用的常用数据结构,以及处理这些数据结构的函数。
  • CV 是常用的 computer vision 相关的函数,比如计算 histogram、目标检测、跟踪的程序。
  • ML 是常用的 machine learning 相关的函数,如做分类的 naive Bayes、SVM 等等。
  • highgui 是一些比较高层函数,主要是做用户界面。
  • 另外还有一个从摄像头获取数据的 CVCAM 库,但是 1.1 里面似乎并进 highgui 了。

最新的是 1.1pre1,但是 debian 里面还是两年前的 1.0 版本的,这就需要自己编译一个了,后面有空学着 debian 的方式做个 deb 包好了。

OpenCV 的文档也算是还不错的了,除了函数的解释,部分功能还有例程、例子可以参考,这对对函数功能不是很清楚的人是非常有用的,比如我 :-D 这里不打算详细的记录 OpenCV 的每个功能,感兴趣的看文档吧。

 

先从 CXCORE 的基本结构讲起,OpenCV 里面提供了:

点 CvPoint(分 int 和 float 类型的,一般 int 的都没有后缀,float 会写 32f,double 是 64f;有 2D 和 3D 的版本),

大小 CvSize、

矩形 CvRect(用左下角的顶点坐标和宽、高表示)、

向量 CvScalar(4 个 double 那么大)。

更重要的就是存储矩阵用的 CvMat、CvMatND(多维矩阵,一般图片就是几个 channel,每个 channel 是一个 CvMat),稀疏矩阵 CvSparseMat。注意这里面有一个比较重要的成员,就是 int* refcount,这是允许多个“矩阵”(其实是 CvMatHeader 或者 CvMatNDHeader)对同一个矩阵进行引用,这时释放的时候涉及到矩阵元素的属主(ownership),只有当 refcount 为 0 的时候,释放的时候才会释放这些元素。数据的入口都是匿名 union,data 可以当作指针用。

图片一般存放在一个 IplImage 结构里面,这个结构里面有很多参数决定图片数据的类型,比如是 UINT8 还是 float 等。创建这些数据最基本的函数就是 cvCreate*,这是产生一个完整的结构,并且分配数据的内存,另有一种是仅仅分配一个 header,函数就是 cvCreate*Header,之后可以用 cvSet*Data 指定数据,释放这些结构使用 cvRelease* 和 cvRelease*Header。另外可以通过 cvInit* 和 cvInit*Header 初始化这些数据结构。我们发现 OpenCV 的函数都是以 cv 开头,而结构都是 Cv 开头。另外,进行深层 copy 使用 cvClone* 函数。如果需要手工增加/减少对数据的 refcount,可以使用 cvIncRefData、cvDecRefData。OpenCV 里面的数据用 CvArr,这是一个 void 类型,因此可以自由转换成为别的类型,如果需要访问 CvArr 类型的数据,可以用 cvGetRawData,下面是一个例子:

cvGetRawData( array, (uchar**)&data, &step, &size );
step /= sizeof(data[0]);
for( y = 0; y < size.height; y++, data += step )
for( x = 0; x < size.width; x++ )
data[x] = (float)fabs(data[x]);

这里的 data 是个 float*,因此每次递增量是 cvGetRawData 返回的 step 除以 sizeof(float)。类似的,cvGet* 命令将会返回对应的 header,如 cvGetMat、cvGetImage 等。

 

对于一个 CvMat,可以用 cvGetSubMat、cvGetRow(s),cvGetCol(s)、cvGetDiag 获得矩阵的部分,cvGetSize 获得矩阵的大小。遍历稀疏矩阵一般用 cvInitSparseMatIterator、cvGetNextSparseNode。另外可以用 cvGetElemType 获得元素种类,cvGetDim(s) 获得多维矩阵的大小。如果需要访问某些元素,可以用 cvPtr?D 获得指针,cvGet?D 获得元素值,另外有快速版本 cvmGet(对 2D 的矩阵)。对应有 Set 版本,用于赋值,特别的有 cvSetZero 和 cvSetIdentity 用于产生 0 矩阵和单位矩阵。另外和 matlab 类似有个 cvRange,cvReshape 改变矩阵大小,cvRepeat 和 repmat 类似,cvFlip 和 flip* 类似,cvSplit 切分矩阵,cvMerge 是逆操作。针对图片提供有 cvMixChannels。和 randperm 类似有一个 cvRandShuffle。

 

cvLUT 进行查表(某些图片是 indexed color),cvConvertScale 可以将不同的类型的数据(尤其是图片,有的用 float 的 0-1 表示,有的用 UINT8 表示)互相转化,它的一个特殊情况就是 cvConvertScaleAbs,cvAdd 将两个 CvArr 相加,cvAddS 加的是 scalar,cvAddWeighted 是加权和,cvSub 是相减,cvSubS 减标量,cvSubRS 是用标量减 CvArr,cvMul 是相乘,,cvDiv 是除,另外有 cvAnd(S)、cvOr(S)、cvXor(S)、cvNot、cvCmp(S);cvInRange(S) 可以检查元素是不是位于上下界中,cvMax(S)、cvMin(S) 求最大最小,cvAbsDiff(S) 求差的绝对值,cvCountNonZero 数非零元素个数,cvSum 求和,cvAvg 求平均,cvAvgSdv 计算均值和标准差,cvMinMaxLoc 返回最小最大的位置,cvNorm 计算范数(包括 L_1L_2L_\infty)。cvReduce 将矩阵变成向量。

 

OpenCV 也实现了一些代数运算,比如 cvDotProduct 计算内积,cvNormalize 将向量依照某种范数归一化,cvCrossProduct 计算叉积,cvScaleAdd 将标量相加,cvGEMM 是一个广义的矩阵乘积,包括每个矩阵是不是转置,然后相乘相加(用它定义了 cvMatMulAdd 和 cvMatMul),矩阵产生的变换 cvTransform、cvPerspectiveTransform,转置相乘 cvMulTransposed,迹 cvTrace,转置 cvTranspose、行列式 cvDet,cvInvert 求逆,cvSolve 求解线性方程组,cvSVD 计算奇异值分解,cvSVBkSb 用奇异值产生原来的矩阵,求对称矩阵的特征值 cvEigenVV,cvCovarMat 计算协方差矩阵,cvMahanobis 计算马氏距离,cvCalcPCA 计算主成分分解,cvProjectPCA 进行投影,cvBackProjectPCA 重构,。

 

下面是 OpenCV 里面常用的数学函数,如舍入的 cvRound、cvFloor 和 cvCeil,开方系列 cvSqrt、cvInvSqrt、cvCbrt,反正切 cvFastArctan、判断 cvIsNaN、cvIsInf,坐标转换 cvCartToPolar 和 cvPolarToCart,幂函数 cvPow,指数 cvExp,对数 cvLog,求解三次方程 cvSolveCubic,一般多项式 cvSolvePoly。

另外有一些随机数相关的函数,比如 cvRNG 产生一个 random number generator,cvRandArr 产生一个随机 CvArr,cvRandInt 返回一个随机整数,cvRandReal 产生 0-1 之间的随机实数。

另外有一些和 discrete Fourier transform 相关的东西,比如 cvDFT,cvDCT 等。

 

OpenCV 提供了一些动态存储的数据结构,这在很多操作中非常重要,比如需要进行检测某些特征点,那么用户并不知道将会发现多少个,所以最好的方法是使用 OpenCV 的动态数据结构,不过很遗憾的是,似乎这些结构不仅不能和 STL 的容器互相转换,接口也并不统一。

比较重要的类结构是 CvMemStorage,一般说来我们使用 cvCreateMemStorage 创建一个,并最后用 cvReleaseMemStorage 释放,OpenCV 里面很多函数需要 workspace 往往就是一个 CvMemStorage,如果需要自己进行更细致的操作,就需要了解一些比较基本的知识,比如它的结构是一个一个的 block 用双向链表链接(CvMemBlock 结构)而成,通过 CvMemStoragePos 记录位置,通过 cvCreateChildMemStorage 可以创建一个和 parent 相对独立的存储空间,临时存放数据非常方便。通过 cvClearMemStorage 将该结构管理的内存减到最少。CvMemStorage 提供了一个较大尺度的内存管理机制,而 CvSeq 就成为了一个容器,这个容器是一个双向链表(另有 CvSeqBlock 是个循环链表)。这个容器可以用 cvCreateSeq 创建(有一些内部支持的类型),cvSeqPush/cvSeqPop 是当作一个 stack 来进行入栈操作,类似的操作是 cvSeqPush/PopFront(队列常用操作),还可以一次插入多个 cvPush/PopMulti,插入 cvSeqInsert、删除 cvSeqRemove、删除所有元素 cvClearSeq、获得其中一个元素 cvGetSeqElem、获得一个元素的指标 cvGetElemIdx、转换成 array cvCvtSeqToArray、为 array 创建 Seq 的 header cvMakeSeqHeaderForArray,创建一个 CvSeq 的子序列 cvSlice、复制 cvCloneSeq、子序列的删除插入 cvRemove/InsertSlice、反转 cvSeqInvert、排序 cvSeqSort、搜索 cvSeqSearch。和 CvSeq 的输入输出相关的就是 CvSeqWriter 和 CvSeqReader 了,分别调用 cvStart/EndWriter/Reader 即可。

另外一个有用的数据结构是 CvSet,它是 CvGraph、SvSparseMat 和 CvSubdiv2D 的父类,其实现依赖于 CvSeq,创建一个 CvSet 和 CvSeq 类似为 cvCreateSet,添加、删除元素使用 cvSetAdd(cvSetNew 是一个 inline 版本)和 cvSetRemove(cvSetRemoveByPtr 使用指针删除),cvGetSetElem 通过一个索引获得元素,cvClearSet 清除里面的元素。

CvGraph 是用来表示一个带权有向或者无向图的数据结构,用 cvCreateGraph 创建,cvGraphAdd/RemoveVxt 添加顶点(另有一个ByPtr 版本),可以用 cvGetGraphVxt 获得顶点内容,cvGraphVxtIdx 获得元素的索引,cvGraphAdd/RemoveEdge 添加/删除边(也有 ByPtr 版本),另外有搜索边的 cvFindGraphEdge 以及 ByPtr 版本。通过 cvGraphVxtDegree 获得顶点的 degree,清除一个 graph 可以用 cvClearGraph,复制用 cvCloneGraph。遍历一个 graph 可以用 CvGraphScanner 这个数据结构,使用 cvCreateGraphScanner 创建深度优先便利的 scanner(用 Release 释放),这个 scanner 可以用一个 mask 来决定哪些地方是值得停下来供程序员处理的,有了这个 scanner 后用 cvGraphNextItem 就可以迭代了。

 

OpenCV 里面还有不少作图函数,就是在图片上画一些简单的几何形状,比如 Line、Rectangle、Circle、Ellipse、EllipseBox、FillPoly、FillConvexPoly、PolyLine。另外为了渲染字体,有 cvInitFont,cvPutText、cvGetTextSize 供使用。另外提供了 cv 里面 contour 的绘制函数(一般使用 cvFindContours 获得等高线,然后)cvDrawContours。通过 cvInitLineIterator 可以获得一条直线(指定起点和终点)上面的那些 pixel。cvClipLine 是将一条直线用一个矩形 clip。cvEllipse2Poly 将椭圆转换成为 polyline。

 

另外 cxcore 里面还提供了一个一致的存储数据的方式,这是通过 XML(或者 YAML)和 CvFileStorage 结构实现的,XML 本身是一个 tree 结构的东西,每个节点用 CvFileNode 表示其类型,用 CvAttrList 表示一个对象含有的属性列表。创建/释放一个 CvFileStorage 对象用 cvOpen/ReleaseFileStorage 函数。前者创建的 CvFileStorage 可用 cvStart/EndWriteStruct 或者 cvWriteInt/String/Real/Comment/RawData 进行写入,另外有 cvWrite 适合写入 CvSeq 等对象。读取使用比较笨的就是直接 cvRead*ByName,或者 cvGetFileNodeByName,比较快的是创建 CvStringHashNode,使用它查询 cvGetFileNode,然后从 CvFileNode 里面获得数据。另外,也有类似的 cvReadInt/Real/等等,以及 cvRead。

OpenCV 提供了一个基本的 RTTI 实现,这是利用 CvTypeInfo 实现的,利用 cvTypeOf 可以获得对应的类型,如果不确定有没有某个类型,可以用 cvFindType 搜索,通过 cvRegisterType 和 cvUnregisterType 注册、注销新类型。这样我们可以直接用 cvRelease 释放某个已知类型的对象、cvClone 复制一个,cvSave 和 cvLoad 实现该对象的存储。

 

cxcore 里面还有一些非常有用的功能,比如 cvCheckArr 检查有没有越界或者 NaN 类型。cvKMeans2 可以进行 kmeans 聚类,cvSeqPartition 用于将序列通过一个等价函数分成等价类。另外有一些用于出错处理的函数,比如每个 OpenCV 的函数源代码里面写的 CV_FUNCNAME( Name ) 就是用于报告出错函数的宏,等价于声明了一个静态的字符串,常用 CV_ERROR 报错,另有 CV_CHECK 检查出错代码,CV_CALL 提供统一的调用 cxcore 函数方法(自动 CV_CHECK),CV_ASSERT 判断条件(和 assert 类似)。另外有 cvGetErrStatus、cvSetErrStatus,设置出错模式 cvGet/SetErrMode(分 leaf 出错就退出,parent 调用 handler 后向上 unwind,silent 不调用 handler 直接向上 unwind),产生错误 cvError,可以用 cvErrorStr 获得解释。

 

和 OS 相关的函数,如 cvAlloc、cvFree,计算用时的 cvGetTickCount 和 cvgetTickFrequency,编写模块用的 cvRegisterModule、cvGetModuleInfo,另外还有获得线程、以及并行运算信息的函数,这里不加叙述了。

 

ml 这个库的结构相对简单,实现的 ML 的算法也仅仅那么几个最经典的,并不具有很好的扩展性。几乎所有的 ml 的模型都是继承 CvStatModel 这个类(其实是一个接口),主要有 clear() 清除模型,train() 训练,predict() 预测,以及 IO 相关的 save/load() 或者 read/write()。实现的算法有朴素贝叶斯分类器 CvNormalBayesClassifier,k-近邻 CvKNearest(不知道用了 kdtree 这些结构没),支持向量机 CvSVM(不支持用户自定义的核函数似乎,可以用 k-fold 交叉验证选择参数),决策树 CART CvDTree,集成算法 AdaBoost CvBoost 以及 boosted tree CvBoostTree、随机树 CvRTree、EM 算法 CvEM(仅仅对某些特定模型可以用),神经网络(两层前馈神经网络)CvANN,感觉就是可以用来做些简单的问题,但是不要指望能用到最新的一些模型。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: OpenCVSharp.ML是一个面向机器学习的OpenCVSharp扩展库。它提供了基于OpenCV的机器学习算法的封装和实现,包括支持向量机、K近邻、决策树、随机森林、Adaboost等算法OpenCVSharp.ML利用了OpenCV的强大功能和性能优势,并提供了易用的C#接口,使得用户可以方便地构建和训练机器学习模型,用于图像分类、目标检测、特征提取、数据聚类等任务。同时,OpenCVSharp.ML还支持使用自定义的特征提取函数和分类器,提高了扩展性和适用性。 尽管OpenCVSharp.ML主要是为视觉任务而设计的,但它也可以用于其他领域的机器学习任务。由于OpenCVSharp.MLOpenCV一样,均为开源软件,用户可以从源代码学习和了解算法和实现细节,也可以根据自己的需求进行自由的修改和扩展。 总之,OpenCVSharp.ML提供了强大和易用的OpenCV机器学习功能,为C#开发者提供了更便捷和高效的机器学习解决方案。它可以帮助用户快速构建和训练机器学习模型,实现各种视觉和数据处理任务。 ### 回答2: OpenCvSharp.ML是一个基于OpenCV的机器学习库,它可以用于图像分类、目标检测、人脸识别等领域。它提供了许多常见的机器学习算法,例如支持向量机、随机森林、朴素贝叶斯、K均值等等。此外,它还提供了各种特征提取工具,包括梯度方向直方图、Haar-like特征、SIFT和SURF特征等等。 OpenCvSharp.ML是一种高效、易于使用的工具,可以轻松地应用于各种计算机视觉领域的研究和开发。由于它的设计和实现,它具有高性能、可扩展性和易于集成的特点,能够满足不同任务和场景的需求。OpenCvSharp.ML一直被广泛应用于多种数据科学和计算机视觉项目,包括医学图像处理、自动驾驶、机器人导航、视频监控等多个领域。 ### 回答3: Opencvsharp.ml是一个基于OpenCV的机器学习库,它提供了各种常见的机器学习算法,如支持向量机、最近邻算法和神经网络等。Opencvsharp.ml可以让用户快速轻松地完成各种机器学习任务。它还提供了一个易于使用的API,可以方便地调用不同的机器学习算法。此外,Opencvsharp.ml可以完成分类、回归、聚类等各种任务,甚至可以进行图像分类和物体识别等计算机视觉任务。由于它是基于OpenCV的,因此它还可以轻松地与OpenCV图像处理库和其他OpenCV工具集成使用。总之,Opencvsharp.ml是一款功能强大、易于使用的机器学习库,它可以使机器学习任务更加高效、方便和准确。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值