OpenCV求解的矩阵: CvMat与cvSolve函数

来源:互联网 发布:如何让安卓手机连入mac 编辑:程序博客网 时间:2024/05/21 19:45

Refer from http://blog.csdn.net/augusdi/article/details/9014459


[cpp] view plain copy
  1. // vv.cpp : 定义控制台应用程序的入口点。  
  2. //  
  3. #include "stdafx.h"    
  4. #include <stdio.h>    
  5. #include <cv.h>    
  6. #include <highgui.h>    
  7. #include "cvaux.h" //必须引此头文件    
  8. #include "cxcore.h"    
  9. using namespace std;    
  10.   
  11. int main( int argc, char** argv )    
  12. {     
  13.     int i = 0;    
  14.     float b[6] = {0,};    
  15.     float a[36] = {0,};    
  16.   
  17.     for( i = 0; i < 6; i++)    
  18.         b[i] = i + 1; //b[i]存放那六个系数    
  19.   
  20.     CvMat *Mb = cvCreateMat(6, 1, CV_32FC1);  //创建 6行1列 矩阵Mb  
  21.     cvSetData(Mb,b,CV_AUTOSTEP);    //给矩阵复制  
  22.   
  23.     for( i=0;i<6;i++)  //打印输出该矩阵  
  24.     {      
  25.         if(i % 3 == 0) printf("\n");      
  26.         printf("%f\t",Mb->data.fl[i]);      
  27.     }      
  28.     printf("\n");  
  29.   
  30.     for( i = 0; i < 36; i++)    
  31.         a[i] = i + 1;    
  32.   
  33.     CvMat  *Ma = cvCreateMat(6, 6, CV_32FC1); //左边的坐标矩阵    
  34.     cvSetData(Ma,a,CV_AUTOSTEP);      
  35.     for( i=0;i<36;i++)    
  36.     {      
  37.         if(i%5==0) printf("\n");      
  38.         printf("%f\t",Ma->data.fl[i]);      
  39.     }      
  40.     printf("\n");  
  41.   
  42.     CvMat* Mx = cvCreateMat(6, 1,CV_32FC1); //要求解的矩阵    
  43.   
  44.     cvSolve(Ma, Mb, Mx, CV_LU ); // solve (Ax=b) for x    
  45.   
  46.     for( i=0;i<6;i++)    
  47.     {      
  48.         if(i%3==0) printf("\n");      
  49.         printf("%f\t",Mx->data.fl[i]);      
  50.     }      
  51.   
  52.     cvReleaseMat(&Ma);   
  53.     cvReleaseMat(&Mb);  
  54.     cvReleaseMat(&Mx);  
  55.   
  56.     getchar();  
  57.     return 0;    
  58. }    
result:

ps:

CV_32FC1 是32位数据,CV_64FC1的是64位数据。

前者类型的数据必须以指向32位数据类型的指针存取,否则会报错,而后者类型的数据必须以指向64位数据类型的指针存取,否则会报错。

也就是说,你如果用cv_32fc1,那么后面对该矩阵的输入输出的数据指针类型都应该是float,这在32位编译器上是32位浮点数,也就是单精度。


你如果用cv_64fc1,那么后面对该矩阵的输入输出的数据指针类型都应该是double,这在32位编译器上是64位浮点数,也就是双精度。

================-------------------------------------------------------=========================

CvMat的定义:

[cpp] view plain copy
  1. typedef struct CvMat  
  2. {  
  3.     int type;  
  4.     int step;  
  5.   
  6.     /* for internal use only */  
  7.     int* refcount;  
  8.     int hdr_refcount;  
  9.   
  10.     union  
  11.     {  
  12.         uchar* ptr;  
  13.         short* s;  
  14.         int* i;  
  15.         float* fl;  
  16.         double* db;  
  17.     } data;  
  18.   
  19. #ifdef __cplusplus  
  20.     union  
  21.     {  
  22.         int rows;  
  23.         int height;  
  24.     };  
  25.   
  26.     union  
  27.     {  
  28.         int cols;  
  29.         int width;  
  30.     };  
  31. #else  
  32.     int rows;  
  33.     int cols;  
  34. #endif  
  35.   
  36. }  
  37. CvMat;  
double ---- CV_64FC1 ------ ma->data.db[i]


=========

还要提一下, opencv 中 cvSolve 的几个默认参数。【求解线性系统或者最小二乘法问题】

[cpp] view plain copy
  1. int cvSolve( const CvArr* src1, const CvArr* src2, CvArr* dst, int method=CV_LU );    
src1
输入矩阵
src2
线性系统的右部
dst
输出解答
method
解决方法(矩阵求逆) :
CV_LU - 最佳主元选取的高斯消除法
CV_SVD - 奇异值分解法 (SVD)
CV_SVD_SYM - 对正定对称矩阵的 SVD 方法

函数 cvSolve 解决线性系统或者最小二乘法问题 (后者用 SVD 方法可以解决)


如果使用 CV_LU 方法。 如果 src1 是非奇异的,该函数则返回 1 ,否则返回 0 ,在后一种情况下 dst 是无效的。

开始一直使用CV_LU,以为是解线性方程而已···结果算出来全是零。

0 0
原创粉丝点击