예제 #1
0
    def augment_test_data(self, cherryPick=False):
        """ Deprecated Menu: Augments the test data."""

        iteration = -1
        equalizeAfter2ndIterationSize = -1  # no equalization
        if cherryPick:
            newName = ""
            iteration = utils.radio_question("[?]", "Pick iteration", None,
                                             [1, 2, 3], [1, 2, 3])
        else:
            newName = utils.value_question(
                "[?]", "Provide new name for data set", "s",
                "Do not use the same name as your current data set.", False)
            if utils.radio_question("[?]", "Equalize after second iteration?",
                                    None, ["Yes", "No"], [True, False]):
                equalizeAfter2ndIterationSize = utils.value_question(
                    "[?]", "Provide desired size (w * h)", "i",
                    "250000 for 500x500 images")

        normDefaultData = utils.radio_question("[?]", "Use default dataset?",
                                               None, ["Yes", "No"],
                                               [True, False])
        datasetPath = ""
        if normDefaultData:
            datasetPath = Settings.G_TEST_DATA_PATH
        else:
            datasetPath = utils.value_question("[?]",
                                               "Provide path to test data",
                                               "s")

        data = TestData(datasetPath, 1)
        data.augment_test_data(newName, iteration,
                               equalizeAfter2ndIterationSize)
예제 #2
0
    def show_loading_screen(self):
        """ 
        Loads a model by letting the user choose from a loading screen.

        Returns: 
        model
        """

        modelUuids, modelParams = self.get_model_options()
        if not modelUuids:
            print "No models available :("
            raw_input("Press any key to continue")
            return None
        else:
            modelParams.insert(0, "Load manually")
            modelUuids.insert(0, "manual")
            modelUuid = utils.radio_question("[Load Model]", "Model Loader",
                                             None, modelParams, modelUuids)
            model = None

            if modelUuid == "manual":
                path = utils.value_question(
                    "[...]", "Provide the path to the model directory", "s")
                if not utils.check_if_dir_exists(path):
                    raise Exception("Could not find path {0}.".format(path))
                try:
                    model = self.load_model(None, path)
                    return model
                except Exception, e:
                    logging.exception(
                        "Could not load model with Path {0}.".format(path))
                    raw_input("Press any key to continue")
                    return None

            try:
                model = self.load_model(modelUuid)
                print "Model {0} was loaded successfully.".format(
                    model.modelSaver.modelUuid)
                return model

            except Exception, e:
                logging.exception(
                    "Could not load model with Uuid {0}. Restart application and try again."
                    .format(modelUuid))
                delete = utils.radio_question("[?]", "Delete model?", None,
                                              ["Yes", "No"], [True, False])
                if delete:
                    remove_model(modelUuid)
                raw_input("Press any key to continue")
                return None
예제 #3
0
    def normalize_test_data(self, size, newName="", forceOverwrite=False):
        normTestDataRootPath = utils.get_parent_dir(self.get_root_path()) + "/"
        if newName == "":
            if not forceOverwrite:
                overwrite = utils.radio_question("[?]", "Do you really wish to overwrite existing images?", None, ["Yes", "No"], [True, False])
            else:
                overwrite = True
            if not overwrite:
                normTestDataRootPath += utils.value_question("", "Provide new foldername:", "s")
            else:
                normTestDataRootPath = self.get_root_path()
        else:
            normTestDataRootPath += newName

        utils.create_dir_if_necessary(normTestDataRootPath)
        print "Saving equalized test data set in path",normTestDataRootPath

        # segment data with only one segment
        self.segment_test_data({"all": 1})
        self.new_segmentation()

        numberOfImages = self.testDataSize
        numberOfImagesDone = 0
        
        currentClass = ""

        print "Starting equalization.\n"
        for img, class_, fileName in self.load_data("all", grayscale=False, outputActions=False, yieldFilename=True):

            path = normTestDataRootPath + "/" + class_ + "/" 
            # reset counter if new class
            if not currentClass == class_:
                currentClass = class_                
                utils.create_dir_if_necessary(path)
                                
            resizedImg = utils.equalize_image_size(img, size)
            path += fileName
            cv.imwrite(path, resizedImg)
            numberOfImagesDone += 1
            utils.show_progress(True, numberOfImagesDone, numberOfImages, "Processing class {0}.\tTotal progress:", currentClass)
        print "\nEqualization finished."
        print "\n"
예제 #4
0
    def crop_bounding_boxes(self):
        """Menu for cropping the bounding boxes of datasets (Works with Food-100)."""

        boundingBoxFilename = utils.value_question(
            "[?]", "Provide bounding box file name", "s",
            "Do not forget the file extension.", True)

        normDefaultData = utils.radio_question("[?]", "Use default dataset?",
                                               None, ["Yes", "No"],
                                               [True, False])
        datasetPath = ""
        if normDefaultData:
            datasetPath = Settings.G_TEST_DATA_PATH
        else:
            datasetPath = utils.value_question("[?]",
                                               "Provide path to test data",
                                               "s")

        data = TestData(datasetPath, 1)
        data.crop_bounding_boxes(boundingBoxFilename)
예제 #5
0
    def rename_prefix(self):
        """Menu for renaming images in a dataset so that datasets can be merged / combined without overwriting files by merging."""

        prefix = utils.value_question("[?]", "Provide prefix", "s",
                                      "Please do not use underscores (_).",
                                      True)

        normDefaultData = utils.radio_question("[?]", "Use default dataset?",
                                               None, ["Yes", "No"],
                                               [True, False])
        datasetPath = ""
        if normDefaultData:
            datasetPath = Settings.G_TEST_DATA_PATH
        else:
            datasetPath = utils.value_question("[?]",
                                               "Provide path to test data",
                                               "s")

        data = TestData(datasetPath, 1)
        data.add_prefix_to_test_data(prefix)
예제 #6
0
    def crop_test_data_to_square(self):
        """ Deprecated Menu: Crops all images in a dataset to squares."""

        rejectedName = utils.value_question(
            "[?]",
            "Provide folder name for images that get rejected due to bad aspect ratio",
            "s", "Do not use the same name as your current data set.", False)

        normDefaultData = utils.radio_question("[?]", "Use default dataset?",
                                               None, ["Yes", "No"],
                                               [True, False])
        datasetPath = ""
        if normDefaultData:
            datasetPath = Settings.G_TEST_DATA_PATH
        else:
            datasetPath = utils.value_question("[?]",
                                               "Provide path to test data",
                                               "s")

        data = TestData(datasetPath, 1)
        data.crop_test_data_to_square(rejectedName)
예제 #7
0
    def normalize_testdata(self):
        """ Deprecated Menu: Resizes every image in a physical dataset to be the same."""

        size = utils.value_question("[?]", "Provide desired size (w * h)", "i",
                                    "250000 for 500x500 images")
        newName = utils.value_question(
            "[?]", "Provide new name", "s",
            "Leave blank if you want to overwrite images", True)

        normDefaultData = utils.radio_question("[?]", "Use default dataset?",
                                               None, ["Yes", "No"],
                                               [True, False])
        datasetPath = ""
        if normDefaultData:
            datasetPath = Settings.G_TEST_DATA_PATH
        else:
            datasetPath = utils.value_question("[?]",
                                               "Provide path to test data",
                                               "s")

        data = TestData(datasetPath, 1)
        data.normalize_test_data(size, newName)
예제 #8
0
    def show_setting_Mail(self):
        Settings.G_MAIL_FROM = utils.value_setting("Mail to send from", "s")
        Settings.G_MAIL_TO = utils.value_setting("Mail to send to", "s")
        Settings.G_MAIL_SERVER = utils.value_setting("SMTP Server URL", "s")
        Settings.G_MAIL_USER = utils.value_setting("Username", "s")
        Settings.G_MAIL_PASSWD = utils.value_setting(
            "Password", "s", "Stored password won't be encryped!", False, True)
        self.save_settings()

        if utils.radio_question(
                "[?]", "Send test mail to " + Settings.G_MAIL_TO + "?", None,
            ["Yes", "No"], [True, False]):
            #from misc.MailService import MailService
            ms = MailServer.MailService()
            try:
                #ms.send_email("Setup complete", "Setup complete", [utils.get_data_path() + "mailTest.png"])
                Settings.G_AUTOMATIC_REPORT_MAILING = utils.radio_setting(
                    "Send automatic mail after the training of a classifier is complete? ",
                    Settings.G_AUTOMATIC_REPORT_MAILING, ["Yes", "No"],
                    [True, False])
                self.save_settings()
            except Exception, e:
                logging.exception("Could not send mail.")
예제 #9
0
    def initialize(self):
        """ Method to load the classifiers and test them."""

        loader = ModelLoader()

        input = None
        testDataPath = None
        while True:
            input = utils.menue(
                "Majority Vote classifier",
                ["add classifier", "save", "test + finish", "finish"], False,
                True)
            if input == 2:
                self.modelSaver(self, -1)
                continue

            if input > 2:
                break

            # Display loading menu
            model = loader.show_loading_screen()
            if not model is None:
                if testDataPath is None:
                    testDataPath = model.testData.get_root_path()
                    self.modelSaver.datasetPath = testDataPath
                else:
                    # check if the test datasets are the same
                    if testDataPath != model.testData.get_root_path():
                        print "Could not load classifier {0} because the classifier was trained on different test data.".format(
                            model.name)
                        continue
                self.classifiers.append(
                    (1, model)
                )  # Tuple[0] = model weight (1 is default weight) | Tuple[1] = model

        # why did we leave the loop?
        if input == 5:
            print "Cancel"
            return False  # cancel -> back to start
        else:
            # initialize test data for the majority classifier

            # check if test data path has changed
            if not utils.check_if_dir_exists(testDataPath):
                testDataPath = utils.value_question(
                    "[...]", "Root path to new Dataset Path", "s")
            self.testData = TestData(testDataPath, 1, False)
            self.testData.segment_test_data({"test": 1})
            self.testData.new_segmentation()

            self.tester = ModelTester(self)

            # test classifier if input == 3
            if input == 3:
                # Be careful: the results might not reflect the actual accuracy of the classifier.
                # if not changed the tester will test on the whole test data set. This might include images that the
                # classifiers has been trained on. For a real accuracy test the images have to be separated manually.
                results = self.tester.test_classifier(["test"])
                self.tester.save_results(results, exportToCSV=False)
                print self.tester.format_results_string(results)
                testLoss = results["test"][1]
                save = utils.radio_question("[?]", "Save/Update classifier?",
                                            None, ["Yes", "No"], [True, False])
                if save:
                    self.modelSaver(self, testLoss)

            return self.classifiers != [
            ]  # finish. Return True if classifiers where loaded, False if not.
예제 #10
0
    def load_model(self, modelUuid, manualPath=None):
        """ 
        Load model from either model dictionary or manually.
        
        Keyword arguments:
        modelUuid -- uuid of the model. If None the method will try to load the model using the manualPath.
        manualPath -- if model shall be loaded manually this is the root path of the model directory

        Returns:
        model
        """

        # manual mode. Load model that is not part of the model dictionary.
        if modelUuid is None:
            classifier = None
            try:
                with open(manualPath + "model", "rb") as f:
                    classifier = pickle.load(f)
            except:
                logging.exception("Could not load model manually")
                return None
            return classifier

        else:
            # Load model from model dictionary
            modelParams = self.get_model_param(modelUuid)
            modelSavePath = modelParams[4]
            modelTypeId = modelParams[0]
            testdata = TestData(modelParams[3], 1, True)

        if not self.does_model_exist(modelUuid):
            raise AttributeError(
                "Model with uuid {0} was not found in model dictionary.".
                format(modelUuid))

        if modelTypeId == "SIFT":
            from classification.local_features.sift import SIFTClassifier
            from classification.model import ModelType
            model = SIFTClassifier(testdata, Settings.E_MODEL_TYPE)
            model = model.load(modelSavePath)

        elif modelTypeId == "SURF":
            from classification.local_features.surf import SURFClassifier
            from classification.model import ModelType
            model = SURFClassifier(testdata, Settings.E_MODEL_TYPE)
            return model.load(modelSavePath)
        elif modelTypeId == "HIST":
            from classification.global_features.histogram import HistogramClassifier
            from classification.model import ModelType
            model = HistogramClassifier(testdata, Settings.E_MODEL_TYPE)
            return model.load(modelSavePath)

        if modelTypeId.startswith("mCL"):
            from classification.late_fusion import MajorityClassifier
            model = MajorityClassifier(testdata)
            try:
                with open(modelSavePath + "model", "r") as f:
                    model = pickle.load(f)
            except:
                logging.exception("Could not load majority classifier.")
                return None
            return model

        # NNs or CNNs
        if modelTypeId.startswith("NN") or modelTypeId.startswith("CNN"):
            from classification.deep.neural_net import *
            # load testdata because we need the output shape
            modelWrapper = NeuralNetClassifier(testdata, modelParams[3])

            # search for best weights
            if not utils.check_if_file_exists(modelSavePath + "model"):
                print "[!] Model file {0} was not found.".format(
                    modelSavePath + "model")

                continue_ = utils.radio_question(
                    "[?]",
                    "It might be possible to restore the model using the weights file. Continue?",
                    None, ["Yes", "No"], [True, False])
                if not continue_:
                    delete = utils.radio_question("[?]", "Delete model?", None,
                                                  ["Yes", "No"], [True, False])
                    if delete:
                        remove_model(modelUuid)
                    raise Exception("Model file does not exist.")

            # try to restore best weights if more recent
            bestWeights = None
            if modelParams[7] == "nn_weights" and utils.check_if_file_exists(
                    modelSavePath + "best_weights"):
                bestWeights = modelSavePath + "best_weights"

            modelWrapper.load_model(modelSavePath + "model", bestWeights)
            # restore params
            modelWrapper.modelSaver.bestLoss = modelParams[5]
            modelWrapper.modelSaver.modelDescription = modelParams[2]
            modelWrapper.modelSaver.modelUuid = modelUuid
            return modelWrapper
        if modelTypeId is None or modelTypeId == "None":
            print "There was a problem loading this model {0}. The save file might be corrupted. Model Dictionary {1}".format(
                modelTypeId, modelParams)
            if utils.radio_question("[?]",
                                    "Repair model with new model type ID?",
                                    None, ["Yes", "No"], [True, False]):
                modelTypeId = utils.value_question("[?]", "Model ID", "s")
                update_model_dict(modelUuid, 0, modelTypeId)
                print "Model Id changed. Restart application and try again."
                raw_input("Press any key to continue.")
                import sys
                sys.exit()
            raise Exception("Could not repair model.")

        else:
            raise Exception(
                "Model {0} is not supported yet.".format(modelTypeId))