mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 19:50:38 +08:00
minor stitching optimization (improve buffer reuse)
This commit is contained in:
parent
b319e7f403
commit
c5adaa717b
@ -1462,6 +1462,8 @@ namespace cv
|
|||||||
void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, std::vector<float>& descriptors,
|
void operator()(const GpuMat& img, const GpuMat& mask, std::vector<KeyPoint>& keypoints, std::vector<float>& descriptors,
|
||||||
bool useProvidedKeypoints = false);
|
bool useProvidedKeypoints = false);
|
||||||
|
|
||||||
|
void releaseMemory();
|
||||||
|
|
||||||
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
|
//! max keypoints = min(keypointsRatio * img.size().area(), 65535)
|
||||||
float keypointsRatio;
|
float keypointsRatio;
|
||||||
|
|
||||||
|
@ -203,8 +203,8 @@ void cv::gpu::BruteForceMatcher_GPU_base::matchSingle(const GpuMat& queryDescs,
|
|||||||
|
|
||||||
const int nQuery = queryDescs.rows;
|
const int nQuery = queryDescs.rows;
|
||||||
|
|
||||||
trainIdx.create(1, nQuery, CV_32S);
|
ensureSizeIsEnough(1, nQuery, CV_32S, trainIdx);
|
||||||
distance.create(1, nQuery, CV_32F);
|
ensureSizeIsEnough(1, nQuery, CV_32F, distance);
|
||||||
|
|
||||||
match_caller_t func = match_callers[distType][queryDescs.depth()];
|
match_caller_t func = match_callers[distType][queryDescs.depth()];
|
||||||
CV_Assert(func != 0);
|
CV_Assert(func != 0);
|
||||||
@ -335,9 +335,9 @@ void cv::gpu::BruteForceMatcher_GPU_base::matchCollection(const GpuMat& queryDes
|
|||||||
|
|
||||||
const int nQuery = queryDescs.rows;
|
const int nQuery = queryDescs.rows;
|
||||||
|
|
||||||
trainIdx.create(1, nQuery, CV_32S);
|
ensureSizeIsEnough(1, nQuery, CV_32S, trainIdx);
|
||||||
imgIdx.create(1, nQuery, CV_32S);
|
ensureSizeIsEnough(1, nQuery, CV_32S, imgIdx);
|
||||||
distance.create(1, nQuery, CV_32F);
|
ensureSizeIsEnough(1, nQuery, CV_32F, distance);
|
||||||
|
|
||||||
match_caller_t func = match_callers[distType][queryDescs.depth()];
|
match_caller_t func = match_callers[distType][queryDescs.depth()];
|
||||||
CV_Assert(func != 0);
|
CV_Assert(func != 0);
|
||||||
@ -435,8 +435,8 @@ void cv::gpu::BruteForceMatcher_GPU_base::knnMatch(const GpuMat& queryDescs, con
|
|||||||
const int nQuery = queryDescs.rows;
|
const int nQuery = queryDescs.rows;
|
||||||
const int nTrain = trainDescs.rows;
|
const int nTrain = trainDescs.rows;
|
||||||
|
|
||||||
trainIdx.create(nQuery, k, CV_32S);
|
ensureSizeIsEnough(nQuery, k, CV_32S, trainIdx);
|
||||||
distance.create(nQuery, k, CV_32F);
|
ensureSizeIsEnough(nQuery, k, CV_32F, distance);
|
||||||
ensureSizeIsEnough(nQuery, nTrain, CV_32FC1, allDist);
|
ensureSizeIsEnough(nQuery, nTrain, CV_32FC1, allDist);
|
||||||
|
|
||||||
if (stream)
|
if (stream)
|
||||||
@ -593,8 +593,8 @@ void cv::gpu::BruteForceMatcher_GPU_base::radiusMatch(const GpuMat& queryDescs,
|
|||||||
ensureSizeIsEnough(1, nQuery, CV_32SC1, nMatches);
|
ensureSizeIsEnough(1, nQuery, CV_32SC1, nMatches);
|
||||||
if (trainIdx.empty())
|
if (trainIdx.empty())
|
||||||
{
|
{
|
||||||
trainIdx.create(nQuery, nTrain, CV_32SC1);
|
ensureSizeIsEnough(nQuery, nTrain, CV_32SC1, trainIdx);
|
||||||
distance.create(nQuery, nTrain, CV_32FC1);
|
ensureSizeIsEnough(nQuery, nTrain, CV_32FC1, distance);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stream)
|
if (stream)
|
||||||
|
@ -192,8 +192,8 @@ namespace
|
|||||||
Size src_size = src.size();
|
Size src_size = src.size();
|
||||||
|
|
||||||
dst.create(src_size, dstType);
|
dst.create(src_size, dstType);
|
||||||
|
|
||||||
ensureSizeIsEnough(src_size, bufType, dstBuf);
|
ensureSizeIsEnough(src_size, bufType, dstBuf);
|
||||||
//dstBuf.create(src_size, bufType);
|
|
||||||
|
|
||||||
if (stream)
|
if (stream)
|
||||||
{
|
{
|
||||||
|
@ -59,6 +59,7 @@ void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, GpuMat&, GpuMat
|
|||||||
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&) { throw_nogpu(); }
|
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&) { throw_nogpu(); }
|
||||||
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&, GpuMat&, bool) { throw_nogpu(); }
|
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&, GpuMat&, bool) { throw_nogpu(); }
|
||||||
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&, vector<float>&, bool) { throw_nogpu(); }
|
void cv::gpu::SURF_GPU::operator()(const GpuMat&, const GpuMat&, vector<KeyPoint>&, vector<float>&, bool) { throw_nogpu(); }
|
||||||
|
void cv::gpu::SURF_GPU::releaseMemory() { throw_nogpu(); }
|
||||||
|
|
||||||
#else /* !defined (HAVE_CUDA) */
|
#else /* !defined (HAVE_CUDA) */
|
||||||
|
|
||||||
@ -201,7 +202,7 @@ namespace
|
|||||||
const int nFeatures = keypoints.cols;
|
const int nFeatures = keypoints.cols;
|
||||||
if (nFeatures > 0)
|
if (nFeatures > 0)
|
||||||
{
|
{
|
||||||
descriptors.create(nFeatures, descriptorSize, CV_32F);
|
ensureSizeIsEnough(nFeatures, descriptorSize, CV_32F, descriptors);
|
||||||
compute_descriptors_gpu(descriptors, keypoints.ptr<float>(SURF_GPU::SF_X), keypoints.ptr<float>(SURF_GPU::SF_Y),
|
compute_descriptors_gpu(descriptors, keypoints.ptr<float>(SURF_GPU::SF_X), keypoints.ptr<float>(SURF_GPU::SF_Y),
|
||||||
keypoints.ptr<float>(SURF_GPU::SF_SIZE), keypoints.ptr<float>(SURF_GPU::SF_DIR), nFeatures);
|
keypoints.ptr<float>(SURF_GPU::SF_SIZE), keypoints.ptr<float>(SURF_GPU::SF_DIR), nFeatures);
|
||||||
}
|
}
|
||||||
@ -431,4 +432,15 @@ void cv::gpu::SURF_GPU::operator()(const GpuMat& img, const GpuMat& mask, vector
|
|||||||
downloadDescriptors(descriptorsGPU, descriptors);
|
downloadDescriptors(descriptorsGPU, descriptors);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void cv::gpu::SURF_GPU::releaseMemory()
|
||||||
|
{
|
||||||
|
sum.release();
|
||||||
|
mask1.release();
|
||||||
|
maskSum.release();
|
||||||
|
intBuffer.release();
|
||||||
|
det.release();
|
||||||
|
trace.release();
|
||||||
|
maxPosBuffer.release();
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* !defined (HAVE_CUDA) */
|
#endif /* !defined (HAVE_CUDA) */
|
||||||
|
@ -363,6 +363,8 @@ int main(int argc, char* argv[])
|
|||||||
images[i] = img.clone();
|
images[i] = img.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
finder.releaseMemory();
|
||||||
|
|
||||||
full_img.release();
|
full_img.release();
|
||||||
img.release();
|
img.release();
|
||||||
|
|
||||||
@ -373,6 +375,7 @@ int main(int argc, char* argv[])
|
|||||||
vector<MatchesInfo> pairwise_matches;
|
vector<MatchesInfo> pairwise_matches;
|
||||||
BestOf2NearestMatcher matcher(try_gpu, match_conf);
|
BestOf2NearestMatcher matcher(try_gpu, match_conf);
|
||||||
matcher(features, pairwise_matches);
|
matcher(features, pairwise_matches);
|
||||||
|
matcher.releaseMemory();
|
||||||
LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
LOGLN("Pairwise matching, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
||||||
|
|
||||||
// Leave only images we are sure are from the same panorama
|
// Leave only images we are sure are from the same panorama
|
||||||
@ -571,7 +574,7 @@ int main(int argc, char* argv[])
|
|||||||
resize(dilated_mask, seam_mask, mask_warped.size());
|
resize(dilated_mask, seam_mask, mask_warped.size());
|
||||||
mask_warped = seam_mask & mask_warped;
|
mask_warped = seam_mask & mask_warped;
|
||||||
|
|
||||||
if (static_cast<Blender*>(blender) == 0)
|
if (blender.empty())
|
||||||
{
|
{
|
||||||
blender = Blender::createDefault(blend_type, try_gpu);
|
blender = Blender::createDefault(blend_type, try_gpu);
|
||||||
Size dst_sz = resultRoi(corners, sizes).size();
|
Size dst_sz = resultRoi(corners, sizes).size();
|
||||||
|
@ -96,11 +96,17 @@ namespace
|
|||||||
num_layers_descr_ = num_layers_descr;
|
num_layers_descr_ = num_layers_descr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void releaseMemory();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void find(const Mat &image, ImageFeatures &features);
|
void find(const Mat &image, ImageFeatures &features);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
GpuMat image_;
|
||||||
|
GpuMat gray_image_;
|
||||||
SURF_GPU surf_;
|
SURF_GPU surf_;
|
||||||
|
GpuMat keypoints_;
|
||||||
|
GpuMat descriptors_;
|
||||||
int num_octaves_, num_layers_;
|
int num_octaves_, num_layers_;
|
||||||
int num_octaves_descr_, num_layers_descr_;
|
int num_octaves_descr_, num_layers_descr_;
|
||||||
};
|
};
|
||||||
@ -118,22 +124,34 @@ namespace
|
|||||||
|
|
||||||
void GpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
|
void GpuSurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
|
||||||
{
|
{
|
||||||
GpuMat gray_image;
|
|
||||||
CV_Assert(image.depth() == CV_8U);
|
CV_Assert(image.depth() == CV_8U);
|
||||||
cvtColor(GpuMat(image), gray_image, CV_BGR2GRAY);
|
|
||||||
|
|
||||||
GpuMat d_keypoints;
|
ensureSizeIsEnough(image.size(), image.type(), image_);
|
||||||
GpuMat d_descriptors;
|
image_.upload(image);
|
||||||
|
|
||||||
|
ensureSizeIsEnough(image.size(), CV_8UC1, gray_image_);
|
||||||
|
cvtColor(image_, gray_image_, CV_BGR2GRAY);
|
||||||
|
|
||||||
surf_.nOctaves = num_octaves_;
|
surf_.nOctaves = num_octaves_;
|
||||||
surf_.nOctaveLayers = num_layers_;
|
surf_.nOctaveLayers = num_layers_;
|
||||||
surf_(gray_image, GpuMat(), d_keypoints);
|
surf_(gray_image_, GpuMat(), keypoints_);
|
||||||
|
|
||||||
surf_.nOctaves = num_octaves_descr_;
|
surf_.nOctaves = num_octaves_descr_;
|
||||||
surf_.nOctaveLayers = num_layers_descr_;
|
surf_.nOctaveLayers = num_layers_descr_;
|
||||||
surf_(gray_image, GpuMat(), d_keypoints, d_descriptors, true);
|
surf_.upright = true;
|
||||||
surf_.downloadKeypoints(d_keypoints, features.keypoints);
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
@ -153,6 +171,11 @@ void SurfFeaturesFinder::find(const Mat &image, ImageFeatures &features)
|
|||||||
(*impl_)(image, features);
|
(*impl_)(image, features);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SurfFeaturesFinder::releaseMemory()
|
||||||
|
{
|
||||||
|
impl_->releaseMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
@ -279,10 +302,13 @@ namespace
|
|||||||
GpuMatcher(float match_conf) : match_conf_(match_conf) {}
|
GpuMatcher(float match_conf) : match_conf_(match_conf) {}
|
||||||
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info);
|
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info);
|
||||||
|
|
||||||
|
void releaseMemory();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
float match_conf_;
|
float match_conf_;
|
||||||
GpuMat descriptors1_, descriptors2_;
|
GpuMat descriptors1_, descriptors2_;
|
||||||
GpuMat train_idx_, distance_, all_dist_;
|
GpuMat train_idx_, distance_, all_dist_;
|
||||||
|
vector< vector<DMatch> > pair_matches;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -327,13 +353,18 @@ namespace
|
|||||||
void GpuMatcher::match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo& matches_info)
|
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);
|
descriptors1_.upload(features1.descriptors);
|
||||||
descriptors2_.upload(features2.descriptors);
|
descriptors2_.upload(features2.descriptors);
|
||||||
|
|
||||||
BruteForceMatcher_GPU< L2<float> > matcher;
|
BruteForceMatcher_GPU< L2<float> > matcher;
|
||||||
vector< vector<DMatch> > pair_matches;
|
|
||||||
MatchesSet matches;
|
MatchesSet matches;
|
||||||
|
|
||||||
// Find 1->2 matches
|
// Find 1->2 matches
|
||||||
|
pair_matches.clear();
|
||||||
matcher.knnMatch(descriptors1_, descriptors2_, train_idx_, distance_, all_dist_, 2);
|
matcher.knnMatch(descriptors1_, descriptors2_, train_idx_, distance_, all_dist_, 2);
|
||||||
matcher.knnMatchDownload(train_idx_, distance_, pair_matches);
|
matcher.knnMatchDownload(train_idx_, distance_, pair_matches);
|
||||||
for (size_t i = 0; i < pair_matches.size(); ++i)
|
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
|
} // anonymous namespace
|
||||||
|
|
||||||
|
|
||||||
@ -456,3 +497,8 @@ void BestOf2NearestMatcher::match(const ImageFeatures &features1, const ImageFea
|
|||||||
// Rerun motion estimation on inliers only
|
// Rerun motion estimation on inliers only
|
||||||
matches_info.H = findHomography(src_points, dst_points, CV_RANSAC);
|
matches_info.H = findHomography(src_points, dst_points, CV_RANSAC);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void BestOf2NearestMatcher::releaseMemory()
|
||||||
|
{
|
||||||
|
impl_->releaseMemory();
|
||||||
|
}
|
||||||
|
@ -59,6 +59,8 @@ public:
|
|||||||
virtual ~FeaturesFinder() {}
|
virtual ~FeaturesFinder() {}
|
||||||
void operator ()(const cv::Mat &image, ImageFeatures &features);
|
void operator ()(const cv::Mat &image, ImageFeatures &features);
|
||||||
|
|
||||||
|
virtual void releaseMemory() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void find(const cv::Mat &image, ImageFeatures &features) = 0;
|
virtual void find(const cv::Mat &image, ImageFeatures &features) = 0;
|
||||||
};
|
};
|
||||||
@ -71,6 +73,8 @@ public:
|
|||||||
int num_octaves = 3, int num_layers = 4,
|
int num_octaves = 3, int num_layers = 4,
|
||||||
int num_octaves_descr = 4, int num_layers_descr = 2);
|
int num_octaves_descr = 4, int num_layers_descr = 2);
|
||||||
|
|
||||||
|
void releaseMemory();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void find(const cv::Mat &image, ImageFeatures &features);
|
void find(const cv::Mat &image, ImageFeatures &features);
|
||||||
|
|
||||||
@ -104,6 +108,8 @@ public:
|
|||||||
|
|
||||||
bool isThreadSafe() const { return is_thread_safe_; }
|
bool isThreadSafe() const { return is_thread_safe_; }
|
||||||
|
|
||||||
|
virtual void releaseMemory() {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
|
FeaturesMatcher(bool is_thread_safe = false) : is_thread_safe_(is_thread_safe) {}
|
||||||
|
|
||||||
@ -120,6 +126,8 @@ public:
|
|||||||
BestOf2NearestMatcher(bool try_use_gpu = true, float match_conf = 0.55f, int num_matches_thresh1 = 6,
|
BestOf2NearestMatcher(bool try_use_gpu = true, float match_conf = 0.55f, int num_matches_thresh1 = 6,
|
||||||
int num_matches_thresh2 = 6);
|
int num_matches_thresh2 = 6);
|
||||||
|
|
||||||
|
void releaseMemory();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
|
void match(const ImageFeatures &features1, const ImageFeatures &features2, MatchesInfo &matches_info);
|
||||||
|
|
||||||
|
@ -50,6 +50,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <utility>
|
#include <utility>
|
||||||
#include <set>
|
#include <set>
|
||||||
|
#include <functional>
|
||||||
#include "opencv2/core/core.hpp"
|
#include "opencv2/core/core.hpp"
|
||||||
#include "opencv2/core/internal.hpp"
|
#include "opencv2/core/internal.hpp"
|
||||||
#include "opencv2/imgproc/imgproc.hpp"
|
#include "opencv2/imgproc/imgproc.hpp"
|
||||||
|
Loading…
Reference in New Issue
Block a user