22 #ifndef OV_CORE_GRIDER_FAST_H
23 #define OV_CORE_GRIDER_FAST_H
25 #include <Eigen/Eigen>
30 #include <opencv2/highgui/highgui.hpp>
31 #include <opencv2/imgproc/imgproc.hpp>
32 #include <opencv2/opencv.hpp>
57 static bool compare_response(cv::KeyPoint first, cv::KeyPoint second) {
return first.response > second.response; }
73 static void perform_griding(
const cv::Mat &img,
const cv::Mat &mask, std::vector<cv::KeyPoint> &pts,
int num_features,
int grid_x,
74 int grid_y,
int threshold,
bool nonmaxSuppression) {
82 if (num_features < grid_x * grid_y) {
83 double ratio = (double)grid_x / (
double)grid_y;
84 grid_y = std::ceil(std::sqrt(num_features / ratio));
85 grid_x = std::ceil(grid_y * ratio);
87 int num_features_grid = (int)((
double)num_features / (double)(grid_x * grid_y)) + 1;
90 assert(num_features_grid > 0);
93 int size_x = img.cols / grid_x;
94 int size_y = img.rows / grid_y;
101 int ct_cols = std::floor(img.cols / size_x);
102 int ct_rows = std::floor(img.rows / size_y);
103 std::vector<std::vector<cv::KeyPoint>> collection(ct_cols * ct_rows);
104 parallel_for_(cv::Range(0, ct_cols * ct_rows),
LambdaBody([&](
const cv::Range &range) {
105 for (
int r = range.start; r < range.end; r++) {
107 int x = r % ct_cols * size_x;
108 int y = r / ct_cols * size_y;
111 if (x + size_x > img.cols || y + size_y > img.rows)
115 cv::Rect img_roi = cv::Rect(x, y, size_x, size_y);
118 std::vector<cv::KeyPoint> pts_new;
119 cv::FAST(img(img_roi), pts_new, threshold, nonmaxSuppression);
122 std::sort(pts_new.begin(), pts_new.end(), Grider_FAST::compare_response);
127 for (size_t i = 0; i < (size_t)num_features_grid && i < pts_new.size(); i++) {
130 cv::KeyPoint pt_cor = pts_new.at(i);
131 pt_cor.pt.x += (float)x;
132 pt_cor.pt.y += (float)y;
135 if ((int)pt_cor.pt.x < 0 || (int)pt_cor.pt.x > img.cols || (int)pt_cor.pt.y < 0 || (int)pt_cor.pt.y > img.rows)
140 if (mask.at<uint8_t>((int)pt_cor.pt.y, (int)pt_cor.pt.x) > 127)
142 collection.at(r).push_back(pt_cor);
148 for (
size_t r = 0; r < collection.size(); r++) {
149 pts.insert(pts.end(), collection.at(r).begin(), collection.at(r).end());
157 cv::Size win_size = cv::Size(5, 5);
158 cv::Size zero_zone = cv::Size(-1, -1);
159 cv::TermCriteria term_crit = cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 20, 0.001);
162 std::vector<cv::Point2f> pts_refined;
163 for (
size_t i = 0; i < pts.size(); i++) {
164 pts_refined.push_back(pts.at(i).pt);
168 cv::cornerSubPix(img, pts_refined, win_size, zero_zone, term_crit);
171 for (
size_t i = 0; i < pts.size(); i++) {
172 pts.at(i).pt = pts_refined.at(i);