/** 
 * @file IDSIFTSampling.cpp
 * @brief random interest point sampling
 * @author Erik Rodner
 * @date 02/05/2008

 */
#include <iostream>

#include "vislearning/features/localfeatures/IDSIFTSampling.h"
#include "vislearning/features/localfeatures/sift.h"
#include "core/image/ImageTools.h"

using namespace OBJREC;

using namespace std;

using namespace NICE;

IDSIFTSampling::IDSIFTSampling(const Config *conf)
{
	threshold = conf->gD("IDSIFTSampling", "threshold", 0.0);
	edgeThreshold = conf->gD("IDSIFTSampling", "edge_threshold", 10.0);
	minScale = conf->gD("IDSIFTSampling", "min_scale", 1.0);
	fixedOrientation = conf->gB("IDSIFTSampling", "fixed_orientation", true);
	octaves = conf->gI("IDSIFTSampling", "octaves", 6);
	levels = conf->gI("IDSIFTSampling", "levels", 3);
	first_octave = conf->gI("IDSIFTSampling", "first_octave", -1);
	magnif = conf->gD("IDSIFTSampling", "magnif", 1.5);
	deletemode = conf->gB("IDSIFTSampling", "deletemode", true);
	srand(time(NULL));
}

IDSIFTSampling::~IDSIFTSampling()
{
}

int IDSIFTSampling::getInterests(const Image & img,
		std::vector<Vector> & positions) const
{

	int O = octaves;
	int const S = levels;
	int const omin = first_octave;

	float const sigman = .5;
	float const sigma0 = 1.6 * powf(2.0f, 1.0f / S);

	if (O < 1)
	{
		O = std::max(int(std::floor(log2(std::min(img.width(), img.height())))
				- omin - 3), 1);
	}

	const unsigned char *blockimg = (unsigned char*) img.getPixelPointer();
	if (blockimg == NULL)
	{
		fprintf(stderr, "FATAL ERROR: do not use subimages !!\n");
		exit(-1);
	}
	float *blockimgfl = new float[img.width() * img.height()];
	for (int k = 0; k < img.width() * img.height(); k++)
		blockimgfl[k] = blockimg[k];

	VL::Sift sift(blockimgfl, img.width(), img.height(), sigman, sigma0, O, S,
			omin, -1, S + 1);

	sift.process(blockimgfl, img.width(), img.height());
	// compute keypoints
	sift.detectKeypoints(threshold, edgeThreshold);

	int keypointCount = 0;

	for (VL::Sift::KeypointsConstIter iter = sift.keypointsBegin(); iter
			!= sift.keypointsEnd(); ++iter, keypointCount++)
	{
		NICE::Vector p(3);
		p[0] = iter->x;
		p[1] = iter->y;
		p[2] = iter->s;

		positions.push_back(p);
		keypointCount++;
	}
	delete[] blockimgfl;
	fprintf(stderr, "IDSIFTSampling:: Number of Keypoints = %d\n",
			keypointCount);

	if (keypointCount <= 0)
		fprintf(stderr, "FATAL ERROR: no keypoints found !!\n");
	return 0;
}
int IDSIFTSampling::getInterests(const ImagePyramid & imp,
		std::vector<Vector> & positions) const
{
	int numLevels = imp.getNumLevels();
	if (numLevels > 0)
	{
		const NICE::Image & img = imp.getLevel(0);
		getInterests(img, positions);
		return 0;
	}
	else
	{
		fprintf(stderr, "IDSIFTSampling: Pyramid is too small (level==0)\n");
		return -1;
	}
}
