简介
在机器学习中,经常需要用到矩阵计算。因此从本篇开始整理下opencv实现的矩阵计算相关函数使用。
矩阵初始化
具体代码
这里初始化了两个3X3矩阵,并将它的数据显示出来:
double x[ 3 ] [ 3 ] = { { 1 , 50 , - 100 } , { 1 , - 110 , 220 } , { - 1 , 150 , 150 } } ;
double y[ 3 ] [ 3 ] = { { 1 , 0 , 0 } , { 0 , 1 , 0 } , { 0 , 0 , 1 } } ;
void showMatdate( Mat tmpMat) {
int i, j;
CvScalar s1;
Width = tmpMat.rows ;
Height = tmpMat.cols ;
IplImage tmp;
tmp = tmpMat;
for ( i= 0 ; i< Width; i++ ) {
for ( j= 0 ; j< Height; j++ ) {
s1 = cvGet2D( & tmp, i, j) ;
printf ( "%0.1lf " , s1.val [ 0 ] ) ;
}
printf ( "\n " ) ;
}
printf ( "\n \n " ) ;
}
int main( int argc, char * argv[ ] ) {
/*************初始化矩阵*****************************/
mat1 = Mat( 3 , 3 , CV_64FC1, x) ;
src1 = mat1;
mat2 = Mat( 3 , 3 , CV_64FC1, y) ;
src2 = mat2;
/*************显示矩阵数据***************************/
printf ( "mat1:\n " ) ;
showMatdate( mat1) ;
printf ( "mat2:\n " ) ;
showMatdate( mat2) ;
return 0 ;
}
结果显示
矩阵绝对值之差
具体代码
/*************两个矩阵绝对值之差*********************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvAbsDiff( & src1, & src2, & src3) ;
printf ( "cvAbsDiff(mat1, mat2):\n " ) ;
showMatdate( mat3) ;
结果显示
矩阵与数值差的绝对值
具体代码
/*************矩阵与数值差的绝对值*******************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvAbsDiffS( & src1, & src3, Scalar( 5 ) ) ;
printf ( "cvAbsDiffS(mat1, 5):\n " ) ;
showMatdate( mat3) ;
结果显示
矩阵相加
具体代码
/************两个矩阵相加***************************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvAdd( & src1, & src2, & src3) ;
printf ( "cvAdd(mat1, mat2):\n " ) ;
showMatdate( mat3) ;
结果显示
矩阵权重相加
具体代码
/**********两个矩阵以权重形式相加******************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvAddWeighted( & src1, 0.5 , & src2, 0.5 , 3 , & src3) ;
printf ( "cvAddWeighted(mat1, 0.5,mat2, 0.5, 3):\n " ) ;
showMatdate( mat3) ;
计算公式为:src3 = src1 * 0.5 + src2 * 0.5 + 3;
结果显示
矩阵的与计算
具体代码
/*******************矩阵与计算**********************
*******可以使用掩码来决定计算被的数据元素*********
*******对应的还有cvNot cvOr cvXor *****************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvAnd( & src1, & src2, & src3) ;
printf ( "cvAnd(mat1, mat2):\n " ) ;
showMatdate( mat3) ;
结果显示
矩阵比较
具体代码
/******************两个矩阵比较********************/
int tmp = CMP_EQ;
mat3 = Mat( 3 , 3 , CV_8UC1) ;
src3 = mat3;
mat1.convertTo ( mat1, CV_8UC1) ;
mat2.convertTo ( mat2, CV_8UC1) ;
cvCmp( & src1, & src2, & src3, tmp) ;
printf ( "cvCmp(mat1, mat2):\n " ) ;
showMatdate( mat3) ;
需要先把mat1和mat2转换为格式CV_8UC1,然后室友函数cvCmp进行比较。注意cvCmp的flag标志,本例使用的是相等:CMP_EQ,也就是将mat1和mat2
矩阵对应位置的数值比较,如果相等,则mat3对应位置数值设置为255,否则设置为0。
对应的flag有:
CMP_EQ src1 is equal to src2.
CMP_GT src1 is greater than src2.
CMP_GE src1 is greater than or equal to src2.
CMP_LT src1 is less than src2.
CMP_LE src1 is less than or equal to src2.
CMP_NE src1 is unequal to src2.
结果显示
计算矩阵绝对值
具体代码
/******************计算绝对值************************/
mat3 = Mat( 3 , 3 , CV_8UC1) ;
src3 = mat3;
cvConvertScaleAbs( & src1, & src3, 0.5 , 4 ) ;
printf ( "cvConvertScaleAbs(mat1, 0.5, 4):\n " ) ;
showMatdate( mat3) ;
注意:mat3 = | mat1 * 0.5 + 4 |;
结果显示
计算矩阵非0元素个数
具体代码
/****************计算矩阵非0元素的个数***************/
int sum = 0 ;
showMatdate( mat2) ;
sum = cvCountNonZero( & src2) ;
printf ( "sum=%d\n " , sum) ;
结果显示
矩阵除法计算
具体代码
double x[ 3 ] [ 3 ] = { { 1 , 50 , - 100 } , { 1 , - 110 , 220 } , { - 1 , 150 , 150 } } ;
double y[ 3 ] [ 3 ] = { { 1 , 0 , 0 } , { 0 , 2 , 0 } , { 0 , 0 , 3 } } ;
/*****************数组除法运算************************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvDiv( & src1, & src2, & src3, 2 ) ;
printf ( "cvDiv(mat1, mat2, 2)\n " ) ;
showMatdate( mat3) ;
注意:1、mat3 = mat1 * 2 / mat2。
2、如果矩阵中mat2某一位为0,则mat3对应那一位的结果直接为0。
结果显示
矩阵行列式计算
具体代码
/*****************矩阵行列式计算**********************/
double sum = 0 ;
sum = cvDet( & src1) ;
showMatdate( mat1) ;
printf ( "cvDet(mat1)=%.1lf\n " , sum) ;
结果显示
矩阵元素指数计算
具体代码
/*****************矩阵元素指数计算**********************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvExp( & src1, & src3) ;
printf ( "cvExp(mat1)\n " ) ;
showMatdate( mat3) ;
计算公式如下:
矩阵水平/垂直翻转
具体代码
/*****************矩阵水平或者垂直翻转**********************/
mat3 = Mat( 3 , 3 , CV_64FC1) ;
src3 = mat3;
cvFlip( & src1, & src3, - 1 ) ;
printf ( "cvFlip(mat1, -1)\n " ) ;
showMatdate( mat3) ;
cvFlip( & src1, & src3, 0 ) ;
printf ( "cvFlip(mat1, 0)\n " ) ;
showMatdate( mat3) ;
cvFlip( & src1, & src3, 1 ) ;
printf ( "cvFlip(mat1, 1)\n " ) ;
showMatdate( mat3) ;
注意:在cvFlip中,当flag小于0时,水平垂直都翻转;flag为0时,垂直翻转;flag大于0时,水平翻转。
结果显示