Example #1
0
 /** \brief Checks if a patch at a specific image location is still within the reference image.
  *
  *   @param img        - Reference Image.
  *   @param c          - Coordinates of the patch in the reference image.
  *   @param withBorder - Check, using either the patch-patchSize of Patch::patch_ (withBorder = false) or the patch-patchSize
  *                       of the expanded patch Patch::patchWithBorder_ (withBorder = true).
  *   @return true, if the patch is completely located within the reference image.
  */
 static bool isPatchInFrame(const cv::Mat& img,const FeatureCoordinates& c,const bool withBorder = false){
   if(c.isInFront() && c.com_warp_c()){
     const int halfpatch_size = patchSize/2+(int)withBorder;
     if(c.isNearIdentityWarping()){
       if(c.get_c().x < halfpatch_size || c.get_c().y < halfpatch_size || c.get_c().x > img.cols-halfpatch_size || c.get_c().y > img.rows-halfpatch_size){
         return false;
       } else {
         return true;
       }
     } else {
       for(int x = 0;x<2;x++){
         for(int y = 0;y<2;y++){
           const float dx = halfpatch_size*(2*x-1);
           const float dy = halfpatch_size*(2*y-1);
           const float wdx = c.get_warp_c()(0,0)*dx + c.get_warp_c()(0,1)*dy;
           const float wdy = c.get_warp_c()(1,0)*dx + c.get_warp_c()(1,1)*dy;
           const float c_x = c.get_c().x + wdx;
           const float c_y = c.get_c().y + wdy;
           if(c_x < 0 || c_y < 0 || c_x > img.cols || c_y > img.rows){
             return false;
           }
         }
       }
       return true;
     }
   } else {
     return false;
   }
 }
Example #2
0
 /** \brief Transforms pixel coordinates between two pyramid levels.
  *
  * @Note Invalidates camera and bearing vector, since the camera model is not valid for arbitrary image levels.
  * @param cIn        - Input coordinates
  * @param cOut       - Output coordinates
  * @param l1         - Input pyramid level.
  * @param l2         - Output pyramid level.
  * @return the corresponding pixel coordinates on pyramid level l2.
  */
 void levelTranformCoordinates(const FeatureCoordinates& cIn,FeatureCoordinates& cOut,const int l1, const int l2) const{
   assert(l1<n_levels && l2<n_levels && l1>=0 && l2>=0);
   cOut.set_c((centers_[l1]-centers_[l2])*pow(0.5,l2)+cIn.get_c()*pow(0.5,l2-l1));
   if(cIn.mpCamera_ != nullptr){
     if(cIn.com_warp_c()){
       cOut.set_warp_c(cIn.get_warp_c());
     }
   }
   cOut.camID_ = -1;
   cOut.mpCamera_ = nullptr;
 }
Example #3
0
  /** \brief Extracts a patch from an image.
   *
   *   @param img        - Reference Image.
   *   @param c          - Coordinates of the patch in the reference image (subpixel coordinates possible).
   *   @param withBorder - If false, the patch object is only initialized with the patch data of the general patch (Patch::patch_).
   *                       If true, the patch object is initialized with both, the patch data of the general patch (Patch::patch_)
   *                       and the patch data of the expanded patch (Patch::patchWithBorder_).
   */
  void extractPatchFromImage(const cv::Mat& img,const FeatureCoordinates& c,const bool withBorder = false){
    assert(isPatchInFrame(img,c,withBorder));
    const int halfpatch_size = patchSize/2+(int)withBorder;
    const int refStep = img.step.p[0];

    // Get Pointers
    uint8_t* img_ptr;
    float* patch_ptr;
    if(withBorder){
      patch_ptr = patchWithBorder_;
    } else {
      patch_ptr = patch_;
    }

    if(c.isNearIdentityWarping()){
      const int u_r = floor(c.get_c().x);
      const int v_r = floor(c.get_c().y);

      // compute interpolation weights
      const float subpix_x = c.get_c().x-u_r;
      const float subpix_y = c.get_c().y-v_r;
      const float wTL = (1.0-subpix_x)*(1.0-subpix_y);
      const float wTR = subpix_x * (1.0-subpix_y);
      const float wBL = (1.0-subpix_x)*subpix_y;
      const float wBR = subpix_x * subpix_y;
      for(int y=0; y<2*halfpatch_size; ++y){
        img_ptr = (uint8_t*) img.data + (v_r+y-halfpatch_size)*refStep + u_r-halfpatch_size;
        for(int x=0; x<2*halfpatch_size; ++x, ++img_ptr, ++patch_ptr)
        {
          *patch_ptr = wTL*img_ptr[0];
          if(subpix_x > 0) *patch_ptr += wTR*img_ptr[1];
          if(subpix_y > 0) *patch_ptr += wBL*img_ptr[refStep];
          if(subpix_x > 0 && subpix_y > 0) *patch_ptr += wBR*img_ptr[refStep+1];
        }
      }
    } else {
      for(int y=0; y<2*halfpatch_size; ++y){
        for(int x=0; x<2*halfpatch_size; ++x, ++patch_ptr){
          const float dx = x - halfpatch_size + 0.5;
          const float dy = y - halfpatch_size + 0.5;
          const float wdx = c.get_warp_c()(0,0)*dx + c.get_warp_c()(0,1)*dy;
          const float wdy = c.get_warp_c()(1,0)*dx + c.get_warp_c()(1,1)*dy;
          const float u_pixel = c.get_c().x+wdx - 0.5;
          const float v_pixel = c.get_c().y+wdy - 0.5;
          const int u_r = floor(u_pixel);
          const int v_r = floor(v_pixel);
          const float subpix_x = u_pixel-u_r;
          const float subpix_y = v_pixel-v_r;
          const float wTL = (1.0-subpix_x) * (1.0-subpix_y);
          const float wTR = subpix_x * (1.0-subpix_y);
          const float wBL = (1.0-subpix_x) * subpix_y;
          const float wBR = subpix_x * subpix_y;
          img_ptr = (uint8_t*) img.data + v_r*refStep + u_r;
          *patch_ptr = wTL*img_ptr[0];
          if(subpix_x > 0) *patch_ptr += wTR*img_ptr[1];
          if(subpix_y > 0) *patch_ptr += wBL*img_ptr[refStep];
          if(subpix_x > 0 && subpix_y > 0) *patch_ptr += wBR*img_ptr[refStep+1];
        }
      }
    }
    if(withBorder){
      extractPatchFromPatchWithBorder();
    }
    validGradientParameters_ = false;
  }