我找到了这段代码并尝试编译它,但它不起作用。在这一行带来的错误:
Q_matrix_tilde += q_tilde * q_tilde_transposed;
它告诉我有一个与内存有关的错误,但我不明白为什么。你可以帮帮我吗?
// Alessandro Gentilini
#include <cv.h>
#include <cxcore.h>
#include <vector>
using namespace std;
using namespace cv;
// Estimation of an affine 2D transformation by means of least squares method.
// Reference:
// SPÄTH, Helmuth. Fitting affine and orthogonal transformations between two sets of points. Mathematical Communications, 2004, 9.1: 27-34.
// http://hrcak.srce.hr/file/1425
template < typename point2D_t, typename point3D_t >
class LeastSquare2DAffineTransformationEstimator
{
public:
// Solves the linear systems descripted by formula (17)
static cv::Mat estimate( const std::vector<point2D_t>& P, const std::vector<point2D_t>& Q )
{
Mat Q_tilde = Q_set_to_Q_matrix_tilde(P);
Mat c_tilde_0 = c_j_tilde(0,P,Q);
Mat c_tilde_1 = c_j_tilde(1,P,Q);
Mat Q_tilde_inv = Q_tilde.inv();
Mat a_tilde_0 = Q_tilde_inv * c_tilde_0;
Mat a_tilde_1 = Q_tilde_inv * c_tilde_1;
cv::Mat t = cv::Mat::zeros( 3, 2, cv::DataType<point2D_t::value_type>::type );
cv::Mat(a_tilde_0).copyTo(t.col(0));
cv::Mat(a_tilde_1).copyTo(t.col(1));
cv::transpose(t,t);
return t;
}
private:
// Implements the formula (12)
static cv::Mat q_to_q_tilde( const point2D_t& q )
{
vector<point2D_t> v;
v.push_back(point2D_t(q.x));
v.push_back(point2D_t(q.y));
v.push_back(point2D_t(1));
return cv::Mat(v,true);
}
// Implements the formula (14)
static cv::Mat Q_set_to_Q_matrix_tilde( const std::vector<point2D_t>& Q_set )
{
size_t m = Q_set.size();
cv::Mat Q_matrix_tilde = cv::Mat::zeros( 3, 3, cv::DataType<point2D_t::value_type>::type );
cv::Mat temp= cv::Mat::zeros( 3, 3, cv::DataType<point2D_t::value_type>::type );
cv::Mat temp1= cv::Mat::zeros( 3, 3, cv::DataType<point2D_t::value_type>::type );
cv::Mat q_tilde = cv::Mat::zeros( 3, 1, cv::DataType<point2D_t::value_type>::type );
cv::Mat q_tilde_transposed = cv::Mat::zeros( 1, 3, cv::DataType<point2D_t::value_type>::type );
for ( size_t i = 0; i < m; i++ ) {
q_tilde = q_to_q_tilde(Q_set[i]);
cv::transpose( q_tilde, q_tilde_transposed );
/*cout<<q_tilde_transposed.col<<" "<<q_tilde_transposed.row<<endl;*/
temp = q_tilde * q_tilde_transposed;
cv::add(temp,Q_matrix_tilde,temp1);
}
return Q_matrix_tilde;
}
// Implements the formula (16)
static cv::Mat c_j_tilde( const size_t& j, const std::vector<point2D_t>& Q_set, const std::vector<point2D_t>& P_set )
{
if ( Q_set.size() != P_set.size() ) {
throw 0;
}
if ( j > 2 ) {
throw 1;
}
size_t m = Q_set.size();
point2D_t::value_type p_ji;
point2D_t::value_type c_j0 = 0;
for ( size_t i = 0; i < m; i++ ) {
switch( j ) {
case 0: p_ji = P_set[i].x; break;
case 1: p_ji = P_set[i].y; break;
}
c_j0 += Q_set[i].x * p_ji;
}
point2D_t::value_type c_j1 = 0;
for ( size_t i = 0; i < m; i++ ) {
switch( j ) {
case 0: p_ji = P_set[i].x; break;
case 1: p_ji = P_set[i].y; break;
}
c_j1 += Q_set[i].y * p_ji;
}
point2D_t::value_type c_j2 = 0;
for ( size_t i = 0; i < m; i++ ) {
switch( j ) {
case 0: p_ji = P_set[i].x; break;
case 1: p_ji = P_set[i].y; break;
}
c_j2 += 1 * p_ji;
}
vector<point2D_t> v;
v.push_back(point2D_t(c_j0));
v.push_back(point2D_t(c_j1));
v.push_back(point2D_t(c_j2));
cv::Mat vv = Mat(v,true);
return vv;
}
};
#include <vector>
#include <iostream>
int main( int argc, char** argv )
{
std::vector<cv::Point2f> P,Q;
P.push_back(cv::Point2f( 1, 0));
P.push_back(cv::Point2f( 0, 1));
P.push_back(cv::Point2f(-1, 0));
P.push_back(cv::Point2f( 0,-1));
Q.push_back(cv::Point2f(1+sqrtf(2)/2, 1+sqrtf(2)/2));
Q.push_back(cv::Point2f(1-sqrtf(2)/2, 1+sqrtf(2)/2));
Q.push_back(cv::Point2f(1-sqrtf(2)/2, 1-sqrtf(2)/2));
Q.push_back(cv::Point2f(1+sqrtf(2)/2, 1-sqrtf(2)/2));
//std::cout <<
LeastSquare2DAffineTransformationEstimator<cv::Point2f,cv::Point3f>::estimate(P,Q);
return 0;
}