// Classifier.cpp - Obsahuje definice exportovaných funkcí tvořících rozhraní pro klasifikátor
// Autor:   Jan Benda
// Datum:   25.10.2020

#include "Classifier.h"

namespace Classification
    {
    //Vytvoří vektor příznaků v závislosti na vstupním parametru iVersion
    std::vector<float> createFeatureVector(const std::vector<float> iFeatureValues, const std::vector<std::string> iFeatureNames, INT16 iVersion)
        {
        std::vector<float> temp_features;

        if(iVersion < 1)
            throw std::exception("Wrong version of feature vector");

        if((iVersion & 1) == 1)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Solidity", iFeatureNames)));
        if((iVersion & 2) == 2)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Angle", iFeatureNames)));
        if((iVersion & 4) == 4)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Extent", iFeatureNames)));
        if((iVersion & 8) == 8)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Max_width", iFeatureNames)));
        if((iVersion & 16) == 16)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Max_height", iFeatureNames)));
        if((iVersion & 32) == 32)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Aspect_ratio", iFeatureNames)));
        if((iVersion & 64) == 64)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Area", iFeatureNames)));
        if((iVersion & 128) == 128)
            temp_features.push_back(iFeatureValues.at(General::getIndex("QMIN", iFeatureNames)));
        if((iVersion & 256) == 256)
            temp_features.push_back(iFeatureValues.at(General::getIndex("QMAX", iFeatureNames)));
        if((iVersion & 512) == 512)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Q25", iFeatureNames))); 
        if((iVersion & 1024) == 1024)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Q50", iFeatureNames)));
        if((iVersion & 2048) == 2048)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Q50_out", iFeatureNames)));
        if((iVersion & 4096) == 4096)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Q75", iFeatureNames)));
        if((iVersion & 8192) == 8192)
            temp_features.push_back(iFeatureValues.at(General::getIndex("Homogenity", iFeatureNames)));
        return temp_features;
        }

    //Vytvoří matici priznaku, ze ktere bude vytvořena trenovaci mnozina
    cv::Mat createFeatureMatrix(const std::vector<Dataset::TrainingSample> iTraining, INT16 iVersion)
        {
        cv::Mat temp_matrix = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, iVersion), true);
        for(int i = 1; i < iTraining.size(); i++)
            hconcat(temp_matrix, cv::Mat(createFeatureVector(iTraining.at(i).iFeatureValues, iTraining.at(i).iFeatureNames, iVersion), true), temp_matrix);

        temp_matrix.convertTo(temp_matrix, CV_32F);
        return temp_matrix;
        }

    //Vytvoří matici trid, ze ktere bude vytvořena trenovaci mnozina
    cv::Mat createLabelMatrix(const std::vector<Dataset::TrainingSample> iTraining, std::vector<std::string> iLabels)
        {
        cv::Mat temp_matrix;
        std::vector<int> temp_count, temp_class;

        size_t temp_n = iLabels.size();
        size_t nClasses = 0;
        if(temp_n > 0)
            nClasses = temp_n;
        else
            return cv::Mat::zeros(1, 1, CV_32FC1);

        for(size_t j = 0; j < nClasses; j++)
            {
            if(j != (size_t) General::getIndex(iTraining.at(0).iLabel, iLabels))
                temp_class.push_back(0);
            else
                temp_class.push_back(1);
            }

        temp_matrix = cv::Mat(temp_class);
        temp_class.clear();

        for(size_t i = 1; i < iTraining.size(); i++)
            {
            for(size_t j = 0; j < nClasses; j++)
                {
                if(j != (size_t) General::getIndex(iTraining.at(i).iLabel, iLabels))
                    temp_class.push_back(0);
                else
                    temp_class.push_back(1);
                }
            hconcat(temp_matrix, cv::Mat(temp_class), temp_matrix);
            temp_class.clear();

            }
        temp_matrix.convertTo(temp_matrix, CV_32F);
        return temp_matrix;
        }

    //Vytvoří vektor trid, ze ktereho bude vytvořena trenovaci mnozina
    std::vector<int> createLabelVector(const std::vector<Dataset::TrainingSample> iTraining, std::vector<std::string> iLabels)
        {
        std::vector<int> temp_labels;
        for(int l = 0; l < iTraining.size(); l++)
            temp_labels.push_back(General::getIndex(iTraining.at(l).iLabel, iLabels));
        return temp_labels;
        }

    Classifiers trainClassifiers(const std::vector<Dataset::TrainingSample> iTraining, const short iID)
        {
        if(iTraining.size() < 1)
            throw std::exception(("V trenovacim datasetu (" + std::to_string(iID) + ") nejsou data").c_str());

        Classifiers temp_classifiers;

        // BAYES
        temp_classifiers.bayesClassifier = cv::ml::NormalBayesClassifier::create();

        // K-NEAREST
        temp_classifiers.knearestClassifier = cv::ml::KNearest::create();

        // SVM
        temp_classifiers.svmClassifier = cv::ml::SVM::create();

        // RANDOM TREES
        temp_classifiers.rtreesClassifier = cv::ml::RTrees::create();

        // ANN_MLP
        temp_classifiers.annClassifier = cv::ml::ANN_MLP::create();
        cv::Mat layer_sizes;

        for(size_t i = 0; i < iTraining.size(); i++)
            if(General::getIndex(iTraining.at(i).iLabel, temp_classifiers.iLabels) < 0)
                temp_classifiers.iLabels.push_back(iTraining.at(i).iLabel);

        switch(iID) 
            {
            case 9:
                {
                temp_classifiers.bayesClassifier->train(createFeatureMatrix(iTraining, bayes_9), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.knearestClassifier->setIsClassifier(true);
                temp_classifiers.knearestClassifier->setAlgorithmType(1);
                temp_classifiers.knearestClassifier->train(createFeatureMatrix(iTraining, knearest_9), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.svmClassifier->setType(cv::ml::SVM::C_SVC);
                temp_classifiers.svmClassifier->setKernel(cv::ml::SVM::INTER);
                try
                    {
                    temp_classifiers.svmClassifier->trainAuto(cv::ml::TrainData::create(createFeatureMatrix(iTraining, svm_9), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels)), 10);
                    }
                catch (std::exception)
                    {
                    temp_classifiers.svmClassifier->train(createFeatureMatrix(iTraining, svm_9), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));
                    }
                temp_classifiers.rtreesClassifier->setActiveVarCount(4);
                temp_classifiers.rtreesClassifier->train(createFeatureMatrix(iTraining, rtrees_9), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));


                cv::Mat samples = createFeatureMatrix(iTraining, ann_9), responses = createLabelMatrix(iTraining, temp_classifiers.iLabels);
                layer_sizes = cv::Mat(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) responses.rows;
                temp_classifiers.annClassifier->setLayerSizes(layer_sizes);
                temp_classifiers.annClassifier->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM, 1.8, 1.8);
                temp_classifiers.annClassifier->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                temp_classifiers.annClassifier->train(samples, cv::ml::COL_SAMPLE, responses);
                }
                break;
            case 10:
                {
                temp_classifiers.bayesClassifier->train(createFeatureMatrix(iTraining, bayes_10), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.knearestClassifier->setIsClassifier(true);
                temp_classifiers.knearestClassifier->setDefaultK(2);
                temp_classifiers.knearestClassifier->setAlgorithmType(0);
                temp_classifiers.knearestClassifier->train(createFeatureMatrix(iTraining, knearest_10), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.svmClassifier->setType(cv::ml::SVM::C_SVC);
                temp_classifiers.svmClassifier->setKernel(cv::ml::SVM::INTER);
                temp_classifiers.svmClassifier->train(createFeatureMatrix(iTraining, svm_10), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.rtreesClassifier->setActiveVarCount(0);
                temp_classifiers.rtreesClassifier->train(createFeatureMatrix(iTraining, rtrees_10), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                cv::Mat samples = createFeatureMatrix(iTraining, ann_10), responses = createLabelMatrix(iTraining, temp_classifiers.iLabels);
                layer_sizes = cv::Mat(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) responses.rows;
                temp_classifiers.annClassifier->setLayerSizes(layer_sizes);
                temp_classifiers.annClassifier->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM, 1.8, 1.8);
                temp_classifiers.annClassifier->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                temp_classifiers.annClassifier->train(samples, cv::ml::COL_SAMPLE, responses);
                }
                break;
            case 11:
                {
                temp_classifiers.bayesClassifier->train(createFeatureMatrix(iTraining, bayes_11), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.knearestClassifier->setIsClassifier(true);
                temp_classifiers.knearestClassifier->setDefaultK(5);
                temp_classifiers.knearestClassifier->setAlgorithmType(1);
                temp_classifiers.knearestClassifier->train(createFeatureMatrix(iTraining, knearest_11), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.svmClassifier->setType(cv::ml::SVM::C_SVC);
                temp_classifiers.svmClassifier->setKernel(cv::ml::SVM::INTER);
                try
                    {
                    temp_classifiers.svmClassifier->trainAuto(cv::ml::TrainData::create(createFeatureMatrix(iTraining, svm_11), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels)), 10);
                    }
                catch(std::exception)
                    {
                    temp_classifiers.svmClassifier->train(createFeatureMatrix(iTraining, svm_11), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));
                    }

                temp_classifiers.rtreesClassifier->setActiveVarCount(0);
                temp_classifiers.rtreesClassifier->train(createFeatureMatrix(iTraining, rtrees_11), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                cv::Mat samples = createFeatureMatrix(iTraining, ann_11), responses = createLabelMatrix(iTraining, temp_classifiers.iLabels);
                layer_sizes = cv::Mat(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) responses.rows;
                temp_classifiers.annClassifier->setLayerSizes(layer_sizes);
                temp_classifiers.annClassifier->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM, 1.8, 1.8);
                temp_classifiers.annClassifier->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                temp_classifiers.annClassifier->train(samples, cv::ml::COL_SAMPLE, responses);
                }
                break;
            case 12:
                {
                temp_classifiers.bayesClassifier->train(createFeatureMatrix(iTraining, bayes_12), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.knearestClassifier->setIsClassifier(true);
                temp_classifiers.knearestClassifier->setDefaultK(10);
                temp_classifiers.knearestClassifier->setAlgorithmType(0);
                temp_classifiers.knearestClassifier->train(createFeatureMatrix(iTraining, knearest_12), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                temp_classifiers.svmClassifier->setType(cv::ml::SVM::C_SVC);
                temp_classifiers.svmClassifier->setKernel(cv::ml::SVM::INTER);
                try
                    {
                    temp_classifiers.svmClassifier->trainAuto(cv::ml::TrainData::create(createFeatureMatrix(iTraining, svm_12), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels)), 10);
                    }
                catch(std::exception)
                    {
                    temp_classifiers.svmClassifier->train(createFeatureMatrix(iTraining, svm_12), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));
                    }

                temp_classifiers.rtreesClassifier->setActiveVarCount(0);
                temp_classifiers.rtreesClassifier->train(createFeatureMatrix(iTraining, rtrees_12), cv::ml::COL_SAMPLE, createLabelVector(iTraining, temp_classifiers.iLabels));

                cv::Mat samples = createFeatureMatrix(iTraining, ann_12), responses = createLabelMatrix(iTraining, temp_classifiers.iLabels);
                layer_sizes = cv::Mat(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) responses.rows;
                temp_classifiers.annClassifier->setLayerSizes(layer_sizes);
                temp_classifiers.annClassifier->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM, 1.8, 1.8);
                temp_classifiers.annClassifier->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                temp_classifiers.annClassifier->train(samples, cv::ml::COL_SAMPLE, responses);
                }
                break;
            default:
                throw std::exception("Wrong ID");
                break;
            }

        return temp_classifiers;
        }

    void clear(Classifiers& iClassifier)
        {
        if(!iClassifier.bayesClassifier.empty())
            {
            iClassifier.bayesClassifier->clear();
            iClassifier.bayesClassifier = nullptr;
            }
        if(!iClassifier.knearestClassifier.empty())
            {
            iClassifier.knearestClassifier->clear();
            iClassifier.knearestClassifier = nullptr;
            }
        if(!iClassifier.svmClassifier.empty())
            {
            iClassifier.svmClassifier->clear();
            iClassifier.svmClassifier = nullptr;
            }
        if(!iClassifier.rtreesClassifier.empty())
            {
            iClassifier.rtreesClassifier->clear();
            iClassifier.rtreesClassifier = nullptr;
            }
        if(!iClassifier.annClassifier.empty())
            {
            iClassifier.annClassifier->clear();
            iClassifier.annClassifier = nullptr;
            }
        iClassifier.iLabels.clear();
        iClassifier.iLabels.shrink_to_fit();
        }

    bool trained(Classifiers iClassifiers)
        {
        if(iClassifiers.bayesClassifier.empty())
            return false;
        else if(!iClassifiers.bayesClassifier->isTrained())
            return false;
        if(iClassifiers.knearestClassifier.empty())
            return false;
        else if(!iClassifiers.knearestClassifier->isTrained())
            return false;
        if(iClassifiers.svmClassifier.empty())
            return false;
        else if(!iClassifiers.svmClassifier->isTrained())
            return false;
        if(iClassifiers.rtreesClassifier.empty())
            return false;
        else if(!iClassifiers.rtreesClassifier->isTrained())
            return false;
        if(iClassifiers.annClassifier.empty())
            return false;
        else if(!iClassifiers.annClassifier->isTrained())
            return false;
        return true;
        }

    void sortAnnResponses(std::vector<float> iResponses, std::vector<float>& iWeights, std::vector<std::string>& iLabels, const std::vector<std::string> iNames)
        {
        iWeights.clear();
        iWeights.shrink_to_fit();
        iLabels.clear();
        iLabels.shrink_to_fit();

        for(size_t i = 0; i < 3; i++)
            {
            iWeights.push_back(-2);
            iLabels.push_back("0");
            }

        for(size_t i = 0; i < iResponses.size(); i++)
            {

            if(iResponses.at(i) > iWeights.at(0))
                {
                iWeights.at(2) = iWeights.at(1);
                iLabels.at(2) = iLabels.at(1);

                iWeights.at(1) = iWeights.at(0);
                iLabels.at(1) = iLabels.at(0);

                iWeights.at(0) = iResponses.at(i);
                iLabels.at(0) = iNames.at(i);
                }
            else if(iResponses.at(i) > iWeights.at(1))
                {
                iWeights.at(2) = iWeights.at(1);
                iLabels.at(2) = iLabels.at(1);

                iWeights.at(1) = iResponses.at(i);
                iLabels.at(1) = iNames.at(i);
                }
            else if(iResponses.at(i) > iWeights.at(2))
                {
                iWeights.at(2) = iResponses.at(i);
                iLabels.at(2) = iNames.at(i);
                }
            }
        }

    void testSample(Dataset::TestingSample& iSample, const Classifiers& iModels, const short iID)
        {
        switch(iID)
            {
            case 9:
                {
                if(!iModels.bayesClassifier.empty())
                    iSample.iPredictions.bayesLabel = iModels.iLabels.at((int) iModels.bayesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, bayes_9)));
                else
                    throw std::exception(("Bayesuv klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.knearestClassifier.empty())
                    iSample.iPredictions.knearestLabel = iModels.iLabels.at((int) iModels.knearestClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, knearest_9)));
                else
                    throw std::exception(("K-Nearest klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.svmClassifier.empty())
                    iSample.iPredictions.svmLabel = iModels.iLabels.at((int) iModels.svmClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, svm_9)));
                else
                    throw std::exception(("SVM klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.rtreesClassifier.empty())
                    iSample.iPredictions.rtreesLabel = iModels.iLabels.at((int) iModels.rtreesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, rtrees_9)));
                else
                    throw std::exception(("D-Trees klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                cv::Mat responses;
                if(!iModels.annClassifier.empty())
                    iModels.annClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, ann_9), responses);
                else
                    throw std::exception(("ANN_MLP klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                
                sortAnnResponses(responses, iSample.iPredictions.annWeights, iSample.iPredictions.annLabels, iModels.iLabels);
                }
                break;
            case 10:
                {
                if(!iModels.bayesClassifier.empty())
                    iSample.iPredictions.bayesLabel = iModels.iLabels.at((int) iModels.bayesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, bayes_10)));
                else
                    throw std::exception(("Bayesuv klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.knearestClassifier.empty())
                    iSample.iPredictions.knearestLabel = iModels.iLabels.at((int) iModels.knearestClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, knearest_10)));
                else
                    throw std::exception(("K-Nearest klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.svmClassifier.empty())
                    iSample.iPredictions.svmLabel = iModels.iLabels.at((int) iModels.svmClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, svm_10)));
                else
                    throw std::exception(("SVM klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.rtreesClassifier.empty())
                    iSample.iPredictions.rtreesLabel = iModels.iLabels.at((int) iModels.rtreesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, rtrees_10)));
                else
                    throw std::exception(("D-Trees klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                cv::Mat responses;
                if(!iModels.annClassifier.empty())
                    iModels.annClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, ann_10), responses);
                else
                    throw std::exception(("ANN_MLP klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                sortAnnResponses(responses, iSample.iPredictions.annWeights, iSample.iPredictions.annLabels, iModels.iLabels);
                }
                break;
            case 11:
                {
                if(!iModels.bayesClassifier.empty())
                    iSample.iPredictions.bayesLabel = iModels.iLabels.at((int) iModels.bayesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, bayes_11)));
                else
                    throw std::exception(("Bayesuv klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.knearestClassifier.empty())
                    iSample.iPredictions.knearestLabel = iModels.iLabels.at((int) iModels.knearestClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, knearest_11)));
                else
                    throw std::exception(("K-Nearest klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.svmClassifier.empty())
                    iSample.iPredictions.svmLabel = iModels.iLabels.at((int) iModels.svmClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, svm_11)));
                else
                    throw std::exception(("SVM klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.rtreesClassifier.empty())
                    iSample.iPredictions.rtreesLabel = iModels.iLabels.at((int) iModels.rtreesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, rtrees_11)));
                else
                    throw std::exception(("D-Trees klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                cv::Mat responses;
                if(!iModels.annClassifier.empty())
                    iModels.annClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, ann_11), responses);
                else
                    throw std::exception(("ANN_MLP klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                sortAnnResponses(responses, iSample.iPredictions.annWeights, iSample.iPredictions.annLabels, iModels.iLabels);
                }
                break;
            case 12:
                {
                if(!iModels.bayesClassifier.empty())
                    iSample.iPredictions.bayesLabel = iModels.iLabels.at((int) iModels.bayesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, bayes_12)));
                else
                    throw std::exception(("Bayesuv klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.knearestClassifier.empty())
                    iSample.iPredictions.knearestLabel = iModels.iLabels.at((int) iModels.knearestClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, knearest_12)));
                else
                    throw std::exception(("K-Nearest klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.svmClassifier.empty())
                    iSample.iPredictions.svmLabel = iModels.iLabels.at((int) iModels.svmClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, svm_12)));
                else
                    throw std::exception(("SVM klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());
                if(!iModels.rtreesClassifier.empty())
                    iSample.iPredictions.rtreesLabel = iModels.iLabels.at((int) iModels.rtreesClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, rtrees_12)));
                else
                    throw std::exception(("D-Trees klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                cv::Mat responses;
                if(!iModels.annClassifier.empty())
                    iModels.annClassifier->predict(createFeatureVector(iSample.iFeatureValues, iSample.iFeatureNames, ann_12), responses);
                else
                    throw std::exception(("ANN_MLP klasifikator neni pro ID = " + std::to_string(iID) + " natrenovan").c_str());

                sortAnnResponses(responses, iSample.iPredictions.annWeights, iSample.iPredictions.annLabels, iModels.iLabels);
                }
                break;
            default:
                break;
            }
        }

    std::string LUTable(std::string iLabel)
        {
        if(iLabel == "90901")
            return "Necistota-podsvit";
        else if(iLabel == "90902")
            return "Prulet-podsvit";
        else if(iLabel == "90903")
            return "Ukap-podsvit";
        else if(iLabel == "90904")
            return "Ukap s dirou-podsvit";
        else if(iLabel == "90905")
            return "Ulet-podsvit";
        else if(iLabel == "90909")
            return "Zeslab. misto-podsvit";
        else if(iLabel == "90911")
            return "Dira-podsvit";

        else if(iLabel == "91003")
            return "Ukap-podsvit";
        else if(iLabel == "91006")
            return "Utrzene vlakno-podsvit";
        else if(iLabel == "91007")
            return "Vlastovka-podsvit";
        else if(iLabel == "91008")
            return "Zesilene misto-podsvit";
        else if(iLabel == "91010")
            return "Sklad-podsvit";
        else if(iLabel == "91015")
            return "Avivaz-podsvit";

        else if(iLabel == "91101")
            return "Necistota-nadsvit";
        else if(iLabel == "91102")
            return "Prulet-nadsvit";
        else if(iLabel == "91109")
            return "Zeslab. misto-nadsvit";
        else if(iLabel == "91112")
            return "Muska-nadsvit";

        else if(iLabel == "91203")
            return "Ukap-nadsvit";
        else if(iLabel == "91204")
            return "Ukap s dirou-nadsvit";
        else if(iLabel == "91205")
            return "Ulet-nadsvit";
        else if(iLabel == "91206")
            return "Utrzene vlakno-nadsvit";
        else if(iLabel == "91207")
            return "Vlastovka-nadsvit";
        else if(iLabel == "91208")
            return "Zesilene misto-nadsvit";
        else if(iLabel == "91210")
            return "Sklad-nadsvit";
        else if(iLabel == "91213")
            return "Praseni-nadsvit";
        else if(iLabel == "91214")
            return "Dlouhy tenky ulet-nadsvit";

        else //(iLabel == "0")
            return "";
        }

    void fMaxSearch(std::string iFilename, const std::vector<Dataset::TrainingSample>& iTraining, std::vector<Dataset::TestingSample>& iTesting, const short ID)
        {
        cv::Mat labels;
        std::vector<std::string> names;
        for(size_t i = 0; i < iTraining.size(); i++)
            if(General::getIndex(iTraining.at(i).iLabel, names) < 0)
                names.push_back(iTraining.at(i).iLabel);

        labels = createLabelMatrix(iTraining, names);
        std::vector<std::vector<float>> success_rate;
        int count_neural = 0, count_bayes = 0, count_knearest = 0, count_svm = 0, count_rtrees = 0, count = 0;

        if(iTraining.at(0).iFeatureValues.size() < 13)
            return;

        std::ofstream myFile(iFilename);
        myFile << "version";
        myFile << ";";
        myFile << "Bayes";
        myFile << ";";
        myFile << "KNearest";
        myFile << ";";
        myFile << "SVM";
        myFile << ";";
        myFile << "R-Trees";
        myFile << ";";
        myFile << "Neural net";
        myFile << "\n";

        try
            {
            for(int version = 1; version < 16384; version++)
                {
                // trenovaci mnozina
                cv::Mat samples = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, version), true);
                for(int t = 1; t < iTraining.size(); t++)
                    hconcat(samples, cv::Mat(createFeatureVector(iTraining.at(t).iFeatureValues, iTraining.at(t).iFeatureNames, version), true), samples);
                samples.convertTo(samples, CV_32F);
                cv::Ptr<cv::ml::TrainData> tdata = cv::ml::TrainData::create(samples, cv::ml::COL_SAMPLE, labels);

                // vynulovani uspesnosti
                count_neural = 0;
                count_bayes = 0;
                count_knearest = 0;
                count_svm = 0;
                count_rtrees = 0;
                count = 0;

                std::vector<int> labels1;
                for(int l = 0; l < iTraining.size(); l++)
                    labels1.push_back(std::stoi(iTraining.at(l).iLabel));

                // BAYES
                cv::Ptr<cv::ml::NormalBayesClassifier> model_bayes = cv::ml::NormalBayesClassifier::create();
                model_bayes->train(samples, cv::ml::COL_SAMPLE, labels1);

                // K-NEAREST
                cv::Ptr<cv::ml::KNearest> model_knearest = cv::ml::KNearest::create();
                model_knearest->train(samples, cv::ml::COL_SAMPLE, labels1);
                
                // SVM
                cv::Ptr<cv::ml::SVM> model_svm = cv::ml::SVM::create();
                //model_svm->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS, 1000, FLT_EPSILON));
                model_svm->train(samples, cv::ml::COL_SAMPLE, labels1);

                // RANDOM TREES
                cv::Ptr<cv::ml::RTrees> model_rtrees = cv::ml::RTrees::create();
                //model_rtrees->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS, 1000, FLT_EPSILON));
                model_rtrees->train(samples, cv::ml::COL_SAMPLE, labels1);

                // ANN_MLP
                cv::Mat layer_sizes(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) names.size();

                cv::Ptr<cv::ml::ANN_MLP> model_neural = cv::ml::ANN_MLP::create();
                model_neural->setLayerSizes(layer_sizes);
                model_neural->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM, 1.8, 1.8);
                //model_neural->setTermCriteria(cv::TermCriteria(cv::TermCriteria::EPS, 1000, FLT_EPSILON));
                model_neural->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                model_neural->train(tdata);
                
                for(int t = 0; t < iTesting.size(); t++)
                    {
                    if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                        {
                        count++;
                        std::vector<float> features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, version);
                        int res = 0;

                        std::string temp = iTesting.at(t).iSamplePath;
                        size_t last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(last_slash_idx);
                                last_slash_idx = temp.find_last_of("\\/");
                                if(std::string::npos != last_slash_idx)
                                    {
                                    temp.erase(0, last_slash_idx + 1);
                                    last_slash_idx = temp.find_first_of("_");
                                    if(std::string::npos != last_slash_idx)
                                        temp.erase(last_slash_idx);
                                    }
                                }
                            }

                        // BAYES
                        res = (int)model_bayes->predict(features);                               // 91003
                        if(temp == std::to_string((int) res))
                            count_bayes++;

                        // KNEAREST
                        res = (int)model_knearest->predict(features);                            // 91003
                        if(temp == std::to_string((int) res))
                            count_knearest++;

                        
                        // SVM
                        res = (int)model_svm->predict(features);                                 // 91003
                        if(temp == std::to_string((int) res))
                            count_svm++;

                        // R-TREES
                        res = (int)model_rtrees->predict(features);                              // 91007
                        if(temp == std::to_string((int) res))
                            count_rtrees++;

                        // NEURAL NET 2
                        res = (int)model_neural->predict(features);                              //2
                        if(General::getIndex(temp, names) == res)
                            count_neural++;
                        }
                    }


                //tisk do souboru
                myFile << std::to_string(version);
                myFile << ";";
                myFile << std::to_string((float) count_bayes / (float) count);
                myFile << ";";
                myFile << std::to_string((float) count_knearest / (float) count);
                myFile << ";";
                myFile << std::to_string((float) count_svm / (float) count);
                myFile << ";";
                myFile << std::to_string((float) count_rtrees / (float) count);
                myFile << ";";
                myFile << std::to_string((float) count_neural / (float) count);
                myFile << "\n";
                }
            }
        catch(std::exception& e)
            {
            myFile.close();
            }
        myFile.close();
        }

    void getVersions(std::string filename, std::vector<int>& bayes, std::vector<int>& knearest, std::vector<int>& svm, std::vector<int>& rtrees, std::vector<int>& ann)
        {
        std::ifstream myFile(filename);
        std::string Line = "";
        std::string Delimeter = ";";
        int Length = 0;

        for(int n = 0; n < 10; n++)
            {
            if(getline(myFile, Line))
                {
                if(n < 1)
                    Line.erase(0, 3);
                Length = Line.find(";");
                bayes.push_back(std::stoi(Line.substr(0, Length)));
                Line.erase(0, Length + Delimeter.length());

                Length = Line.find(";");
                knearest.push_back(std::stoi(Line.substr(0, Length)));
                Line.erase(0, Length + Delimeter.length());

                Length = Line.find(";");
                svm.push_back(std::stoi(Line.substr(0, Length)));
                Line.erase(0, Length + Delimeter.length());

                Length = Line.find(";");
                rtrees.push_back(std::stoi(Line.substr(0, Length)));
                Line.erase(0, Length + Delimeter.length());

                Length = Line.find(";");
                ann.push_back(std::stoi(Line.substr(0, Length)));
                Line.erase(0, Length + Delimeter.length());
                }
            }
        myFile.close();
        }

    void getTable(std::string iFilename, Classifiers iClassifiers, std::vector<Dataset::TestingSample>& iTesting, const short ID)
        {
        std::vector<std::vector<int>> count_ann, count_bayes, count_knearest, count_svm, count_rtrees;
        std::ofstream myFile(iFilename);

        try
            {
            for(size_t i = 0; i < iClassifiers.iLabels.size(); i++)
                {
                count_bayes.push_back({ 0, });
                count_knearest.push_back({ 0, });
                count_svm.push_back({ 0, });
                count_rtrees.push_back({ 0, });
                count_ann.push_back({ 0, });
                for(size_t j = 0; j < iClassifiers.iLabels.size() - 1; j++)
                    {
                    count_bayes.at(i).push_back(0);
                    count_knearest.at(i).push_back(0);
                    count_svm.at(i).push_back(0);
                    count_rtrees.at(i).push_back(0);
                    count_ann.at(i).push_back(0);
                    }
                }

            for(int t = 0; t < iTesting.size(); t++)
                {
                if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                    {
                    std::string temp = iTesting.at(t).iSamplePath;
                    size_t last_slash_idx = temp.find_last_of("\\/");
                    if(std::string::npos != last_slash_idx)
                        {
                        temp.erase(last_slash_idx);
                        last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(0, last_slash_idx + 1);
                                last_slash_idx = temp.find_first_of("_");
                                if(std::string::npos != last_slash_idx)
                                    temp.erase(last_slash_idx);
                                }
                            }
                        }
                    std::vector<float> features;
                    if(ID == 9)
                        {
                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, bayes_9);
                        count_bayes.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.bayesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, knearest_9);
                        count_knearest.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.knearestClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, svm_9);
                        count_svm.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.svmClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, rtrees_9);
                        count_rtrees.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.rtreesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_9);
                        count_ann.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.annClassifier->predict(features))++;
                        }
                    if(ID == 10)
                        {
                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, bayes_10);
                        count_bayes.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.bayesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, knearest_10);
                        count_knearest.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.knearestClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, svm_10);
                        count_svm.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.svmClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, rtrees_10);
                        count_rtrees.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.rtreesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_10);
                        count_ann.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.annClassifier->predict(features))++;
                        }
                    if(ID == 11)
                        {
                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, bayes_11);
                        count_bayes.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.bayesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, knearest_11);
                        count_knearest.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.knearestClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, svm_11);
                        count_svm.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.svmClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, rtrees_11);
                        count_rtrees.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.rtreesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_11);
                        count_ann.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.annClassifier->predict(features))++;
                        }
                    if(ID == 12)
                        {
                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, bayes_12);
                        count_bayes.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.bayesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, knearest_12);
                        count_knearest.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.knearestClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, svm_12);
                        count_svm.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.svmClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, rtrees_12);
                        count_rtrees.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.rtreesClassifier->predict(features))++;

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_12);
                        count_ann.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.annClassifier->predict(features))++;
                        }
                    }
                }


            //tisk do souboru
            if(ID == 9)
                {
                prinTable("Bayes", bayes_9, count_bayes, iClassifiers.iLabels, myFile);
                prinTable("K-Nearest", knearest_9, count_knearest, iClassifiers.iLabels, myFile);
                prinTable("SVM", svm_9, count_svm, iClassifiers.iLabels, myFile);
                prinTable("R-Trees", rtrees_9, count_rtrees, iClassifiers.iLabels, myFile);
                prinTable("ANN_MLP", ann_9, count_ann, iClassifiers.iLabels, myFile);
                }
            if(ID == 10)
                {
                prinTable("Bayes", bayes_10, count_bayes, iClassifiers.iLabels, myFile);
                prinTable("K-Nearest", knearest_10, count_knearest, iClassifiers.iLabels, myFile);
                prinTable("SVM", svm_10, count_svm, iClassifiers.iLabels, myFile);
                prinTable("R-Trees", rtrees_10, count_rtrees, iClassifiers.iLabels, myFile);
                prinTable("ANN_MLP", ann_10, count_ann, iClassifiers.iLabels, myFile);
                }
            if(ID == 11)
                {
                prinTable("Bayes", bayes_11, count_bayes, iClassifiers.iLabels, myFile);
                prinTable("K-Nearest", knearest_11, count_knearest, iClassifiers.iLabels, myFile);
                prinTable("SVM", svm_11, count_svm, iClassifiers.iLabels, myFile);
                prinTable("R-Trees", rtrees_11, count_rtrees, iClassifiers.iLabels, myFile);
                prinTable("ANN_MLP", ann_11, count_ann, iClassifiers.iLabels, myFile);
                }
            if(ID == 12)
                {
                prinTable("Bayes", bayes_12, count_bayes, iClassifiers.iLabels, myFile);
                prinTable("K-Nearest", knearest_12, count_knearest, iClassifiers.iLabels, myFile);
                prinTable("SVM", svm_12, count_svm, iClassifiers.iLabels, myFile);
                prinTable("R-Trees", rtrees_12, count_rtrees, iClassifiers.iLabels, myFile);
                prinTable("ANN_MLP", ann_12, count_ann, iClassifiers.iLabels, myFile);
                }
            myFile << "\n";

            count_bayes.clear();
            count_knearest.clear();
            count_svm.clear();
            count_rtrees.clear();
            count_ann.clear();
            }



        catch(std::exception& e)
            {
            myFile.close();
            }
        myFile.close();
        }


        void prinTable(std::string name, int version, std::vector<std::vector<int>>& count, std::vector<std::string> labels, std::ofstream& myFile)
            {
            myFile << name;
            myFile << ";";
            myFile << version;
            myFile << "\n";

            myFile << "";
            myFile << ";";
            for(size_t i = 0; i < labels.size(); i++)
                {
                myFile << labels.at(i);
                myFile << ";";
                }
            myFile << "\n";

            for(size_t i = 0; i < labels.size(); i++)
                {
                myFile << labels.at(i);
                myFile << ";";
                for(size_t j = 0; j < labels.size(); j++)
                    {
                    myFile << std::to_string(count.at(j).at(i));
                    myFile << ";";
                    }
                myFile << "\n";
                }

            myFile << "uspesnost";
            myFile << ";";
            int sum_all = 0;
            for(size_t i = 0; i < labels.size(); i++)
                {
                int sum = 0;
                for(size_t j = 0; j < labels.size(); j++)
                    {
                    sum += count.at(i).at(j);
                    }
                sum_all += sum;
                myFile << std::to_string((float)count.at(i).at(i)/(float)sum);
                myFile << ";";
                }
            myFile << "\n";

            myFile << "celk. usp.";
            myFile << ";";
            int sum = 0;
            for(size_t j = 0; j < labels.size(); j++)
                {
                sum += count.at(j).at(j);
                }
            myFile << std::to_string((float) sum / (float)sum_all);
            myFile << ";";
            myFile << "\n";
            }

        void getTable1(std::string iFilename, const std::vector<Dataset::TrainingSample>& iTraining, std::vector<Dataset::TestingSample>& iTesting, const short ID)
            {
            std::vector<std::vector<int>> count1_kn, count2_kn, count3_kn, count4_kn, count5_kn, count6_kn, count7_kn, count8_kn;
            std::vector<std::vector<int>> count1_svm, count2_svm, count3_svm, count4_svm, count5_svm, count6_svm;
            std::vector<std::vector<int>> count1_nusvc, count2_nusvc, count3_nusvc, count4_nusvc, count5_nusvc, count6_nusvc;
            std::vector<std::vector<int>> count1_ann, count2_ann, count3_ann, count4_ann, count5_ann, count6_ann, count7_ann, count8_ann, count9_ann, count10_ann, count11_ann, count12_ann, count13_ann, count14_ann, count15_ann;
            std::vector<std::vector<int>> count1_rt, count2_rt, count3_rt, count4_rt, count5_rt;
            std::ofstream myFile(iFilename);

            std::vector<float> features;

            cv::Mat labels;
            std::vector<std::string> names;
            for(size_t i = 0; i < iTraining.size(); i++)
                if(General::getIndex(iTraining.at(i).iLabel, names) < 0)
                    names.push_back(iTraining.at(i).iLabel);

            int ann_version = 0, knearest_version = 0, svm_version = 0, rtrees_version = 0, label_size = 0;

            if(ID == 9)
                {
                ann_version = ann_9;
                knearest_version = knearest_9;
                svm_version = svm_9;
                rtrees_version = rtrees_9;
                label_size = 7;
                }

            if(ID == 10)
                {
                ann_version = ann_10;
                knearest_version = knearest_10;
                svm_version = svm_10;
                rtrees_version = rtrees_10;
                label_size = 6;
                }
            if(ID == 11)
                {
                ann_version = ann_11;
                knearest_version = knearest_11;
                svm_version = svm_11;
                rtrees_version = rtrees_11;
                label_size = 4;
                }
            if(ID == 12)
                {
                ann_version = ann_12;
                knearest_version = knearest_12;
                svm_version = svm_12;
                rtrees_version = rtrees_12;
                label_size = 9;
                }

            try
                {
                for(size_t i = 0; i < label_size; i++)
                    {
                    count1_kn.push_back({ 0, });
                    count2_kn.push_back({ 0, });
                    count3_kn.push_back({ 0, });
                    count4_kn.push_back({ 0, });
                    count5_kn.push_back({ 0, });
                    count6_kn.push_back({ 0, });
                    count7_kn.push_back({ 0, });
                    count8_kn.push_back({ 0, });

                    count1_svm.push_back({ 0, });
                    count2_svm.push_back({ 0, });
                    count3_svm.push_back({ 0, });
                    count4_svm.push_back({ 0, });
                    count5_svm.push_back({ 0, });
                    count6_svm.push_back({ 0, });

                    count1_nusvc.push_back({ 0, });
                    count2_nusvc.push_back({ 0, });
                    count3_nusvc.push_back({ 0, });
                    count4_nusvc.push_back({ 0, });
                    count5_nusvc.push_back({ 0, });
                    count6_nusvc.push_back({ 0, });

                    count1_rt.push_back({ 0, });
                    count2_rt.push_back({ 0, });
                    count3_rt.push_back({ 0, });
                    count4_rt.push_back({ 0, });
                    count5_rt.push_back({ 0, });

                    count1_ann.push_back({ 0, });
                    count2_ann.push_back({ 0, });
                    count3_ann.push_back({ 0, });
                    count4_ann.push_back({ 0, });
                    count5_ann.push_back({ 0, });
                    count6_ann.push_back({ 0, });
                    count7_ann.push_back({ 0, });
                    count8_ann.push_back({ 0, });
                    count9_ann.push_back({ 0, });
                    count10_ann.push_back({ 0, });
                    count11_ann.push_back({ 0, });
                    count12_ann.push_back({ 0, });
                    count13_ann.push_back({ 0, });
                    count14_ann.push_back({ 0, });
                    count15_ann.push_back({ 0, });

                    for(size_t j = 0; j < label_size - 1; j++)
                        {
                        count1_kn.at(i).push_back(0);
                        count2_kn.at(i).push_back(0);
                        count3_kn.at(i).push_back(0);
                        count4_kn.at(i).push_back(0);
                        count5_kn.at(i).push_back(0);
                        count6_kn.at(i).push_back(0);
                        count7_kn.at(i).push_back(0);
                        count8_kn.at(i).push_back(0);

                        count1_svm.at(i).push_back(0);
                        count2_svm.at(i).push_back(0);
                        count3_svm.at(i).push_back(0);
                        count4_svm.at(i).push_back(0);
                        count5_svm.at(i).push_back(0);
                        count6_svm.at(i).push_back(0);

                        count1_nusvc.at(i).push_back(0);
                        count2_nusvc.at(i).push_back(0);
                        count3_nusvc.at(i).push_back(0);
                        count4_nusvc.at(i).push_back(0);
                        count5_nusvc.at(i).push_back(0);
                        count6_nusvc.at(i).push_back(0);

                        count1_rt.at(i).push_back(0);
                        count2_rt.at(i).push_back(0);
                        count3_rt.at(i).push_back(0);
                        count4_rt.at(i).push_back(0);
                        count5_rt.at(i).push_back(0);

                        count1_ann.at(i).push_back(0);
                        count2_ann.at(i).push_back(0);
                        count3_ann.at(i).push_back(0);
                        count4_ann.at(i).push_back(0);
                        count5_ann.at(i).push_back(0);
                        count6_ann.at(i).push_back(0);
                        count7_ann.at(i).push_back(0);
                        count8_ann.at(i).push_back(0);
                        count9_ann.at(i).push_back(0);
                        count10_ann.at(i).push_back(0);
                        count11_ann.at(i).push_back(0);
                        count12_ann.at(i).push_back(0);
                        count13_ann.at(i).push_back(0);
                        count14_ann.at(i).push_back(0);
                        count15_ann.at(i).push_back(0);
                        }
                    }

                labels = createLabelMatrix(iTraining, names);
                cv::Mat samples = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, knearest_version), true);
                for(int t = 1; t < iTraining.size(); t++)
                    hconcat(samples, cv::Mat(createFeatureVector(iTraining.at(t).iFeatureValues, iTraining.at(t).iFeatureNames, knearest_version), true), samples);
                samples.convertTo(samples, CV_32F);

                std::vector<int> labels1;
                for(int l = 0; l < iTraining.size(); l++)
                    labels1.push_back(std::stoi(iTraining.at(l).iLabel));

                // KNEAREST
                cv::Ptr<cv::ml::KNearest> model1_kn = cv::ml::KNearest::create();
                model1_kn->setIsClassifier(true);
                model1_kn->setAlgorithmType(1);
                model1_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model2_kn = cv::ml::KNearest::create();
                model2_kn->setIsClassifier(true);
                model2_kn->setDefaultK(2);
                model2_kn->setAlgorithmType(1);
                model2_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model3_kn = cv::ml::KNearest::create();
                model3_kn->setIsClassifier(true);
                model3_kn->setDefaultK(5);
                model3_kn->setAlgorithmType(1);
                model3_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model4_kn = cv::ml::KNearest::create();
                model4_kn->setIsClassifier(true);
                model4_kn->setDefaultK(10);
                model4_kn->setAlgorithmType(1);
                model4_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model5_kn = cv::ml::KNearest::create();
                model5_kn->setIsClassifier(true);
                model5_kn->setAlgorithmType(1);
                model5_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model6_kn = cv::ml::KNearest::create();
                model6_kn->setIsClassifier(true);
                model6_kn->setDefaultK(2);
                model6_kn->setAlgorithmType(0);
                model6_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model7_kn = cv::ml::KNearest::create();
                model7_kn->setIsClassifier(true);
                model7_kn->setDefaultK(5);
                model7_kn->setAlgorithmType(0);
                model7_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::KNearest> model8_kn = cv::ml::KNearest::create();
                model8_kn->setIsClassifier(true);
                model8_kn->setDefaultK(10);
                model8_kn->setAlgorithmType(0);
                model8_kn->train(samples, cv::ml::COL_SAMPLE, labels1);

                for(int t = 0; t < iTesting.size(); t++)
                    {
                    if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                        {
                        std::string temp = iTesting.at(t).iSamplePath;
                        size_t last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(last_slash_idx);
                                last_slash_idx = temp.find_last_of("\\/");
                                if(std::string::npos != last_slash_idx)
                                    {
                                    temp.erase(0, last_slash_idx + 1);
                                    last_slash_idx = temp.find_first_of("_");
                                    if(std::string::npos != last_slash_idx)
                                        temp.erase(last_slash_idx);
                                    }
                                }
                            }
                        // trenovaci mnozina
                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, knearest_version);

                        count1_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model1_kn->predict(features)), names))++;
                        count2_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model2_kn->predict(features)), names))++;
                        count3_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model3_kn->predict(features)), names))++;
                        count4_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model4_kn->predict(features)), names))++;
                        count5_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model5_kn->predict(features)), names))++;
                        count6_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model6_kn->predict(features)), names))++;
                        count7_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model7_kn->predict(features)), names))++;
                        count8_kn.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model8_kn->predict(features)), names))++;

                        }
                    }

                //SVM

                labels = createLabelMatrix(iTraining, names);
                samples = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, svm_version), true);
                for(int t = 1; t < iTraining.size(); t++)
                    hconcat(samples, cv::Mat(createFeatureVector(iTraining.at(t).iFeatureValues, iTraining.at(t).iFeatureNames, svm_version), true), samples);
                samples.convertTo(samples, CV_32F);

                // SVM csvc
                labels1.clear();
                for(int l = 0; l < iTraining.size(); l++)
                    labels1.push_back(std::stoi(iTraining.at(l).iLabel));
                cv::Ptr<cv::ml::TrainData> tdata = cv::ml::TrainData::create(samples, cv::ml::COL_SAMPLE, labels1);
                cv::Ptr<cv::ml::SVM> model1_svm = cv::ml::SVM::create();
                model1_svm->setType(cv::ml::SVM::C_SVC);
                model1_svm->setKernel(cv::ml::SVM::LINEAR);
                if(ID == 10)
                    model1_svm->train(tdata);
                else
                    model1_svm->trainAuto(tdata, 10);

                //cv::Ptr<cv::ml::SVM> model2_svm = cv::ml::SVM::create();
                //model2_svm->setType(cv::ml::SVM::C_SVC);
                //model2_svm->setKernel(cv::ml::SVM::POLY);
                //model2_svm->trainAuto(tdata);

                cv::Ptr<cv::ml::SVM> model3_svm = cv::ml::SVM::create();
                model3_svm->setType(cv::ml::SVM::C_SVC);
                model3_svm->setKernel(cv::ml::SVM::RBF);
                if(ID == 10)
                    model3_svm->train(tdata);
                else
                    model3_svm->trainAuto(tdata, 10);

                //cv::Ptr<cv::ml::SVM> model4_svm = cv::ml::SVM::create();
                //model4_svm->setType(cv::ml::SVM::C_SVC);
                //model4_svm->setKernel(cv::ml::SVM::SIGMOID);
                //model4_svm->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model5_svm = cv::ml::SVM::create();
                model5_svm->setType(cv::ml::SVM::C_SVC);
                model5_svm->setKernel(cv::ml::SVM::CHI2);
                if(ID == 10)
                    model5_svm->train(tdata);
                else
                    model5_svm->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model6_svm = cv::ml::SVM::create();
                model6_svm->setType(cv::ml::SVM::C_SVC);
                model6_svm->setKernel(cv::ml::SVM::INTER);
                if(ID == 10)
                    model6_svm->train(tdata);
                else
                    model6_svm->trainAuto(tdata, 10);

                /*//svm nu-svc
                cv::Ptr<cv::ml::SVM> model1_nusvc = cv::ml::SVM::create();
                model1_nusvc->setType(cv::ml::SVM::NU_SVC);
                //model1_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model1_nusvc->trainAuto(tdata, 10, cv::ml::SVM::getDefaultGrid(0), cv::ml::SVM::getDefaultGrid(1), cv::ml::SVM::getDefaultGrid(2), cv::ml::SVM::getDefaultGrid(cv::ml::SVM::NU), cv::ml::SVM::getDefaultGrid(4), cv::ml::SVM::getDefaultGrid(5));

                cv::Ptr<cv::ml::SVM> model2_nusvc = cv::ml::SVM::create();
                model2_nusvc->setType(cv::ml::SVM::NU_SVC);
                model2_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model2_nusvc->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model3_nusvc = cv::ml::SVM::create();
                model3_nusvc->setType(cv::ml::SVM::NU_SVC);
                model3_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model3_nusvc->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model4_nusvc = cv::ml::SVM::create();
                model4_nusvc->setType(cv::ml::SVM::NU_SVC);
                model4_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model4_nusvc->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model5_nusvc = cv::ml::SVM::create();
                model5_nusvc->setType(cv::ml::SVM::NU_SVC);
                model5_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model5_nusvc->trainAuto(tdata, 10);

                cv::Ptr<cv::ml::SVM> model6_nusvc = cv::ml::SVM::create();
                model6_nusvc->setType(cv::ml::SVM::NU_SVC);
                model6_nusvc->setKernel(cv::ml::SVM::LINEAR);
                model6_nusvc->trainAuto(tdata, 10);*/


                for(int t = 0; t < iTesting.size(); t++)
                    {
                    if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                        {
                        std::string temp = iTesting.at(t).iSamplePath;
                        size_t last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(last_slash_idx);
                                last_slash_idx = temp.find_last_of("\\/");
                                if(std::string::npos != last_slash_idx)
                                    {
                                    temp.erase(0, last_slash_idx + 1);
                                    last_slash_idx = temp.find_first_of("_");
                                    if(std::string::npos != last_slash_idx)
                                        temp.erase(last_slash_idx);
                                    }
                                }
                            }

                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, svm_version);
                        count1_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model1_svm->predict(features)), names))++;
                        //count2_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model2_svm->predict(features)), names))++;
                        count3_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model3_svm->predict(features)), names))++;
                        //count4_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model4_svm->predict(features)), names))++;
                        count5_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model5_svm->predict(features)), names))++;
                        count6_svm.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model6_svm->predict(features)), names))++;

                        //float k = model4_svm->predict(features);

                        /*count1_nusvc.at(General::getIndex(temp, names)).at((int) model1_nusvc->predict(features))++;
                        count2_nusvc.at(General::getIndex(temp, names)).at((int) model2_nusvc->predict(features))++;
                        count3_nusvc.at(General::getIndex(temp, names)).at((int) model3_nusvc->predict(features))++;
                        count4_nusvc.at(General::getIndex(temp, names)).at((int) model4_nusvc->predict(features))++;
                        count5_nusvc.at(General::getIndex(temp, names)).at((int) model5_nusvc->predict(features))++;
                        count6_nusvc.at(General::getIndex(temp, names)).at((int) model6_nusvc->predict(features))++;*/

                        }
                    }


                //RTREES
                labels1.clear();
                for(int l = 0; l < iTraining.size(); l++)
                    labels1.push_back(std::stoi(iTraining.at(l).iLabel));

                labels = createLabelMatrix(iTraining, names);
                samples = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, rtrees_version), true);
                for(int t = 1; t < iTraining.size(); t++)
                    hconcat(samples, cv::Mat(createFeatureVector(iTraining.at(t).iFeatureValues, iTraining.at(t).iFeatureNames, rtrees_version), true), samples);
                samples.convertTo(samples, CV_32F);

                cv::Ptr<cv::ml::RTrees> model1_rt = cv::ml::RTrees::create();
                model1_rt->setActiveVarCount(0);
                model1_rt->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::RTrees> model2_rt = cv::ml::RTrees::create();
                model2_rt->setActiveVarCount(2);
                model2_rt->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::RTrees> model3_rt = cv::ml::RTrees::create();
                model3_rt->setActiveVarCount(12);
                model3_rt->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::RTrees> model4_rt = cv::ml::RTrees::create();
                model4_rt->setActiveVarCount(10);
                model4_rt->train(samples, cv::ml::COL_SAMPLE, labels1);

                cv::Ptr<cv::ml::RTrees> model5_rt = cv::ml::RTrees::create();
                model5_rt->setActiveVarCount(8);
                model5_rt->train(samples, cv::ml::COL_SAMPLE, labels1);

                for(int t = 0; t < iTesting.size(); t++)
                    {
                    if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                        {
                        std::string temp = iTesting.at(t).iSamplePath;
                        size_t last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(last_slash_idx);
                                last_slash_idx = temp.find_last_of("\\/");
                                if(std::string::npos != last_slash_idx)
                                    {
                                    temp.erase(0, last_slash_idx + 1);
                                    last_slash_idx = temp.find_first_of("_");
                                    if(std::string::npos != last_slash_idx)
                                        temp.erase(last_slash_idx);
                                    }
                                }
                            }


                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, rtrees_version);
                        count1_rt.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model1_rt->predict(features)), names))++;
                        count2_rt.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model2_rt->predict(features)), names))++;
                        count3_rt.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model3_rt->predict(features)), names))++;
                        count4_rt.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model4_rt->predict(features)), names))++;
                        count5_rt.at(General::getIndex(temp, names)).at(General::getIndex(std::to_string((int) model5_rt->predict(features)), names))++;


                        }
                    }
                // ANN_MLP 

                labels = createLabelMatrix(iTraining, names);
                samples = cv::Mat::Mat(createFeatureVector(iTraining.at(0).iFeatureValues, iTraining.at(0).iFeatureNames, ann_version), true);
                for(int t = 1; t < iTraining.size(); t++)
                    hconcat(samples, cv::Mat(createFeatureVector(iTraining.at(t).iFeatureValues, iTraining.at(t).iFeatureNames, ann_version), true), samples);
                samples.convertTo(samples, CV_32F);


                cv::Mat layer_sizes(1, 5, CV_32SC1);
                layer_sizes.at<int>(0) = (int) samples.rows;
                layer_sizes.at<int>(1) = 15;
                layer_sizes.at<int>(2) = 15;
                layer_sizes.at<int>(3) = 15;
                layer_sizes.at<int>(4) = (int) names.size();

                //cv::Ptr<cv::ml::ANN_MLP> model1_ann = cv::ml::ANN_MLP::create();
                //model1_ann->setLayerSizes(layer_sizes);
                //model1_ann->setActivationFunction(cv::ml::ANN_MLP::IDENTITY);
                //model1_ann->setTrainMethod(cv::ml::ANN_MLP::BACKPROP);
                //model1_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model2_ann = cv::ml::ANN_MLP::create();
                model2_ann->setLayerSizes(layer_sizes);
                model2_ann->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM);
                model2_ann->setTrainMethod(cv::ml::ANN_MLP::BACKPROP, 0.001);
                model2_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model3_ann = cv::ml::ANN_MLP::create();
                model3_ann->setLayerSizes(layer_sizes);
                model3_ann->setActivationFunction(cv::ml::ANN_MLP::GAUSSIAN);
                model3_ann->setTrainMethod(cv::ml::ANN_MLP::BACKPROP);
                model3_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model4_ann = cv::ml::ANN_MLP::create();
                model4_ann->setLayerSizes(layer_sizes);
                model4_ann->setActivationFunction(cv::ml::ANN_MLP::RELU);
                model4_ann->setTrainMethod(cv::ml::ANN_MLP::BACKPROP);
                model4_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model5_ann = cv::ml::ANN_MLP::create();
                model5_ann->setLayerSizes(layer_sizes);
                model5_ann->setActivationFunction(cv::ml::ANN_MLP::LEAKYRELU);
                model5_ann->setTrainMethod(cv::ml::ANN_MLP::BACKPROP);
                model5_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model6_ann = cv::ml::ANN_MLP::create();
                model6_ann->setLayerSizes(layer_sizes);
                model6_ann->setActivationFunction(cv::ml::ANN_MLP::IDENTITY);
                model6_ann->setTrainMethod(cv::ml::ANN_MLP::RPROP);
                model6_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model7_ann = cv::ml::ANN_MLP::create();
                model7_ann->setLayerSizes(layer_sizes);
                model7_ann->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM);
                model7_ann->setTrainMethod(cv::ml::ANN_MLP::RPROP);
                model7_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model8_ann = cv::ml::ANN_MLP::create();
                model8_ann->setLayerSizes(layer_sizes);
                model8_ann->setActivationFunction(cv::ml::ANN_MLP::GAUSSIAN);
                model8_ann->setTrainMethod(cv::ml::ANN_MLP::RPROP);
                model8_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model9_ann = cv::ml::ANN_MLP::create();
                model9_ann->setLayerSizes(layer_sizes);
                model9_ann->setActivationFunction(cv::ml::ANN_MLP::RELU);
                model9_ann->setTrainMethod(cv::ml::ANN_MLP::RPROP);
                model9_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model10_ann = cv::ml::ANN_MLP::create();
                model10_ann->setLayerSizes(layer_sizes);
                model10_ann->setActivationFunction(cv::ml::ANN_MLP::LEAKYRELU);
                model10_ann->setTrainMethod(cv::ml::ANN_MLP::RPROP);
                model10_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                /*cv::Ptr<cv::ml::ANN_MLP> model11_ann = cv::ml::ANN_MLP::create();
                model11_ann->setLayerSizes(layer_sizes);
                model11_ann->setActivationFunction(cv::ml::ANN_MLP::IDENTITY);
                model11_ann->setTrainMethod(cv::ml::ANN_MLP::ANNEAL);
                model11_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model12_ann = cv::ml::ANN_MLP::create();
                model12_ann->setLayerSizes(layer_sizes);
                model12_ann->setActivationFunction(cv::ml::ANN_MLP::SIGMOID_SYM);
                model12_ann->setTrainMethod(cv::ml::ANN_MLP::ANNEAL);
                model12_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model13_ann = cv::ml::ANN_MLP::create();
                model13_ann->setLayerSizes(layer_sizes);
                model13_ann->setActivationFunction(cv::ml::ANN_MLP::GAUSSIAN);
                model13_ann->setTrainMethod(cv::ml::ANN_MLP::ANNEAL);
                model13_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model14_ann = cv::ml::ANN_MLP::create();
                model14_ann->setLayerSizes(layer_sizes);
                model14_ann->setActivationFunction(cv::ml::ANN_MLP::RELU);
                model14_ann->setTrainMethod(cv::ml::ANN_MLP::ANNEAL);
                model14_ann->train(samples, cv::ml::COL_SAMPLE, labels);

                cv::Ptr<cv::ml::ANN_MLP> model15_ann = cv::ml::ANN_MLP::create();
                model15_ann->setLayerSizes(layer_sizes);
                model15_ann->setActivationFunction(cv::ml::ANN_MLP::LEAKYRELU);
                model15_ann->setTrainMethod(cv::ml::ANN_MLP::ANNEAL);
                model15_ann->train(samples, cv::ml::COL_SAMPLE, labels);*/

                for(int t = 0; t < iTesting.size(); t++)
                    {
                    if(General::getID(iTesting.at(t).iPredictions.annLabels.at(0)) == ID)
                        {
                        std::string temp = iTesting.at(t).iSamplePath;
                        size_t last_slash_idx = temp.find_last_of("\\/");
                        if(std::string::npos != last_slash_idx)
                            {
                            temp.erase(last_slash_idx);
                            last_slash_idx = temp.find_last_of("\\/");
                            if(std::string::npos != last_slash_idx)
                                {
                                temp.erase(last_slash_idx);
                                last_slash_idx = temp.find_last_of("\\/");
                                if(std::string::npos != last_slash_idx)
                                    {
                                    temp.erase(0, last_slash_idx + 1);
                                    last_slash_idx = temp.find_first_of("_");
                                    if(std::string::npos != last_slash_idx)
                                        temp.erase(last_slash_idx);
                                    }
                                }
                            }


                        features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_version);
                        //count1_ann.at(General::getIndex(temp, names)).at((int) model1_ann->predict(features))++;
                        count2_ann.at(General::getIndex(temp, names)).at((int) model2_ann->predict(features))++;
                        count3_ann.at(General::getIndex(temp, names)).at((int) model3_ann->predict(features))++;
                        count4_ann.at(General::getIndex(temp, names)).at((int) model4_ann->predict(features))++;
                        count5_ann.at(General::getIndex(temp, names)).at((int) model5_ann->predict(features))++;
                        count6_ann.at(General::getIndex(temp, names)).at((int) model6_ann->predict(features))++;
                        count7_ann.at(General::getIndex(temp, names)).at((int) model7_ann->predict(features))++;
                        count8_ann.at(General::getIndex(temp, names)).at((int) model8_ann->predict(features))++;
                        count9_ann.at(General::getIndex(temp, names)).at((int) model9_ann->predict(features))++;
                        count10_ann.at(General::getIndex(temp, names)).at((int) model10_ann->predict(features))++;
                        /*count11_ann.at(General::getIndex(temp, names)).at((int) model11_ann->predict(features))++;
                        count12_ann.at(General::getIndex(temp, names)).at((int) model12_ann->predict(features))++;
                        count13_ann.at(General::getIndex(temp, names)).at((int) model13_ann->predict(features))++;
                        count14_ann.at(General::getIndex(temp, names)).at((int) model14_ann->predict(features))++;
                        count15_ann.at(General::getIndex(temp, names)).at((int) model15_ann->predict(features))++;*/




                        //features = createFeatureVector(iTesting.at(t).iFeatureValues, iTesting.at(t).iFeatureNames, ann_version);
                        // count_ann.at(General::getIndex(temp, iClassifiers.iLabels)).at((int) iClassifiers.annClassifier->predict(features))++;

                        }
                    }

                //tisk do souboru
                prinTable("Model1", knearest_version, count1_kn, names, myFile);
                prinTable("Model2", knearest_version, count2_kn, names, myFile);
                prinTable("Model3", knearest_version, count3_kn, names, myFile);
                prinTable("Model4", knearest_version, count4_kn, names, myFile);
                prinTable("Model5", knearest_version, count5_kn, names, myFile);
                prinTable("Model6", knearest_version, count6_kn, names, myFile);
                prinTable("Model7", knearest_version, count7_kn, names, myFile);
                prinTable("Model8", knearest_version, count8_kn, names, myFile);

                prinTable("Model1_svm", svm_version, count1_svm, names, myFile);
                prinTable("Model2_svm", svm_version, count2_svm, names, myFile);
                prinTable("Model3_svm", svm_version, count3_svm, names, myFile);
                prinTable("Model4_svm", svm_version, count4_svm, names, myFile);
                prinTable("Model5_svm", svm_version, count5_svm, names, myFile);
                prinTable("Model6_svm", svm_version, count6_svm, names, myFile);

                /*prinTable("Model1_nusvc", svm_version, count1_nusvc, names, myFile);
                prinTable("Model2_nusvc", svm_version, count2_nusvc, names, myFile);
                prinTable("Model3_nusvc", svm_version, count3_nusvc, names, myFile);
                prinTable("Model4_nusvc", svm_version, count4_nusvc, names, myFile);
                prinTable("Model5_nusvc", svm_version, count5_nusvc, names, myFile);
                prinTable("Model6_nusvc", svm_version, count6_nusvc, names, myFile);*/

                prinTable("Model1_rt", rtrees_version, count1_rt, names, myFile);
                prinTable("Model2_rt", rtrees_version, count2_rt, names, myFile);
                prinTable("Model3_rt", rtrees_version, count3_rt, names, myFile);
                prinTable("Model4_rt", rtrees_version, count4_rt, names, myFile);
                prinTable("Model5_rt", rtrees_version, count5_rt, names, myFile);

                //prinTable("Model1_ann", ann_version, count1_ann, names, myFile);
                prinTable("Model2_ann", ann_version, count2_ann, names, myFile);
                prinTable("Model3_ann", ann_version, count3_ann, names, myFile);
                prinTable("Model4_ann", ann_version, count4_ann, names, myFile);
                prinTable("Model5_ann", ann_version, count5_ann, names, myFile);
                prinTable("Model6_ann", ann_version, count6_ann, names, myFile);
                prinTable("Model7_ann", ann_version, count7_ann, names, myFile);
                prinTable("Model8_ann", ann_version, count8_ann, names, myFile);
                prinTable("Model9_ann", ann_version, count9_ann, names, myFile);
                prinTable("Model10_ann", ann_version, count10_ann, names, myFile);
                /*prinTable("Model11_ann", ann_version, count1_ann, names, myFile);
                prinTable("Model12_ann", ann_version, count1_ann, names, myFile);
                prinTable("Model13_ann", ann_version, count1_ann, names, myFile);
                prinTable("Model14_ann", ann_version, count1_ann, names, myFile);
                prinTable("Model15_ann", ann_version, count1_ann, names, myFile);*/



                myFile << "\n";
                }



            catch(std::exception& e)
                {
                myFile.close();
                }
            myFile.close();
            }

    }

