Added handling of ROI in stitching features matchers
This commit is contained in:
@@ -67,6 +67,7 @@ class CV_EXPORTS FeaturesFinder
|
|||||||
public:
|
public:
|
||||||
virtual ~FeaturesFinder() {}
|
virtual ~FeaturesFinder() {}
|
||||||
void operator ()(const Mat &image, ImageFeatures &features);
|
void operator ()(const Mat &image, ImageFeatures &features);
|
||||||
|
void operator ()(const Mat &image, ImageFeatures &features, const std::vector<cv::Rect> &rois);
|
||||||
virtual void collectGarbage() {}
|
virtual void collectGarbage() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
@@ -66,6 +66,7 @@ public:
|
|||||||
|
|
||||||
// Stitches the biggest found pano. Returns status code.
|
// Stitches the biggest found pano. Returns status code.
|
||||||
Status stitch(InputArray imgs, OutputArray pano);
|
Status stitch(InputArray imgs, OutputArray pano);
|
||||||
|
Status stitch(InputArray imgs, const std::vector<std::vector<cv::Rect> > &rois, OutputArray pano);
|
||||||
|
|
||||||
double registrationResol() const { return registr_resol_; }
|
double registrationResol() const { return registr_resol_; }
|
||||||
void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
|
void setRegistrationResol(double resol_mpx) { registr_resol_ = resol_mpx; }
|
||||||
@@ -147,6 +148,7 @@ private:
|
|||||||
Ptr<detail::Blender> blender_;
|
Ptr<detail::Blender> blender_;
|
||||||
|
|
||||||
std::vector<cv::Mat> imgs_;
|
std::vector<cv::Mat> imgs_;
|
||||||
|
std::vector<std::vector<cv::Rect> > rois_;
|
||||||
std::vector<cv::Size> full_img_sizes_;
|
std::vector<cv::Size> full_img_sizes_;
|
||||||
std::vector<detail::ImageFeatures> features_;
|
std::vector<detail::ImageFeatures> features_;
|
||||||
std::vector<detail::MatchesInfo> pairwise_matches_;
|
std::vector<detail::MatchesInfo> pairwise_matches_;
|
||||||
|
@@ -249,10 +249,47 @@ namespace detail {
|
|||||||
void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features)
|
void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features)
|
||||||
{
|
{
|
||||||
find(image, features);
|
find(image, features);
|
||||||
|
cout << features.descriptors.cols << " " << features.descriptors.rows << " " << features.descriptors.type() << endl;
|
||||||
features.img_size = image.size();
|
features.img_size = image.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// TODO add tests for this function
|
||||||
|
void FeaturesFinder::operator ()(const Mat &image, ImageFeatures &features, const vector<Rect> &rois)
|
||||||
|
{
|
||||||
|
vector<ImageFeatures> roi_features;
|
||||||
|
size_t total_kps_count = 0;
|
||||||
|
int total_descriptors_width = 0;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < rois.size(); ++i)
|
||||||
|
{
|
||||||
|
find(image(rois[i]), roi_features[i]);
|
||||||
|
total_kps_count += roi_features[i].keypoints.size();
|
||||||
|
total_descriptors_width += roi_features[i].descriptors.cols;
|
||||||
|
}
|
||||||
|
|
||||||
|
features.img_size = image.size();
|
||||||
|
features.keypoints.resize(total_kps_count);
|
||||||
|
features.descriptors.create(1, total_descriptors_width, roi_features[0].descriptors.type());
|
||||||
|
|
||||||
|
int kp_idx = 0;
|
||||||
|
int descr_offset = 0;
|
||||||
|
for (size_t i = 0; i < rois.size(); ++i)
|
||||||
|
{
|
||||||
|
for (size_t j = 0; j < features.keypoints.size(); ++j, ++kp_idx)
|
||||||
|
{
|
||||||
|
features.keypoints[kp_idx] = roi_features[i].keypoints[j];
|
||||||
|
features.keypoints[kp_idx].pt.x += (float)rois[i].x;
|
||||||
|
features.keypoints[kp_idx].pt.y += (float)rois[i].y;
|
||||||
|
}
|
||||||
|
Mat subdescr = features.descriptors.colRange(
|
||||||
|
descr_offset, descr_offset + roi_features[i].descriptors.cols);
|
||||||
|
roi_features[i].descriptors.copyTo(subdescr);
|
||||||
|
descr_offset += roi_features[i].descriptors.cols;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
SurfFeaturesFinder::SurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
|
SurfFeaturesFinder::SurfFeaturesFinder(double hess_thresh, int num_octaves, int num_layers,
|
||||||
int num_octaves_descr, int num_layers_descr)
|
int num_octaves_descr, int num_layers_descr)
|
||||||
{
|
{
|
||||||
|
@@ -100,6 +100,13 @@ Stitcher::Status Stitcher::stitch(InputArray imgs, OutputArray pano)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Stitcher::Status Stitcher::stitch(InputArray imgs, const vector<vector<Rect> > &rois, OutputArray pano)
|
||||||
|
{
|
||||||
|
rois_ = rois;
|
||||||
|
return stitch(imgs, pano);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Stitcher::Status Stitcher::matchImages()
|
Stitcher::Status Stitcher::matchImages()
|
||||||
{
|
{
|
||||||
if ((int)imgs_.size() < 2)
|
if ((int)imgs_.size() < 2)
|
||||||
@@ -148,7 +155,10 @@ Stitcher::Status Stitcher::matchImages()
|
|||||||
is_seam_scale_set = true;
|
is_seam_scale_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*features_finder_)(img, features_[i]);
|
if (rois_.empty())
|
||||||
|
(*features_finder_)(img, features_[i]);
|
||||||
|
else
|
||||||
|
(*features_finder_)(img, features_[i], rois_[i]);
|
||||||
features_[i].img_idx = i;
|
features_[i].img_idx = i;
|
||||||
LOGLN("Features in image #" << i+1 << ": " << features_[i].keypoints.size());
|
LOGLN("Features in image #" << i+1 << ": " << features_[i].keypoints.size());
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user