/** \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 Draws the patch borders into an image. * * @param drawImg - Image in which the patch borders should be drawn. * @param s - Scaling factor. * @param color - Line color. */ void drawMultilevelPatchBorder(cv::Mat& drawImg,const FeatureCoordinates& c,const float s, const cv::Scalar& color,const FeatureWarping* mpWarp = nullptr) const{ if(!c.isInFront()) return; if(mpWarp == nullptr){ patches_[0].drawPatchBorder(drawImg,c.get_c(),s*pow(2.0,nLevels-1),color,Eigen::Matrix2f::Identity()); } else { if(mpWarp->com_affineTransform(&c)){ patches_[0].drawPatchBorder(drawImg,c.get_c(),s*pow(2.0,nLevels-1),color,mpWarp->get_affineTransform(&c)); } } }
/** \brief Checks if the MultilevelPatchFeature's patches are fully located within the corresponding images. * * @param pyr - Image pyramid, which should be checked to fully contain the patches. * @param l - Maximal pyramid level which should be checked (Note: The maximal level is the critical level.) * @param mpCoor - Coordinates of the patch in the reference image (subpixel coordinates possible). * @param mpWarp - Affine warping matrix. If nullptr not warping is considered. * @param withBorder - If true, the check is executed with the expanded patch dimensions (incorporates the general patch dimensions). * If false, the check is only executed with the general patch dimensions. */ bool isMultilevelPatchInFrame(const ImagePyramid<nLevels>& pyr,const FeatureCoordinates& c, const int l = nLevels-1,const FeatureWarping* mpWarp = nullptr,const bool withBorder = false) const{ if(!c.isInFront()) return false; pyr.levelTranformCoordinates(c,coorTemp_,0,l); if(mpWarp == nullptr){ return patches_[l].isPatchInFrame(pyr.imgs_[l],coorTemp_.get_c(),Eigen::Matrix2f::Identity(),withBorder); } else { if(!mpWarp->com_affineTransform(&c)){ return false; } return patches_[l].isPatchInFrame(pyr.imgs_[l],coorTemp_.get_c(),mpWarp->get_affineTransform(&c),withBorder); } }
/** \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); } }