|
|
|
@ -96,11 +96,17 @@ namespace |
|
|
|
|
num_layers_descr_ = num_layers_descr; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void releaseMemory(); |
|
|
|
|
|
|
|
|
|
protected: |
|
|
|
|
void find(const Mat &image, ImageFeatures &features); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
GpuMat image_; |
|
|
|
|
GpuMat gray_image_; |
|
|
|
|
SURF_GPU surf_; |
|
|
|
|
GpuMat keypoints_; |
|
|
|
|
GpuMat descriptors_; |
|
|
|
|
int num_octaves_, num_layers_; |
|
|
|
|
int num_octaves_descr_, num_layers_descr_; |
|
|
|
|
}; |
|
|
|
@ -118,22 +124,34 @@ namespace |
|
|
|
|
|
|
|
|
|
void GpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features) |
|
|
|
|
{ |
|
|
|
|
GpuMat gray_image; |
|
|
|
|
CV_Assert(image.depth() == CV_8U); |
|
|
|
|
cvtColor(GpuMat(image), gray_image, CV_BGR2GRAY); |
|
|
|
|
|
|
|
|
|
GpuMat d_keypoints; |
|
|
|
|
GpuMat d_descriptors; |
|
|
|
|
ensureSizeIsEnough(image.size(), image.type(), image_); |
|
|
|
|
image_.upload(image); |
|
|
|
|
|
|
|
|
|
ensureSizeIsEnough(image.size(), CV_8UC1, gray_image_); |
|
|
|
|
cvtColor(image_, gray_image_, CV_BGR2GRAY); |
|
|
|
|
|
|
|
|
|
surf_.nOctaves = num_octaves_; |
|
|
|
|
surf_.nOctaveLayers = num_layers_; |
|
|
|
|
surf_(gray_image, GpuMat(), d_keypoints); |
|
|
|
|
surf_(gray_image_, GpuMat(), keypoints_); |
|
|
|
|
|
|
|
|
|
surf_.nOctaves = num_octaves_descr_; |
|
|
|
|
surf_.nOctaveLayers = num_layers_descr_; |
|
|
|
|
surf_(gray_image, GpuMat(), d_keypoints, d_descriptors, true); |
|
|
|
|
surf_.downloadKeypoints(d_keypoints, features.keypoints); |
|
|
|
|
surf_.upright = true; |
|
|
|
|
surf_(gray_image_, GpuMat(), keypoints_, descriptors_, true); |
|
|
|
|
surf_.downloadKeypoints(keypoints_, features.keypoints); |
|
|
|
|
|
|
|
|
|
d_descriptors.download(features.descriptors); |
|
|
|
|
descriptors_.download(features.descriptors); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GpuSurfFeaturesFinder::releaseMemory() |
|
|
|
|
{ |
|
|
|
|
surf_.releaseMemory(); |
|
|
|
|
image_.release(); |
|
|
|
|
gray_image_.release(); |
|
|
|
|
keypoints_.release(); |
|
|
|
|
descriptors_.release(); |
|
|
|
|
} |
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
@ -153,6 +171,11 @@ void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features) |
|
|
|
|
(*impl_)(image, features); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void SurfFeaturesFinder::releaseMemory() |
|
|
|
|
{ |
|
|
|
|
impl_->releaseMemory(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
@ -279,10 +302,13 @@ namespace |
|
|
|
|
GpuMatcher(float match_conf) : match_conf_(match_conf) {} |
|
|
|
|
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info); |
|
|
|
|
|
|
|
|
|
void releaseMemory(); |
|
|
|
|
|
|
|
|
|
private: |
|
|
|
|
float match_conf_; |
|
|
|
|
GpuMat descriptors1_, descriptors2_; |
|
|
|
|
GpuMat train_idx_, distance_, all_dist_; |
|
|
|
|
vector< vector<DMatch> > pair_matches; |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -326,14 +352,19 @@ namespace |
|
|
|
|
|
|
|
|
|
void GpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info) |
|
|
|
|
{ |
|
|
|
|
matches_info.matches.clear();
|
|
|
|
|
matches_info.matches.clear();
|
|
|
|
|
|
|
|
|
|
ensureSizeIsEnough(features1.descriptors.size(), features1.descriptors.type(), descriptors1_); |
|
|
|
|
ensureSizeIsEnough(features2.descriptors.size(), features2.descriptors.type(), descriptors2_); |
|
|
|
|
|
|
|
|
|
descriptors1_.upload(features1.descriptors); |
|
|
|
|
descriptors2_.upload(features2.descriptors); |
|
|
|
|
|
|
|
|
|
BruteForceMatcher_GPU< L2<float> > matcher; |
|
|
|
|
vector< vector<DMatch> > pair_matches; |
|
|
|
|
MatchesSet matches; |
|
|
|
|
|
|
|
|
|
// Find 1->2 matches
|
|
|
|
|
pair_matches.clear(); |
|
|
|
|
matcher.knnMatch(descriptors1_, descriptors2_, train_idx_, distance_, all_dist_, 2); |
|
|
|
|
matcher.knnMatchDownload(train_idx_, distance_, pair_matches); |
|
|
|
|
for (size_t i = 0; i < pair_matches.size(); ++i) |
|
|
|
@ -365,6 +396,16 @@ namespace |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void GpuMatcher::releaseMemory() |
|
|
|
|
{ |
|
|
|
|
descriptors1_.release(); |
|
|
|
|
descriptors2_.release(); |
|
|
|
|
train_idx_.release(); |
|
|
|
|
distance_.release(); |
|
|
|
|
all_dist_.release(); |
|
|
|
|
vector< vector<DMatch> >().swap(pair_matches); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@ -456,3 +497,8 @@ void BestOf2NearestMatcher::match(const ImageFeatures &features1, const ImageFea |
|
|
|
|
// Rerun motion estimation on inliers only
|
|
|
|
|
matches_info.H = findHomography(src_points, dst_points, CV_RANSAC); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void BestOf2NearestMatcher::releaseMemory() |
|
|
|
|
{ |
|
|
|
|
impl_->releaseMemory(); |
|
|
|
|
} |
|
|
|
|