22 #ifndef OV_CORE_GRIDER_GRID_H
23 #define OV_CORE_GRIDER_GRID_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; }
74 static void perform_griding(
const cv::Mat &img,
const cv::Mat &mask,
const std::vector<std::pair<int, int>> &valid_locs,
75 std::vector<cv::KeyPoint> &pts,
int num_features,
int grid_x,
int grid_y,
int threshold,
76 bool nonmaxSuppression) {
79 if (valid_locs.empty())
88 if (num_features < grid_x * grid_y) {
89 double ratio = (double)grid_x / (
double)grid_y;
90 grid_y = std::ceil(std::sqrt(num_features / ratio));
91 grid_x = std::ceil(grid_y * ratio);
93 int num_features_grid = (int)((
double)num_features / (double)(grid_x * grid_y)) + 1;
96 assert(num_features_grid > 0);
99 int size_x = img.cols / grid_x;
100 int size_y = img.rows / grid_y;
107 std::vector<std::vector<cv::KeyPoint>> collection(valid_locs.size());
108 parallel_for_(cv::Range(0, (
int)valid_locs.size()),
LambdaBody([&](
const cv::Range &range) {
109 for (
int r = range.start; r < range.end; r++) {
112 auto grid = valid_locs.at(r);
113 int x = grid.first * size_x;
114 int y = grid.second * size_y;
117 if (x + size_x > img.cols || y + size_y > img.rows)
121 cv::Rect img_roi = cv::Rect(x, y, size_x, size_y);
124 std::vector<cv::KeyPoint> pts_new;
125 cv::FAST(img(img_roi), pts_new, threshold, nonmaxSuppression);
128 std::sort(pts_new.begin(), pts_new.end(), Grider_FAST::compare_response);
133 for (size_t i = 0; i < (size_t)num_features_grid && i < pts_new.size(); i++) {
136 cv::KeyPoint pt_cor = pts_new.at(i);
137 pt_cor.pt.x += (float)x;
138 pt_cor.pt.y += (float)y;
141 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)
146 if (mask.at<uint8_t>((int)pt_cor.pt.y, (int)pt_cor.pt.x) > 127)
148 collection.at(r).push_back(pt_cor);
154 for (
size_t r = 0; r < collection.size(); r++) {
155 pts.insert(pts.end(), collection.at(r).begin(), collection.at(r).end());
163 cv::Size win_size = cv::Size(5, 5);
164 cv::Size zero_zone = cv::Size(-1, -1);
165 cv::TermCriteria term_crit = cv::TermCriteria(cv::TermCriteria::COUNT + cv::TermCriteria::EPS, 20, 0.001);
168 std::vector<cv::Point2f> pts_refined;
169 for (
size_t i = 0; i < pts.size(); i++) {
170 pts_refined.push_back(pts.at(i).pt);
174 cv::cornerSubPix(img, pts_refined, win_size, zero_zone, term_crit);
177 for (
size_t i = 0; i < pts.size(); i++) {
178 pts.at(i).pt = pts_refined.at(i);