#include "BoF.h"

#define CODEBOOK



int main()
{
	int type = BoF::SIFT; // 特徴量の種類 SIFT or SURF

	BoF myBoF;
	// databaseから特徴点の検出
	myBoF.detectFeature("./database/", 0, 199, type);

#ifdef CODEBOOK
	// databaseの特徴量の記述
	myBoF.computeDescriptors(type);

	cv::TermCriteria tc(CV_TERMCRIT_ITER, 10, 0.001); // 停止条件
	// k-meansクラスタリングを用いてコードブックの生成 500種類のvisual word
	myBoF.createCodebook(500, tc, 1, cv::KMEANS_PP_CENTERS);

	myBoF.saveCodebook("./codebook_SIFT.xml");

#else
	myBoF.loadCodebook("./codebook_SIFT.xml");
	// databaseの画像記述子の生成
	myBoF.createImageDescriptorsForImages(type);

	// query画像を1枚ごとに識別する
	for (int i = 0; i < 100; ++i) {
		std::stringstream str;
		str << "./query/image(" << i << ").jpg";
		cv::Mat img = cv::imread(str.str());
		
		cv::Mat similarImage;

		double dist = -1;
		int mostSimilarImageIndex = -1;
		// 類似度の計算
		myBoF.computeMostSimilarImage(img, similarImage, mostSimilarImageIndex, dist, type);

		std::cout << "[" << i << "] : ";
		if (i < 50) {
			std::cout << "山 → ";
		}
		else {
			std::cout << "森 → ";
		}

		// 識別結果の表示
		if (mostSimilarImageIndex < 100) {
			std::cout << "result : 山 (index : " << mostSimilarImageIndex << ", 類似度 : " << dist;
		}
		else {
			std::cout << "result : 森 (index : " << mostSimilarImageIndex << ", 類似度 : " << dist;
		}

		std::cout << ")\n";

		// 結果を画像で1枚ずつ見たいときはコメントアウトをはずす
		/*cv::imshow("img", img);
		cv::imshow("similarImage", similarImage);
		cv::waitKey();*/
	}
#endif

	std::cout << "\n";

	return 0;
}
	