/** \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; } }
/** \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; }
/** \brief Draws the patch borders into an image. * * @param drawImg - Image in which the patch borders should be drawn. * @param c - Coordinates of the patch in the reference image. * @param s - Scaling factor. * @param color - Line color. */ void drawPatchBorder(cv::Mat& drawImg,const FeatureCoordinates& c,const float s, const cv::Scalar& color) const{ const double half_length = s*patchSize/2; if(c.isInFront() && c.com_warp_c()){ cv::Point2f c1 = c.get_patchCorner(half_length,half_length).get_c(); cv::Point2f c2 = c.get_patchCorner(half_length,-half_length).get_c(); cv::line(drawImg,c1,c2,color,1); c1 = c.get_patchCorner(-half_length,-half_length).get_c(); cv::line(drawImg,c2,c1,color,1); c2 = c.get_patchCorner(-half_length,half_length).get_c(); cv::line(drawImg,c1,c2,color,1); c1 = c.get_patchCorner(half_length,half_length).get_c(); cv::line(drawImg,c2,c1,color,1); } }