mirror of
https://github.com/opencv/opencv.git
synced 2024-11-30 06:10:02 +08:00
Merge pull request #13503 from Tytan:gain_comp_multi_feed
Stitching: multi-feed on gain and block compensator (#13503) * multi-feed on gain and block compensator * ABI compatibility
This commit is contained in:
parent
6142b21dd5
commit
757411bffc
@ -110,15 +110,24 @@ intensities, see @cite BL07 and @cite WJ10 for details.
|
||||
class CV_EXPORTS_W GainCompensator : public ExposureCompensator
|
||||
{
|
||||
public:
|
||||
CV_WRAP GainCompensator()
|
||||
: GainCompensator(1) {}
|
||||
CV_WRAP GainCompensator(int nr_feeds)
|
||||
: nr_feeds_(nr_feeds) {}
|
||||
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
|
||||
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
|
||||
void singleFeed(const std::vector<Point> &corners, const std::vector<UMat> &images,
|
||||
const std::vector<std::pair<UMat,uchar> > &masks);
|
||||
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
|
||||
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE ;
|
||||
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE ;
|
||||
CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; }
|
||||
CV_WRAP int getNrFeeds() { return nr_feeds_; }
|
||||
std::vector<double> gains() const;
|
||||
|
||||
private:
|
||||
Mat_<double> gains_;
|
||||
int nr_feeds_;
|
||||
};
|
||||
|
||||
/** @brief Exposure compensator which tries to remove exposure related artifacts by adjusting image block
|
||||
@ -128,18 +137,22 @@ class CV_EXPORTS_W BlocksGainCompensator : public ExposureCompensator
|
||||
{
|
||||
public:
|
||||
CV_WRAP BlocksGainCompensator(int bl_width = 32, int bl_height = 32)
|
||||
: bl_width_(bl_width), bl_height_(bl_height) {setUpdateGain(true);}
|
||||
: BlocksGainCompensator(bl_width, bl_height, 1) {}
|
||||
CV_WRAP BlocksGainCompensator(int bl_width, int bl_height, int nr_feeds)
|
||||
: bl_width_(bl_width), bl_height_(bl_height), nr_feeds_(nr_feeds) {setUpdateGain(true);}
|
||||
void feed(const std::vector<Point> &corners, const std::vector<UMat> &images,
|
||||
const std::vector<std::pair<UMat,uchar> > &masks) CV_OVERRIDE;
|
||||
CV_WRAP void apply(int index, Point corner, InputOutputArray image, InputArray mask) CV_OVERRIDE;
|
||||
CV_WRAP void getMatGains(CV_OUT std::vector<Mat>& umv) CV_OVERRIDE;
|
||||
CV_WRAP void setMatGains(std::vector<Mat>& umv) CV_OVERRIDE;
|
||||
CV_WRAP void setNrFeeds(int nr_feeds) { nr_feeds_ = nr_feeds; }
|
||||
CV_WRAP int getNrFeeds() { return nr_feeds_; }
|
||||
|
||||
private:
|
||||
int bl_width_, bl_height_;
|
||||
std::vector<UMat> gain_maps_;
|
||||
int nr_feeds_;
|
||||
};
|
||||
|
||||
//! @}
|
||||
|
||||
} // namespace detail
|
||||
|
@ -15,6 +15,7 @@ using namespace perf;
|
||||
typedef TestBaseWithParam<string> stitch;
|
||||
typedef TestBaseWithParam<int> stitchExposureCompensation;
|
||||
typedef TestBaseWithParam<tuple<string, string> > stitchDatasets;
|
||||
typedef TestBaseWithParam<tuple<string, int>> stitchExposureCompMultiFeed;
|
||||
|
||||
#ifdef HAVE_OPENCV_XFEATURES2D
|
||||
#define TEST_DETECTORS testing::Values("surf", "orb", "akaze")
|
||||
@ -22,6 +23,8 @@ typedef TestBaseWithParam<tuple<string, string> > stitchDatasets;
|
||||
#define TEST_DETECTORS testing::Values("orb", "akaze")
|
||||
#endif
|
||||
#define TEST_EXP_COMP_BS testing::Values(32, 16, 12, 10, 8)
|
||||
#define TEST_EXP_COMP_NR_FEED testing::Values(1, 2, 3, 4, 5)
|
||||
#define TEST_EXP_COMP_MODE testing::Values("gain", "blocks")
|
||||
#define AFFINE_DATASETS testing::Values("s", "budapest", "newspaper", "prague")
|
||||
|
||||
PERF_TEST_P(stitch, a123, TEST_DETECTORS)
|
||||
@ -92,6 +95,45 @@ PERF_TEST_P(stitchExposureCompensation, a123, TEST_EXP_COMP_BS)
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P(stitchExposureCompMultiFeed, a123, testing::Combine(TEST_EXP_COMP_MODE, TEST_EXP_COMP_NR_FEED))
|
||||
{
|
||||
const int block_size = 32;
|
||||
Mat pano;
|
||||
|
||||
vector<Mat> imgs;
|
||||
imgs.push_back( imread( getDataPath("stitching/a1.png") ) );
|
||||
imgs.push_back( imread( getDataPath("stitching/a2.png") ) );
|
||||
imgs.push_back( imread( getDataPath("stitching/a3.png") ) );
|
||||
|
||||
string mode = get<0>(GetParam());
|
||||
int nr_feeds = get<1>(GetParam());
|
||||
|
||||
declare.time(30 * 10).iterations(10);
|
||||
|
||||
Ptr<detail::ExposureCompensator> exp_comp;
|
||||
if (mode == "blocks")
|
||||
exp_comp = makePtr<detail::BlocksGainCompensator>(block_size, block_size, nr_feeds);
|
||||
else if (mode == "gain")
|
||||
exp_comp = makePtr<detail::GainCompensator>(nr_feeds);
|
||||
|
||||
while(next())
|
||||
{
|
||||
Ptr<Stitcher> stitcher = Stitcher::create();
|
||||
stitcher->setWarper(makePtr<SphericalWarper>());
|
||||
stitcher->setRegistrationResol(WORK_MEGAPIX);
|
||||
stitcher->setExposureCompensator(exp_comp);
|
||||
|
||||
startTimer();
|
||||
stitcher->stitch(imgs, pano);
|
||||
stopTimer();
|
||||
}
|
||||
|
||||
EXPECT_NEAR(pano.size().width, 1182, 50);
|
||||
EXPECT_NEAR(pano.size().height, 682, 30);
|
||||
|
||||
SANITY_CHECK_NOTHING();
|
||||
}
|
||||
|
||||
PERF_TEST_P(stitch, b12, TEST_DETECTORS)
|
||||
{
|
||||
Mat pano;
|
||||
|
@ -85,6 +85,33 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
|
||||
int64 t = getTickCount();
|
||||
#endif
|
||||
|
||||
const int num_images = static_cast<int>(images.size());
|
||||
Mat accumulated_gains;
|
||||
|
||||
for (int n = 0; n < nr_feeds_; ++n)
|
||||
{
|
||||
if (n > 0)
|
||||
{
|
||||
// Apply previous iteration gains
|
||||
for (int i = 0; i < num_images; ++i)
|
||||
apply(i, corners[i], images[i], masks[i].first);
|
||||
}
|
||||
|
||||
singleFeed(corners, images, masks);
|
||||
|
||||
if (n == 0)
|
||||
accumulated_gains = gains_.clone();
|
||||
else
|
||||
multiply(accumulated_gains, gains_, accumulated_gains);
|
||||
}
|
||||
gains_ = accumulated_gains;
|
||||
|
||||
LOGLN("Exposure compensation, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
||||
}
|
||||
|
||||
void GainCompensator::singleFeed(const std::vector<Point> &corners, const std::vector<UMat> &images,
|
||||
const std::vector<std::pair<UMat,uchar> > &masks)
|
||||
{
|
||||
CV_Assert(corners.size() == images.size() && images.size() == masks.size());
|
||||
|
||||
const int num_images = static_cast<int>(images.size());
|
||||
@ -204,8 +231,6 @@ void GainCompensator::feed(const std::vector<Point> &corners, const std::vector<
|
||||
gains_.at<double>(i, 0) = l_gains(j++, 0);
|
||||
}
|
||||
}
|
||||
|
||||
LOGLN("Exposure compensation, time: " << ((getTickCount() - t) / getTickFrequency()) << " sec");
|
||||
}
|
||||
|
||||
|
||||
@ -282,7 +307,7 @@ void BlocksGainCompensator::feed(const std::vector<Point> &corners, const std::v
|
||||
|
||||
if (getUpdateGain())
|
||||
{
|
||||
GainCompensator compensator;
|
||||
GainCompensator compensator(nr_feeds_);
|
||||
compensator.feed(block_corners, block_images, block_masks);
|
||||
std::vector<double> gains = compensator.gains();
|
||||
gain_maps_.resize(num_images);
|
||||
|
Loading…
Reference in New Issue
Block a user