24 #ifndef _POINTSAMPLER_H
25 #define _POINTSAMPLER_H
30 #include <hugin_config.h>
31 #include <vigra/stdimage.hxx>
48 enum LimitType{LIMIT_UINT8, LIMIT_UINT16, LIMIT_FLOAT};
75 o_images(images), o_numPoints(nPoints), m_limits(limits)
85 vigra::FRGBImage::ConstAccessor,
92 virtual void samplePoints(
const std::vector<InterpolImg>& imgs,
93 const std::vector<vigra::FImage*>& voteImgs,
96 std::vector<std::multimap<double,vigra_ext::PointPairRGB> >& radiusHist,
97 unsigned& nGoodPoints,
105 template<
class Po
intPairClass>
106 static void sampleRadiusUniform(
const std::vector<std::multimap<double,PointPairClass> >& radiusHist,
108 std::vector<PointPairClass>& selectedPoints,
117 virtual bool runAlgorithm();
134 return o_resultPoints;
156 :
PointSampler(panorama, progressDisplay, images, limits, nPoints)
167 template <
class Img,
class VoteImg,
class PP>
169 const std::vector<VoteImg *> &voteImgs,
173 std::vector<std::multimap<double, PP > > & radiusHist,
174 unsigned & nGoodPoints,
175 unsigned & nBadPoints,
181 const std::vector<vigra::FImage*>& voteImgs,
184 std::vector<std::multimap<double,vigra_ext::PointPairRGB> >& radiusHist,
185 unsigned& nGoodPoints,
186 unsigned& nBadPoints,
213 :
PointSampler(panorama, progressDisplay, images, limits, nPoints)
221 template <
class Img,
class VoteImg,
class PP>
223 const std::vector<VoteImg *> &voteImgs,
227 std::vector<std::multimap<double, PP > > & radiusHist,
228 unsigned & nBadPoints,
234 const std::vector<vigra::FImage*>& voteImgs,
237 std::vector<std::multimap<double,vigra_ext::PointPairRGB> >& radiusHist,
238 unsigned& nGoodPoints,
239 unsigned& nBadPoints,
267 namespace HuginBase {
269 template<
class Po
intPairClass>
272 std::vector<PointPairClass> &selectedPoints,
275 typedef std::multimap<double,PointPairClass> PointPairMap;
278 int drawsPerBin = nPoints / radiusHist.size();
280 selectedPoints.reserve(drawsPerBin*radiusHist.size());
281 for (
typename std::vector<PointPairMap>::const_iterator bin = radiusHist.begin();
282 bin != radiusHist.end(); ++bin)
284 unsigned i=drawsPerBin;
286 for (
typename PointPairMap::const_iterator it= (*bin).begin();
287 it != (*bin).end(); ++it)
289 selectedPoints.push_back(it->second);
300 template <
class Img,
class VoteImg,
class PP>
302 const std::vector<VoteImg *> &voteImgs,
307 std::vector<std::multimap<double, PP > > & radiusHist,
308 unsigned & nGoodPoints,
309 unsigned & nBadPoints,
312 typedef typename Img::PixelType PixelType;
315 radiusHist.resize(10);
316 const unsigned pairsPerBin = nPoints / radiusHist.size();
320 vigra_precondition(imgs.size() > 1,
"sampleAllPanoPoints: At least two images required");
322 const unsigned nImg = imgs.size();
324 vigra::Size2D srcSize = pano.
getImage(0).getSize();
325 double maxr = sqrt(((
double)srcSize.x)*srcSize.x + ((
double)srcSize.y)*srcSize.y) / 2.0;
329 std::vector<PTools::Transform*> transf(imgs.size());
332 for(
unsigned i=0; i < nImg; i++) {
333 vigra_precondition(pano.
getImage(i).getSize() == srcSize,
"images need to have the same size");
339 for (
int y=roi.top(); y < roi.bottom(); ++y) {
340 for (
int x=roi.left(); x < roi.right(); ++x) {
342 for (
unsigned i=0; i< nImg-1; i++) {
345 if(!transf[i]->transformImgCoord(p1, panoPnt))
347 vigra::Point2D p1Int(p1.
toDiff2D());
355 if (imgs[i](p1.
x,p1.
y, i1, maskI)){
357 if (limitI[i].GetMinI() > im1 || limitI[i].GetMaxI() < im1 || maskI == 0) {
364 for (
unsigned j=i+1; j < nImg; j++) {
366 if(!transf[j]->transformImgCoord(p2, panoPnt))
368 vigra::Point2D p2Int(p2.
toDiff2D());
375 if (imgs[j](p2.
x, p2.
y, i2, maskI2)){
377 if (limitI[j].GetMinI() > im2 || limitI[j].GetMaxI() < im2 || maskI2 == 0) {
383 const VoteImg & vimg1 = *voteImgs[i];
384 const VoteImg & vimg2 = *voteImgs[j];
386 int bin1 = (int)(r1*10);
387 int bin2 = (int)(r2*10);
389 if (bin1 > 9) bin1 = 9;
390 if (bin2 > 9) bin2 = 9;
395 pp = PP(i, i1, p1, r1, j, i2, p2, r2);
397 pp = PP(j, i2, p2, r2, i, i1, p1, r1);
401 std::multimap<double, PP> * map1 = &radiusHist[bin1];
402 std::multimap<double, PP> * map2 = &radiusHist[bin2];
403 std::multimap<double, PP> * destMap;
406 }
else if (map2->empty()) {
408 }
else if (map1->size() < map2->size()) {
410 }
else if (map1->size() > map2->size()) {
412 }
else if (map1->rbegin()->first > map2->rbegin()->first) {
420 destMap->insert(std::make_pair(laplace,pp));
422 if (destMap->size() > pairsPerBin) {
423 destMap->erase((--(destMap->end())));
433 for(
unsigned i=0; i < nImg; i++) {
440 template <
class Img,
class VoteImg,
class PP>
442 const std::vector<VoteImg *> &voteImgs,
447 std::vector<std::multimap<double, PP > > & radiusHist,
448 unsigned & nBadPoints,
451 typedef typename Img::PixelType PixelType;
453 vigra_precondition(imgs.size() > 1,
"sampleRandomPanoPoints: At least two images required");
455 const unsigned nImg = imgs.size();
457 const unsigned nBins = radiusHist.size();
458 const unsigned pairsPerBin = nPoints / nBins;
462 std::vector<PTools::Transform *> transf(imgs.size());
463 std::vector<double> maxr(imgs.size());
466 for(
unsigned i=0; i < nImg; i++) {
471 vigra::Size2D srcSize = pano.
getImage(i).getSize();
472 maxr[i] = sqrt(((
double)srcSize.x)*srcSize.x + ((
double)srcSize.y)*srcSize.y) / 2.0;
476 std::mt19937 rng(static_cast<unsigned int>(std::time(0)));
477 std::uniform_int_distribution<unsigned int> distribx(roi.left(), roi.right()-1);
478 std::uniform_int_distribution<unsigned int> distriby(roi.top(), roi.bottom()-1);
479 auto randX = std::bind(distribx, std::ref(rng));
480 auto randY = std::bind(distriby, std::ref(rng));
482 for (
unsigned maxTry = nPoints*5; nPoints > 0 && maxTry > 0; maxTry--) {
483 unsigned x = randX();
484 unsigned y = randY();
486 for (
unsigned i=0; i< nImg-1; i++) {
490 if(!transf[i]->transformImgCoord(p1, panoPnt))
492 vigra::Point2D p1Int(p1.
toDiff2D());
499 if ( imgs[i](p1.
x,p1.
y, i1, maskI)){
501 if (limitI[i].GetMinI() > im1 || limitI[i].GetMaxI() < im1) {
506 for (
unsigned j=i+1; j < nImg; j++) {
509 if(!transf[j]->transformImgCoord(p2, panoPnt))
512 vigra::Point2D p2Int(p2.
toDiff2D());
518 if (imgs[j](p2.
x, p2.
y, i2, maskI2)){
520 if (limitI[j].GetMinI() > im2 || limitI[j].GetMaxI() < im2) {
529 points.push_back(PP(i, i1, p1, r1, j, i2, p2, r2) );
531 points.push_back(PP(j, i2, p2, r2, i, i1, p1, r1) );
535 const VoteImg & vimg1 = *voteImgs[i];
536 const VoteImg & vimg2 = *voteImgs[j];
538 size_t bin1 = (size_t)(r1*nBins);
539 size_t bin2 = (size_t)(r2*nBins);
541 if (bin1+1 > nBins) bin1 = nBins-1;
542 if (bin2+1 > nBins) bin2 = nBins-1;
547 pp = PP(i, i1, p1, r1, j, i2, p2, r2);
549 pp = PP(j, i2, p2, r2, i, i1, p1, r1);
553 std::multimap<double, PP> * map1 = &radiusHist[bin1];
554 std::multimap<double, PP> * map2 = &radiusHist[bin2];
555 std::multimap<double, PP> * destMap;
558 }
else if (map2->empty()) {
560 }
else if (map1->size() < map2->size()) {
562 }
else if (map1->size() > map2->size()) {
564 }
else if (map1->rbegin()->first > map2->rbegin()->first) {
572 destMap->insert(std::make_pair(laplace,pp));
574 if (destMap->size() > pairsPerBin) {
575 destMap->erase((--(destMap->end())));
585 for(
unsigned i=0; i < imgs.size(); i++) {
static void sampleRadiusUniform(const std::vector< std::multimap< double, PointPairClass > > &radiusHist, unsigned nPoints, std::vector< PointPairClass > &selectedPoints, AppBase::ProgressDisplay *)
extract some random points out of the bins.
class for storing the limits of an image used by the sampler to exclude too dark or too bright pixel ...
V getMaxComponent(vigra::RGBValue< V > const &v)
get the maximum component of a vector (also works for single pixel types...)
float m_minI
internal stored limits
LimitType
some pre-defined limits
PointSampler(PanoramaData &panorama, AppBase::ProgressDisplay *progressDisplay, std::vector< vigra::FRGBImage * > images, LimitIntensityVector limits, int nPoints)
virtual bool modifiesPanoramaData() const
returns true if the algorithm changes the PanoramaData.
virtual ~AllPointSampler()
const float GetMaxI() const
return the upper limit
hugin_utils::FDiff2D getRadialVigCorrCenter() const
AllPointSampler(PanoramaData &panorama, AppBase::ProgressDisplay *progressDisplay, std::vector< vigra::FRGBImage * > images, LimitIntensityVector limits, int nPoints)
"wrapper" for efficient interpolation access to an image
std::vector< vigra::FRGBImage * > o_images
bool isInside(vigra::Point2D p, bool ignoreMasks=false) const
check if a coordinate is inside the source image
virtual ~RandomPointSampler()
functions to manage ROI's
static void sampleAllPanoPoints(const std::vector< Img > &imgs, const std::vector< VoteImg * > &voteImgs, const PanoramaData &pano, int nPoints, const LimitIntensityVector limitI, std::vector< std::multimap< double, PP > > &radiusHist, unsigned &nGoodPoints, unsigned &nBadPoints, AppBase::ProgressDisplay *progress)
sample all points inside a panorama and check for create a bins of point pairs that include a specifi...
virtual void samplePoints(const std::vector< InterpolImg > &imgs, const std::vector< vigra::FImage * > &voteImgs, const PanoramaData &pano, const LimitIntensityVector limitI, std::vector< std::multimap< double, vigra_ext::PointPairRGB > > &radiusHist, unsigned &nGoodPoints, unsigned &nBadPoints, AppBase::ProgressDisplay *progress)
PointPairs getResultPoints()
LimitIntensityVector m_limits
const vigra::Rect2D & getROI() const
PointPairs o_resultPoints
virtual const PanoramaOptions & getOptions() const =0
returns the options for this panorama
virtual const SrcPanoImage & getImage(std::size_t nr) const =0
get a panorama image, counting starts with 0
virtual void samplePoints(const std::vector< InterpolImg > &imgs, const std::vector< vigra::FImage * > &voteImgs, const PanoramaData &pano, const LimitIntensityVector limitI, std::vector< std::multimap< double, vigra_ext::PointPairRGB > > &radiusHist, unsigned &nGoodPoints, unsigned &nBadPoints, AppBase::ProgressDisplay *progress)
static void sampleRandomPanoPoints(const std::vector< Img > &imgs, const std::vector< VoteImg * > &voteImgs, const PanoramaData &pano, int nPoints, const LimitIntensityVector limitI, std::vector< std::multimap< double, PP > > &radiusHist, unsigned &nBadPoints, AppBase::ProgressDisplay *progress)
std::vector< vigra_ext::PointPairRGB > PointPairs
std::vector< LimitIntensity > LimitIntensityVector
RandomPointSampler(PanoramaData &panorama, AppBase::ProgressDisplay *progressDisplay, std::vector< vigra::FRGBImage * > images, LimitIntensityVector limits, int nPoints)
vigra::Diff2D toDiff2D() const
const float GetMinI() const
return the lower limit