/*!
  Compute the points of interest in the current image and try to recognise them 
  using the trained classifier. The matched pairs can be found with the 
  getMatchedPointByRef function. The homography between the two planar 
  surfaces is also computed.
  
  \param I : The gray scaled image where the points are computed.
  
  \return True if the surface has been found.
*/
bool 
vpPlanarObjectDetector::matchPoint(const vpImage<unsigned char> &I)
{
  fern.matchPoint(I);
  
  /* compute homography */
  std::vector<cv::Point2f> refPts = fern.getRefPt();
  std::vector<cv::Point2f> curPts = fern.getCurPt();
  
  for(unsigned int i=0; i<refPts.size(); ++i){
    refPts[i].x += modelROI.x;
    refPts[i].y += modelROI.y;
  }
  for(unsigned int i=0; i<curPts.size(); ++i){
    curPts[i].x += modelROI.x;
    curPts[i].y += modelROI.y;
  }
  
  if(curPts.size() < 4){
    for (unsigned int i = 0; i < 3; i += 1){
      for (unsigned int j = 0; j < 3; j += 1){
        if(i == j){
          homography[i][j] = 1;
        }
        else{
          homography[i][j] = 0;
        }
      }
    }
    return false;
  } 

  /* part of code from OpenCV planarObjectDetector */
  std::vector<unsigned char> mask;
  H = cv::findHomography(cv::Mat(refPts), cv::Mat(curPts), mask, cv::RANSAC, 10);
  
  if( H.data )
  {
    const cv::Mat_<double>& H_tmp = H;
    dst_corners.resize(4);
    for(unsigned int i = 0; i < 4; i++ )
    {
        cv::Point2f pt = ref_corners[i];

        double w = 1./(H_tmp(2,0)*pt.x + H_tmp(2,1)*pt.y + H_tmp(2,2));
        dst_corners[i] = cv::Point2f((float)((H_tmp(0,0)*pt.x + H_tmp(0,1)*pt.y + H_tmp(0,2))*w),
                             (float)((H_tmp(1,0)*pt.x + H_tmp(1,1)*pt.y + H_tmp(1,2))*w));
    }
    
    double* ptr = (double*)H_tmp.data;
    for(unsigned int i=0; i<9; i++){
      this->homography[(unsigned int)(i/3)][i%3] = *(ptr++);
    }
    isCorrect = true;
  }
  else{
    isCorrect = false;
  }
  
  
  currentImagePoints.resize(0);
  refImagePoints.resize(0);
  for (unsigned int i = 0; i < mask.size(); i += 1){
    if(mask[i] != 0){
      vpImagePoint ip;
      ip.set_i(curPts[i].y);
      ip.set_j(curPts[i].x);
      currentImagePoints.push_back(ip);
      ip.set_i(refPts[i].y);
      ip.set_j(refPts[i].x);
      refImagePoints.push_back(ip);
    }
  }
  
  if(currentImagePoints.size() < minNbMatching){
    isCorrect = false;
  }

  return isCorrect;
}
Example #2
0
 virtual void compute_cost_hessian(mat<double,mat_structure::symmetric>& H, const vect_n<double>& x, double f, const vect_n<double>& x_grad) const {
   first_eval->compute_cost_hessian(H, x, f, x_grad);
   mat<double,mat_structure::symmetric> H_tmp(H.get_row_count());
   second_eval->compute_cost_hessian(H_tmp, x, f, x_grad);
   H += H_tmp;
 };