矩阵和图像操作(3)

cvAvg

 
 
  1. CvScalar cvAvg(  
  2.     const CvArr*    arr,  
  3.     const CvArr*    mask = NULL 
  4. ); 

cvAvg()计算数组arr的平均像素值,如果mask为非空,那么平均值仅由那些mask值为非0的元素相对应的像素算出。

此函数还有别名cvMean(),但不推荐使用。

cvAvgSdv

 
 
  1. cvAvgSdv(  
  2.     const CvArr*    arr,  
  3.     CvScalar*       mean,  
  4.     CvScalar*       std_dev,  
  5.     const CvArr*    mask     = NULL 
  6. );  

【53】

此函数同cvAvg()类似,但除了求平均,还可以计算像素的标准差。

函数现在有不再使用的别名cvMean_StdDev()。

 
 
  1. cvCalcCovarMatrix  
  2. void cvCalcCovarMatrix(  
  3.     const CvArr** vects,  
  4.     int           count,  
  5.     CvArr*        cov_mat,  
  6.     CvArr*        avg,  
  7.     int           flags  
  8. ); 

给定一些向量,假定这些向量表示的点是高斯分布,cvCalcCovarMatrix()将计算这些点的均值和协方差矩阵。这当然可以运用到很多方面,并且OpenCV有很多附加的flags值,在特定的环境下会起作用(参见表3-4)。这些标志可以用标准的布尔或操作组合到一起。

表3-4:cvCalcCovarMatrix()可能用到的标志参数的值

标志参数的具体标志值

意义

CV_COVAR_NORMAL

计算均值和协方差

CV_COVAR_SCRAMBLED

快速PCA“Scrambled”协方差

CV_COVAR_USE_AVERAGE

输入均值而不是计算均值

CV_COVAR_SCALE

重新缩放输出的协方差矩阵

在所有情况下,在vects中是OpenCV指针数组(即一个指向指针数组的指针),并有一个指示多少数组的参数count。在所有情况下,结果将被置于cov_mat,但是avg的确切含义取决于标志的值(参见表3-4)。

标识CV_COVAR_NORMAL和CV_COVAR_SCRAMBLED是相互排斥的;只能使用其中一种,不能两者同时使用。如果为CV_COVAR_NORMAL,函数便只计算该点的均值和协方差。

 

因此,标准的协方差 由长度为n的m个向量计算,其中 被定义为平均向量 的第n个元素,由此产生的协方差矩阵是一个n × n矩阵, 比例z是一个可选的缩放比例,除非使用CV_COVAR_SCALE标志,否则它将被设置为1。【54】

如果是CV_COVAR_SCRAMBLED标志,cvCalcCovarMatrix ()将如下计算:

 

这种矩阵不是通常的协方差矩阵(注意转置运算符的位置),这种矩阵的计算来自同样长度为n的m个向量,但由此而来的协方差矩阵是一个m×m矩阵。这种矩阵是用在一些特定的算法中,如针对非常大的向量的快速PCA分析法(人脸识别可能会用到此运算)。

如果已知平均向量,则使用标志CV_COVAR_USE_AVG,在这种情况下,参数avg用来作为输入而不是输出,从而减少计算时间。

最后,标志CV_COVAR_SCALE用于对计算得到的协方差矩阵进行均匀缩放。这是前述方程的比例z,同标志CV_COVAR_NORMAL一起使用时,应用的缩放比例将是1.0 /m(或等效于1.0/count)。如果不使用CV_COVAR_SCRAMBLED,那么z的值将会是1.0/n(向量长度的倒数),cvCalcCovarMatrix()的输入输出矩阵都应该是浮点型,结果矩阵cov_mat的大小应当是n×n 或者 m×m,这取决于计算的是标准协方差还是scrambled的协方差。应当指出的是,在vects中输入的"向量"并不一定要是一维的;它们也可以是两维对象(例如图像)。

cvCmp和cvCmpS

 
 
  1. void cvCmp(  
  2.     const CvArr*    src1,  
  3.     const CvArr*    src2,  
  4.     CvArr*          dst,  
  5.     int             cmp_op  
  6. );  
  7. void cvCmpS(  
  8.     const CvArr*    src,  
  9.     double          value,  
  10.     CvArr*          dst,  
  11.     int             cmp_op  
  12. ); 

这两个函数都是进行比较操作,比较两幅图像相应的像素值或将给定图像的像素值与某常标量值进行比较。cvCmp()和cvCmpS()的最后一个参数的比较操作符可以是表3-5所列出的任意一个。【55】

表3-5:cvCmp()和cvCmpS()使用的cmp_op值以及由此产生的比较操作

cmp_op的值

比较方法

CV_CMP_EQ

(src1i == src2i)

CV_CMP_GT

(src1i > src2i)

CV_CMP_GE

(src1i >= src2i)

CV_CMP_LT

(src1i < src2i)

CV_CMP_LE

(src1i <= src2i)

CV_CMP_NE

(src1i != src2i)

表3-5列出的比较操作都是通过相同的函数实现的,只需传递合适的参数来说明你想怎么做,这些特殊的功能操作只能应用于单通道的图像。

这些比较功能适用于这样的应用程序,当你使用某些版本的背景减法并想对结果进行掩码处理但又只从图像中提取变化区域信息时(如从安全监控摄像机看一段视频流)。

cvConvertScale

 
 
  1. void cvConvertScale(  
  2.     const CvArr*    src,  
  3.     CvArr*          dst,  
  4.     double          scale = 1.0,  
  5.     double          shift = 0.0  
  6. ); 

cvConvertScale()函数实际上融多种功能于一体,它能执行几个功能中的任意之一,如果需要,也可以一起执行多个功能。第一个功能是将源图像的数据类型转变成目标图像的数据类型。例如,如果我们有一个8位的RGB灰度图像并想把它变为16位有符号的图像,就可以调用函数cvConvertScale()来做这个工作。

cvConvertScale()的第二个功能是对图像数据执行线性变换。在转换成新的数据类型之后,每个像素值将乘以scale值,然后将shift值加到每个像素上。

至关重要的是要记住,尽管在函数名称中"Convert"在"Scale"之前,但执行这些操作的顺序实际上是相反的。具体来说,在数据类型转变之前,与scale相乘和shift的相加已经发生了。【56】

如果只是传递默认值(scale = 1.0和shift = 0.0),则不必担心性能; OpenCV足够聪明,能意识到这种情况而不会在无用的操作上浪费处理器的时间。澄清一下(如果你想添加一些),OpenCV还提供了宏指令cvConvert(),该指令同cvConvertScale()一样,但是通常只适用于scale 和 shift 参数设为默认值时。

对于所有数据类型和任何数量通道cvConvertScale ()都适用,但是源图像和目标图像的通道数量必须相同。(如果你想实现彩色图像与灰度图的相互转换,可以使用cvCvtColor(),之后我们将会提到。) 【56~57】

cvConvertScaleAbs

 
 
  1. void cvConvertScaleAbs(  
  2.     const CvArr*    src,  
  3.     CvArr*          dst,  
  4.     double          scale = 1.0,  
  5.     double          shift = 0.0  
  6. ); 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值