opencv矩阵运算

Posted lytwajue

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了opencv矩阵运算相关的知识,希望对你有一定的参考价值。

简单介绍

  本篇承接上一篇。继续opencv下矩阵计算的函数使用。

计算矩阵的逆

  注意:矩阵A是可逆矩阵的充分必要条件是行列式detA不等于0。

详细代码

double x[3][3] = {{1, 2, 3}, {2, 2, 1}, {3, 4, 3}};
double y[3][3] = {{1, 0, 0}, {0, 2, 0}, {0, 0, 3}};
 
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");
}
 
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);
 
/*****************矩阵的逆**********************/
	mat3 = Mat(3, 3, CV_64FC1);
	src3 = mat3;
	cvInvert(&src1, &src3);
	showMatdate(mat3);
	return 0;
}

结果显示

      技术分享

矩阵元素自然对数

详细代码

/*****************矩阵元素自然对数**********************/
    mat3 = Mat(3, 3, CV_64FC1);
    src3 = mat3;
    cvLog(&src1, &src3);
    showMatdate(mat3);

结果显示

      技术分享

矩阵查找表转换

详细代码

/*****************矩阵查找表转换**×******************/
    uchar lut[256];
 
    mat3 = Mat(3, 3, CV_8UC1);
    src3 = mat3;
    mat1.convertTo(mat1, CV_8UC1);
    src1 = mat1;
    mat2 = cvCreateMatHeader(1, 256, CV_8UC1);
    src2 = mat2;
    for (int i = 0; i < 256; i++) {
        lut[i] = 255 - i;
    }
    cvSetData(&src2, lut, 0);
    cvLUT(&src1, &src3, &src2);
    printf("cvLUT(mat1):\n");
    showMatdate(mat3);
    注意:mat3 = src2[mat1].(假设mat1格式为CV_8U)
          mat3 = src2[mat1 + 128].(假设mat1格式为CV_8S)

结果显示

      技术分享

计算向量间马氏距离

详细代码

/*************显示矩阵数据***************************/
    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");
    showMatdate(mat2);
 
/*****************计算向量间马氏距离**********************/                                                                          
    mat3 = Mat(3, 3, CV_64FC1, z);
    src3 = mat3;
    printf("mat3:\n");
    showMatdate(mat3);
 
    tmp = cvMahalanobis(&src1, &src2, &src3);
    printf("cvMahalanobis(mat1, mat2, mat3): %.1lf\n", tmp);
    马氏距离的定义。參考例如以下:http://blog.csdn.net/jmy5945hh/article/details/20536929

结果显示

      技术分享

获得矩阵元素间最大值

详细代码

/*****************计算矩阵參数间最大值**********************/
    mat3 = Mat(3, 3, CV_64FC1);
    src3 = mat3;
    cvMax(&src1, &src2, &src3);
    printf("cvMax(mat1, mat2):\n");
    showMatdate(mat3);
   类似的还有cvMaxS:计算矩阵元素和參数的最大值。

cvAvg:计算矩阵元素的平均值。

cvAvgSdv:计算矩阵元素的平均值和标准差。

cvMin:计算矩阵參数间最小值。

cvMinS:计算矩阵元素和參数的最小值。

结果显示

      技术分享

单通道合成多通道矩阵

详细代码

    mat3 = Mat(1, 3, CV_8UC3);                                                                                                       
    src3 = mat3;
    cvMerge(&src1, &src2, 0, 0, &src3);
    printf("cvMax(mat1, mat2):\n");
    showMatdate(mat3);
  相应的函数为:split()(将多通道分离为单通道矩阵)。

获取矩阵最大最小元素

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    cvMinMaxLoc(&src1, &min, &max, &min_p1, &max_p2);
    printf("min:%lf, min_p1.x:%d, min_p1.y:%d\n", min, min_p1.x, min_p1.y);
    printf("max:%lf, max_p2.x:%d, max_p2.y:%d\n", max, max_p2.x, max_p2.y);
     获取到最大最小值:max,min。以及它们的相应位置坐标:min_p1, max_p2。

结果显示

         技术分享

两个矩阵傅里叶频谱相乘

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");
    showMatdate(mat2);
 
    mat3 = Mat(3, 3, CV_64FC1);                                                                                                      
    src3 = mat3;
 
    cvMulSpectrums(&src1, &src2, &src3, DFT_ROWS);
    printf("mat3:\n");
    showMatdate(mat3);

结果显示

         技术分享

矩阵乘法

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");
    showMatdate(mat2);
 
    mat3 = Mat(3, 3, CV_64FC1);
    src3 = mat3;
 
    cvMul(&src1, &src2, &src3, 3);
    printf("cvMul(mat1 * mat2 * 3):\n");                                                                                             
    showMatdate(mat3);

结果显示

         技术分享

矩阵和转置的乘积

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");                                                                                                               
    showMatdate(mat2);
 
    mat3 = Mat(3, 3, CV_64FC1);
    src3 = mat3;
 
    cvMulTransposed(&src1, &src3, 0, &src2);
    printf("cvMulTransposed(mat1):\n");
    showMatdate(mat3);
    void cvMulTransposed( const CvArr* src, CvArr* dst, int order, const CvArr* delta=NULL );
    src:输入矩阵
    dst:目标矩阵
    order:乘法顺序
    delta:一个可选数组, 在乘法之前从 src 中减去该数组。

函数 cvMulTransposed 计算 src 和它的转置的乘积。 函数求值公式: 假设 order=0 dst=(src-delta)*(src-delta)T 否则 dst=(src-delta)T*(src-delta)

结果显示

        技术分享

矩阵绝对差等

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");
    showMatdate(mat2);
 
    mat3 = Mat(3, 3, CV_64FC1);
    src3 = mat3;
 
    tmp = cvNorm(&src1, &src2, NORM_L1);                                                                                             
    printf("cvNorm(mat1, mat2, NORM_INF):%lf\n", tmp);
  double cvNorm(const CvArr* arr1, const CvArr* arr2=NULL, int norm_type=CV_L2, const CvArr* mask=NULL )
  假设arr2 == NULL
则:
    技术分享
否则:
      技术分享
   或者
      技术分享

结果显示

     技术分享

极性坐标转换到笛卡尔坐标

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
    printf("mat2:\n");
    showMatdate(mat2);
 
    mat3 = Mat(3, 1, CV_64FC1);
    src3 = mat3;
    mat4 = Mat(3, 1, CV_64FC1);
    src4 = mat4;
 
    cvPolarToCart(&src1, &src2, &src3, &src4, true);
    printf("cvPolarToCart(mat1, mat2)--x:\n");
    showMatdate(mat3);
    printf("cvPolarToCart(mat1, mat2)--y:\n");
    showMatdate(mat4);
  void cvPolarToCart(const CvArr* magnitude, const CvArr* angle, CvArr* x, CvArr* y, int angle_in_degrees=0)
  magnitude:极坐标的长度。

angle:极坐标的角度。 x:笛卡尔X坐标。

y:笛卡尔Y坐标。 angle_in_degrees:若为true,表示输入的是角度,否则表示输入的是弧度。

结果显示

   技术分享

矩阵元素求幂

详细代码

    printf("mat1:\n");
    showMatdate(mat1);
 
    mat3 = Mat(3, 1, CV_64FC1);
    src3 = mat3;
 
    cvPow(&src1, &src3, 2);
    printf("cvPow(mat1, 2):\n");                                                                                                     
    showMatdate(mat3);

结果显示

   技术分享

矩阵简化为向量

详细代

    printf("mat1:\n");
    showMatdate(mat1);
 
    mat3 = Mat(3, 1, CV_64FC1);
    src3 = mat3;
 
    cvReduce(&src1, &src3, 1, CV_REDUCE_MAX);
    printf("cvReduce(mat1, 1 , CV_REDUCE_MAX):\n");
    showMatdate(mat3);
  void cvReduce(const CvArr* src, CvArr* dst, int dim=-1, int op=CV_REDUCE_SUM)
  src:待简化的矩阵。
  dst:生成的向量。
  dim:0意味着矩阵被处理成一行,1意味着矩阵被处理成为一列,-1时维数将依据输出向量的大小自己主动选择.
  op:
       CV_REDUCE_SUM-输出是矩阵的全部行/列的和.
       CV_REDUCE_AVG-输出是矩阵的全部行/列的平均向量.
       CV_REDUCE_MAX-输出是矩阵的全部行/列的最大值.
       CV_REDUCE_MIN-输出是矩阵的全部行/列的最小值.

结果显示

   技术分享

以上是关于opencv矩阵运算的主要内容,如果未能解决你的问题,请参考以下文章

opencv学习_矩阵运算和绘制图像

opencv学习_矩阵运算和绘制图像

OpenCV 矩阵运算是不是比简单的循环迭代更快?

如何使用OpenCV作图像或矩阵的逻辑运算

用于矩阵运算的 OpenCV GPU 库有多好?

opencv-矩阵运算