现在的位置: 首页 > 综合 > 正文

opencv里面的 CvMat 以及 cvSolve 的用法

2012年10月03日 ⁄ 综合 ⁄ 共 1839字 ⁄ 字号 评论关闭

code:

// vv.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"  
#include <stdio.h>  
#include <cv.h>  
#include <highgui.h>  
#include "cvaux.h" //必须引此头文件  
#include "cxcore.h"  
using namespace std;  

int main( int argc, char** argv )  
{   
	int i = 0;  
	float b[6] = {0,};  
	float a[36] = {0,};  

	for( i = 0; i < 6; i++)  
		b[i] = i + 1; //b[i]存放那六个系数  

	CvMat *Mb = cvCreateMat(6, 1, CV_32FC1);  //创建 6行1列 矩阵Mb
	cvSetData(Mb,b,CV_AUTOSTEP);    //给矩阵复制

	for( i=0;i<6;i++)  //打印输出该矩阵
	{    
		if(i % 3 == 0) printf("\n");    
		printf("%f\t",Mb->data.fl[i]);    
	}    
	printf("\n");

	for( i = 0; i < 36; i++)  
		a[i] = i + 1;  

	CvMat  *Ma = cvCreateMat(6, 6, CV_32FC1); //左边的坐标矩阵  
	cvSetData(Ma,a,CV_AUTOSTEP);    
	for( i=0;i<36;i++)  
	{    
		if(i%5==0) printf("\n");    
		printf("%f\t",Ma->data.fl[i]);    
	}    
	printf("\n");

	CvMat* Mx = cvCreateMat(6, 1,CV_32FC1); //要求解的矩阵  

	cvSolve(Ma, Mb, Mx, CV_LU ); // solve (Ax=b) for x  

	for( i=0;i<6;i++)  
	{    
		if(i%3==0) printf("\n");    
		printf("%f\t",Mx->data.fl[i]);    
	}    

	cvReleaseMat(&Ma); 
	cvReleaseMat(&Mb);
	cvReleaseMat(&Mx);

	getchar();
	return 0;  
}  

result:

ps:

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

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

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

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

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

CvMat的定义:

typedef struct CvMat
{
    int type;
    int step;

    /* for internal use only */
    int* refcount;
    int hdr_refcount;

    union
    {
        uchar* ptr;
        short* s;
        int* i;
        float* fl;
        double* db;
    } data;

#ifdef __cplusplus
    union
    {
        int rows;
        int height;
    };

    union
    {
        int cols;
        int width;
    };
#else
    int rows;
    int cols;
#endif

}
CvMat;

 double   ----   CV_64FC1  ------  ma->data.db[i]

=========

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

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,以为是解线性方程而已···结果算出来全是零。

抱歉!评论已关闭.