opencv 中求解线性方程组,或者最小二乘法问题,使用cvSolve函数。该函数使用不同的参数,求解出来的结果天差地别。CV_LU和CV_SVD完全不一样。
求A*I=c这样的问题,
对应Matlab是I=pinv(A)*c,对应的opencv是cvSolve(A,c,I,CV_SVD)。使用CV_LU参数结果天差地别。
以下是参考内容
原文地址:cvSolve详细使用说明(转)
作者:xyzer_yuan
求解线性系统或者最小二乘法问题
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 方法可以解决):
src1
输入矩阵
src2
线性系统的右部
dst
输出解答
method
解决方法(矩阵求逆) :
CV_LU - 最佳主元选取的高斯消除法
CV_SVD - 奇异值分解法 (SVD)
CV_SVD_SYM - 对正定对称矩阵的 SVD 方法
函数 cvSolve 解决线性系统或者最小二乘法问题 (后者用 SVD 方法可以解决):
dst = argmin |src1*X -src2|
如果使用 CV_LU 方法。 如果 src1 是非奇异的,该函数则返回 1 ,否则返回 0 ,在后一种情况下 dst 是无效的。
如果使用 CV_LU 方法。 如果 src1 是非奇异的,该函数则返回 1 ,否则返回 0 ,在后一种情况下 dst 是无效的。
例如解抛物线拟合的问题:
y = a*x*x + b*x +c
假设有三个点: A1(x1,y1),A1(x1,y1),A2(x3,y3)
a*x1*x1 + b*x1 + c = y1
a*x2*x2 + b*x2 + c = y2
a*x3*x3 + b*x3 + c = y3
a*x2*x2 + b*x2 + c = y2
a*x3*x3 + b*x3 + c = y3
A = [x1*x1
x1
1
x2*x2
x2
1
x3*x3
x3
1]
B = [y1
y2
y3]
X = [a
b
c]
AX = B
求解X 即可得出a, b, c
int
cvSolve(
const
CvArr*
src1,
const
CvArr*
src2,
CvArr*
dst,
int
method=CV_LU
);
临时写了一个,并附上matlab代码和结果.
#include
<stdio.h>
#include
"cv.h"
#include
"cxcore.h"
#pragma
comment(lib,"cvd.lib")
#pragma
comment(lib,"cxcored.lib")
//author: qiansen
//date: 2006.8.8
//descript: colve
linear
equation.
//compile:
cl
mySolve.cpp
void
main(int
argc,
char
*argv[])
{
float
a[9]={1,2,3,4,5,7,6,8,9};
float
b[3]={2,3,1};
CvMat*
A
=
cvCreateMat(3,3,CV_32FC1);
CvMat*
X
=
cvCreateMat(3,1,CV_32FC1);
CvMat*
B
=
cvCreateMat(3,1,CV_32FC1);
cvSetData(A,a,CV_AUTOSTEP);
cvSetData(B,b,CV_AUTOSTEP);
cvSolve(A,
B,
X,
CV_LU);
//
solve
(Ax=b)
for
x
printf("A:");
for(int
i=0;i<9;i++){
if(i%3==0) printf("n");
printf("%ft",A->data.fl[i]);
}
printf("nnX:n");
for(
i=0;i<3;i++){
printf("%ft",X->data.fl[i]);
}
printf("nnb:n");
for(
i=0;i<3;i++){
printf("%ft",B->data.fl[i]);
}
}
/*
matlab
code:
>>A=[1,2,3;4,5,7;6,8,9]
A
=
1
2
3
4
5
7
6
8
9
>>B=[2;3;1]
B
=
2
3
1
>>AB
ans
=
-0.7143
-1.4286
1.8571