OpenCV使用RANSAC的仿射变换估计 estimateAffine2D(2)

if( goodCount > MAX(maxGoodCount, modelPoints-1) )
   {
    std::swap(tmask, mask);
    cvCopy( &model_i, model );
    maxGoodCount = goodCount;
    niters = cvRANSACUpdateNumIters( confidence,
     (double)(count - goodCount)/count, modelPoints, niters );
   }
  }
 }

if( maxGoodCount > 0 )
 {
  if( mask != mask0 )
   cvCopy( mask, mask0 );
  result = true;
 }

return result;
}

Mat getAffineTransform64f( const Point2d src[], const Point2d dst[] )
{
 Mat M(2, 3, CV_64F), X(6, 1, CV_64F, M.data);
 double a[6*6], b[6];
 Mat A(6, 6, CV_64F, a), B(6, 1, CV_64F, b);

for( int i = 0; i < 3; i++ )
 {
  int j = i*12;
  int k = i*12+6;
  a[j] = a[k+3] = src[i].x;
  a[j+1] = a[k+4] = src[i].y;
  a[j+2] = a[k+5] = 1;
  a[j+3] = a[j+4] = a[j+5] = 0;
  a[k] = a[k+1] = a[k+2] = 0;
  b[i*2] = dst[i].x;
  b[i*2+1] = dst[i].y;
 }

solve( A, B, X );
 return M;
}

int Affine2DEstimator::runKernel( const CvMat* m1, const CvMat* m2, CvMat* model )

 const Point2d* from = reinterpret_cast<const Point2d*>(m1->data.ptr);
 const Point2d* to  = reinterpret_cast<const Point2d*>(m2->data.ptr);
 Mat M0 = cv::cvarrToMat(model);
 Mat M=getAffineTransform64f(from,to);
 CV_Assert( M.size() == M0.size() );
 M.convertTo(M0, M0.type());

return model!=NULL?1:0;
}

int estimateAffine2D(InputArray _from, InputArray _to,
 OutputArray _out, OutputArray _inliers,
 double param1, double param2)
{
 Mat from = _from.getMat(), to = _to.getMat();
 int count = from.checkVector(2, CV_32F);

CV_Assert( count >= 0 && to.checkVector(2, CV_32F) == count );

_out.create(2, 3, CV_64F);
 Mat out = _out.getMat();

_inliers.create(count, 1, CV_8U, -1, true);
 Mat inliers = _inliers.getMat();
 inliers = Scalar::all(1);

Mat dFrom, dTo;
 from.convertTo(dFrom, CV_64F);
 to.convertTo(dTo, CV_64F);

CvMat F2x3 = out;
 CvMat mask  = inliers;
 CvMat m1 = dFrom;
 CvMat m2 = dTo;

const double epsilon = numeric_limits<double>::epsilon();       
 param1 = param1 <= 0 ? 3 : param1;
 param2 = (param2 < epsilon) ? 0.99 : (param2 > 1 - epsilon) ? 0.99 : param2;

return Affine2DEstimator().runRANSAC(&m1, &m2, &F2x3, &mask, param1, param2 );   
}

bool Affine2DEstimator::getSubset( const CvMat* m1, const CvMat* m2,
 CvMat* ms1, CvMat* ms2, int maxAttempts )
{
 cv::AutoBuffer<int> _idx(modelPoints);
 int* idx = _idx;
 int i = 0, j, k, idx_i, iters = 0;
 int type = CV_MAT_TYPE(m1->type), elemSize = CV_ELEM_SIZE(type);
 const int *m1ptr = m1->data.i, *m2ptr = m2->data.i;
 int *ms1ptr = ms1->data.i, *ms2ptr = ms2->data.i;
 int count = m1->cols*m1->rows;

assert( CV_IS_MAT_CONT(m1->type & m2->type) && (elemSize % sizeof(int) == 0) );
 elemSize /= sizeof(int);

for(; iters < maxAttempts; iters++)
 {
  for( i = 0; i < modelPoints && iters < maxAttempts; )
  {
   idx[i] = idx_i = cvRandInt(&rng) % count;
   for( j = 0; j < i; j++ )
    if( idx_i == idx[j] )
     break;
   if( j < i )
    continue;
   for( k = 0; k < elemSize; k++ )
   {
    ms1ptr[i*elemSize + k] = m1ptr[idx_i*elemSize + k];
    ms2ptr[i*elemSize + k] = m2ptr[idx_i*elemSize + k];
   }
   if( checkPartialSubsets && (!checkSubset( ms1, i+1 ) || !checkSubset( ms2, i+1 )))
   {
    iters++;
    continue;
   }
   i++;
  }
  if( !checkPartialSubsets && i == modelPoints &&
   (!checkSubset( ms1, i ) || !checkSubset( ms2, i )))
   continue;
  break;
 }

return i == modelPoints && iters < maxAttempts;
}


bool Affine2DEstimator::checkSubset( const CvMat* ms1, int count )
{
 int j, k, i, i0, i1;
 CvPoint2D64f* ptr = (CvPoint2D64f*)ms1->data.ptr;

assert( CV_MAT_TYPE(ms1->type) == CV_64FC2 );

if( checkPartialSubsets )
  i0 = i1 = count - 1;
 else
  i0 = 0, i1 = count - 1;

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/8e513cc479c1f385896ff8afc4a650db.html