diff --git a/modules/features2d/src/keypoint.cpp b/modules/features2d/src/keypoint.cpp index f71186d16f..ffeb534638 100644 --- a/modules/features2d/src/keypoint.cpp +++ b/modules/features2d/src/keypoint.cpp @@ -183,10 +183,13 @@ void KeyPointsFilter::runByImageBorder( vector& keypoints, Size imageS { if( borderSize > 0) { - keypoints.erase( remove_if(keypoints.begin(), keypoints.end(), - RoiPredicate(Rect(Point(borderSize, borderSize), - Point(imageSize.width - borderSize, imageSize.height - borderSize)))), - keypoints.end() ); + if (imageSize.height <= borderSize * 2 || imageSize.width <= borderSize * 2) + keypoints.clear(); + else + keypoints.erase( remove_if(keypoints.begin(), keypoints.end(), + RoiPredicate(Rect(Point(borderSize, borderSize), + Point(imageSize.width - borderSize, imageSize.height - borderSize)))), + keypoints.end() ); } } diff --git a/modules/features2d/src/orb.cpp b/modules/features2d/src/orb.cpp index 15c14f3e46..3af79a2a5c 100644 --- a/modules/features2d/src/orb.cpp +++ b/modules/features2d/src/orb.cpp @@ -530,12 +530,40 @@ void ORB::operator()(const cv::Mat &image, const cv::Mat &mask, std::vector & keypoints_in_out, +void ORB::operator()(const cv::Mat &_image_in, const cv::Mat &_mask, std::vector & keypoints_in_out, cv::Mat & descriptors, bool do_keypoints, bool do_descriptors) { - if (((!do_keypoints) && (!do_descriptors)) || (image_in.empty())) + if (((!do_keypoints) && (!do_descriptors)) || (_image_in.empty())) return; + //ROI handling + cv::Mat image_in(_image_in); + cv::Mat mask(_mask); + Point image_in_roi_offset(0,0); + if (image_in.isSubmatrix()) + { + Size image_in_size; + image_in.locateROI(image_in_size, image_in_roi_offset); + image_in_roi_offset.x = image_in_roi_offset.x - std::max(0, image_in_roi_offset.x - params_.edge_threshold_); + image_in_roi_offset.y = image_in_roi_offset.y - std::max(0, image_in_roi_offset.y - params_.edge_threshold_); + + image_in.adjustROI(params_.edge_threshold_, params_.edge_threshold_, params_.edge_threshold_, params_.edge_threshold_); + if (!do_keypoints && image_in_roi_offset != Point(0,0)) + { + for (std::vector::iterator kp = keypoints_in_out.begin(); kp != keypoints_in_out.end(); ++kp) + { + kp->pt.x += image_in_roi_offset.x; + kp->pt.y += image_in_roi_offset.y; + } + } + + if (!mask.empty()) + copyMakeBorder(_mask, mask, + image_in_roi_offset.y, image_in.rows - image_in_roi_offset.y - mask.rows, + image_in_roi_offset.x, image_in.cols - image_in_roi_offset.x - mask.cols, + cv::BORDER_CONSTANT, Scalar::all(0)); + } + cv::Mat image; if (image_in.type() != CV_8UC1) cvtColor(image_in, image, CV_BGR2GRAY); @@ -635,6 +663,16 @@ void ORB::operator()(const cv::Mat &image_in, const cv::Mat &mask, std::vector::iterator kp = keypoints_in_out.begin(); kp != keypoints_in_out.end(); ++kp) + { + kp->pt.x -= image_in_roi_offset.x; + kp->pt.y -= image_in_roi_offset.y; + } + } } //takes keypoints and culls them by the response