0

我找到了这段代码并尝试编译它,但它不起作用。在这一行带来的错误:

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;
}
4

1 回答 1

1

您的代码完美运行。我已经运行它并得到结果:

[0.70710683, -0.70710683 1,
 0.70710683,  0.70710683 1]
于 2013-08-08T07:59:55.990 回答