矩阵和图像操作(6)

cvGetDiag ()类似于cvGetCol();它能从一个矩阵选择某一条对角线并将其作为向量返回。submat是一个矩阵类型的头指针。函数cvGetDiag()将填充该向量头指针中的各分量,以使用指向arr中的正确信息。注意,调用cvGetDiag()会修改输入的头指针,将数据指针指向arr对角线上的数据,实际上,并没有复制arr的数据。可选参数diag表明submat指向哪一条对角线的。如果diag被设置为默认值0,主对角线将被选中。如果diag大于0,则始于(diag,0)的对角线将被选中,如果diag小于0,则始于(0,-diag)的对角线将被选中。cvGetDiag()并不要求矩阵arr是方阵,但是数组submat长度必须与输入数组的尺寸相匹配。当该函数被调用时,最终的返回结果与输入的submat相同。

cvGetDims和cvGetDimSize

  
  
  
  
  1. int cvGetDims(  
  2.     const CvArr* arr,  
  3.     int* sizes=NULL 
  4. );  
  5. int cvGetDimSize(  
  6.     const CvArr* arr,  
  7.     int index  
  8. ); 

【63】

您一定还记得OpenCV中的矩阵维数可以远远大于2。函数cvGetDims()返回指定数组的维数并可返回每一个维数的大小。如果数组sizes非空,那么大小将被写入sizes。如果使用了参数sizes,它应该是一个指向n个整数的指针,这里的n指维数。如果无法事先获知维数,为了安全起见,可以把sizes大小指定为CV_MAX_DIM。

函数cvGetDimSize()返回一个由index参数指定的某一维大小。如果这个数组是矩阵或者图像,那么cvGetDims()将一直返回为2。 对于矩阵和图像,由cvGetDims()返回的sizes的次序将总是先是行数然后是列数。

cvGetRow和cvGetRows

  
  
  
  
  1. CvMat* cvGetRow(  
  2.     const CvArr* arr,  
  3.     CvMat* submat,  
  4.  
  5.     int row  
  6. );  
  7. CvMat* cvGetRows(  
  8.     const CvArr* arr,  
  9.     CvMat*submat,  
  10.     int start_row,  
  11.     int end_row  
  12. ); 

cvGetRow()获取矩阵中的一行让它作为向量(仅有一行的矩阵)返回。跟cvGetCol()类似,矩阵头指针submat将被修改为指向arr中的某个特定行,并且对该头指针的修改不涉及内存的分配和数据的复制;submat的内容仅是作为适当的修改以使它正确地指向arr中所选择的行。该指针所有数据类型。  cvGetRows()函数的工作原理与cvGetRow()完全一致,区别只在于前者将选择从start_row到end_row之间的所有行。这两个函数都返回一个的头指针,指向特定行或者多个行。

cvGetSize

  
  
  
  
  1. CvSize cvGetSize( const CvArr* arr ); 

它与cvGetDims()密切相关,cvGetDims()返回一个数组的大小。主要的不同是cvGetSize()是专为矩阵和图像设计的,这两种对象的维数总是2。其尺寸可以以CvSize结构的形式返回,例如当创建一个新的大小相同的矩阵或图像时,使用此函数就很方便。【64】

cvGetSubRect

  
  
  
  
  1. cvGetSubRect  
  2. CvSize cvGetSubRect(  
  3.     const CvArr* arr,  
  4.     CvArr* submat,  
  5.     CvRect rect  
  6. ); 

cvGetSubRect()与cvGetColumns()或cvGetRows()非常类似,区别在于cvGetSubRect()通过参数rect在数组中选择一个任意的子矩阵。与其他选择数组子区域的函数的函数一样,submat仅仅是一个被cvGetSubRect()函数填充的头,它将指向用户期望的子矩阵数据,这里并不涉及内存分配和数据的复制。

cvInRange和cvInRangeS

  
  
  
  
  1. void cvInRange(const CvArr* src,  
  2.     const CvArr* lower,  
  3.     const CvArr* upper,  
  4.     CvArr*       dst  
  5. );  
  6. void cvInRangeS(  
  7.     const CvArr* src,  
  8.     CvScalar     lower,  
  9.     CvScalar     upper,  
  10.     CvArr*       dst  
  11. ); 

这两个函数可用于检查图像中像素的灰度是否属于某一指定范围。cvInRange()检查,src的每一个像素点是否落在lower和upper范围中。如果src的值大于或者等于lower值,并且小于upper值,那么dst中对应的对应值将被设置为0xff;否则,dst的值将被设置为0。

cvInRangeS()的原理与之完全相同,但src是与lower和upper中的一组常量值(类型CvScala)进行比较。对于这两个函数,图像src可以是任意类型;如果图像有多个通道,那么每一种通道都将被分别处理。注意,dst的尺寸和通道数必须与src一致,且必须为8位的图像。

cvInvert

  
  
  
  
  1. double cvInvert(  
  2.     const CvArr* src,  
  3.     CvArr* dst,  
  4.     Int method = CV_LU 
  5. ); 

cvInvert()求取保存在src中的矩阵的逆并把结果保存在dst中。这个函数支持使用多种方法来计算矩阵的逆(见表3-8),但默认采取的是高斯消去法。该函数的返回值与所选用的方法有关。【65】

表3-8:cvInvert()函数中指定方法的参数值

方法的参数值

含义

CV_LU

高斯消去法 (LU 分解)

CV_SVD

奇异值分解(SVD)

CV_SVD_SYM

对称矩阵的SVD


就高斯消去法(method=CV_LU)来说,当函数执行完毕,src的行列式将被返回。如果行列式是0,那么事实上不进行求逆操作,并且数组dst将被设置为全0。

就CV_SVD或者CV_SVD_SYM,来说,返回值是矩阵的逆条件数(最小特征值跟最大特征值的比例)。如果src是奇异的,那么cvInvert()在SVD模式中将进行伪逆计算。

cvMahalonobis

  
  
  
  
  1. CvSize cvMahalonobis(  
  2.     const CvArr* vec1,  
  3.     const CvArr* vec2,  
  4.     CvArr*       mat  
  5. ); 

Mahalonobis距离(Mahal)被定义为一点和高斯分布中心之间的向量距离,该距离使用给定分布的协方差矩阵的逆作为归一化标准。参见图3-5。直观上,这是与基础统计学中的标准分数(Z-score)类似,某一点到分布中心的距离是以该分布的方差作为单位。马氏距离则是该思路在高维空间中的推广。

cvMahalonobis()计算的公式如下:

 

假设向量vec1对应x点,向量vec2是分布的均值 。mat是协方差矩阵的逆。

实际上,这个协方差矩阵通常用cvCalcCovarMatrix()(前面所述)来进行计算,然后用cvInvert()来求逆。使用SV_SVD方法求逆是良好的程序设计习惯,因为其中一个特征值为0的分布这种情况在所难免!

矩阵和图像操作(6)_第1张图片 
(点击查看大图)图3-5:数据在2D空间分布,3个叠加在一起的
椭圆分别对应到分布中心的马氏距离为1.0,2.0和3.0所有点
cvMax和cvMaxS
  
  
  
  
  1. void cvMax(  
  2.     const CvArr* src1,  
  3.     const CvArr* src2,  
  4.     CvArr*       dst  
  5. );  
  6. void cvMaxS(  
  7.     const CvArr* src,  
  8.     double       value,  
  9.     CvArr*       dst  
  10. ); 

【66】

cvMax()计算数组src1和src2中相对应的每像素一对中的最大值。而cvMaxS(),将数组src与常量参数value进行比较。通常,如果mask非空,那么只有与非0参数相对应的dst中的元素参与计算。

你可能感兴趣的:(opencv,图像矩阵操作)