#include "find_features.h"

// ---------- Constructor ---------- //
FindFeatures::FindFeatures(std::string features_type,
	double w, double s) :
	work_megapix(w), seam_megapix(s) {
	if (features_type == "surf") {
		finder = new cv::detail::SurfFeaturesFinder();
	}
	else if (features_type == "orb") {
		finder = new cv::detail::OrbFeaturesFinder();
	}
	is_work_scale_set = false;
	is_seam_scale_set = false;
	seam_scale = 1;
}

int FindFeatures::find_features(std::vector<cv::Mat> &video_frames,
	std::vector<cv::detail::ImageFeatures> &features,
	std::vector<cv::Mat> &images,
	std::vector<cv::Size> &full_image_sizes,
	double &work_scale,
	double &seam_work_aspect) {
	for (size_t i = 0; i < video_frames.size(); ++i) {
		full_image = video_frames.at(i);
		full_image_sizes[i] = full_image.size();

		// Set work scale
		if (!is_work_scale_set) {
			work_scale = cv::min(1.0, sqrt(work_megapix * 1e6 / full_image.size().area()));
			is_work_scale_set = true;
		}
		cv::resize(full_image, image, cv::Size(), work_scale, work_scale);

		// Set seam scale
		if (!is_seam_scale_set) {
			seam_scale = cv::min(1.0, sqrt(seam_megapix * 1e6 / full_image.size().area()));
			seam_work_aspect = seam_scale / work_scale;
			is_seam_scale_set = true;
		}

		// Find features
		(*finder)(image, features[i]);
		features[i].img_idx = i;

		cv::resize(full_image, image, cv::Size(), seam_scale, seam_scale);

		images[i] = image.clone();
	}

	// Release memory
	finder->collectGarbage();

	return 0;
}
