Пример #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 __instantiate_model_by_id(self, name=None, description=None):
        """ 
        Instantiates a model using self.__modelId of the type ClassifierType
        
        Keyword arguments:
        name -- Name of the model. Default: Ask
        description -- Description of the model. Default: Ask 
        """
        if name is None:
            name = utils.value_question("[?]", "Provide a name for the model", "s")
        if description is None:
            description = utils.value_question("[?]", "Provide a description for the model", "s", "(optional)", True)
            
        # Ini testdata
        if self.__modelId != ClassifierType.VOTE.value:
            testdata = TestData(Settings.G_TEST_DATA_PATH, Settings.H_CROSS_VALIDATION_K, True)

        # Ini potential bow
        
            
        if self.__modelId == ClassifierType.SIFT.value:                  
            m = SIFTClassifier(testdata, Settings.E_MODEL_TYPE, name, description)
            bow = utils.value_question("[?]", "Provide a precomputed bow", "s", "(optional)", True)
            if bow != "":
                m.restore_bow(bow)
            return m

        elif self.__modelId == ClassifierType.HIST.value:
            return HistogramClassifier(testdata, Settings.H_MODEL_TYPE, name, description)

        elif self.__modelId == ClassifierType.SURF.value:
            m = SURFClassifier(testdata, Settings.E_MODEL_TYPE, name, description)
            bow = utils.value_question("[?]", "Provide a precomputed bow", "s", "(optional)", True)
            if bow != "":
                m.restore_bow(bow)
            return m

        elif self.__modelId == ClassifierType.ORB.value:
            return ORBClassifier(testdata, Settings.E_MODEL_TYPE, name, description)

        elif self.__modelId == ClassifierType.DAISY.value:
            return DaisyClassifier(testdata, Settings.E_MODEL_TYPE, name, description)

        elif self.__modelId == ClassifierType.CENSURE.value:
            from classification.local_features.censure import CENSUREClassifier
            return CENSUREClassifier(testdata, Settings.E_MODEL_TYPE, name, description)

        elif self.__modelId == ClassifierType.LF.value:
            return MultiStepClassifier(testdata, ModelType.OpenCV, name, description)

        elif self.__modelId == ClassifierType.LBP.value:
            return LBPClassifier(testdata, Settings.L_MODEL_TYPE, name, description)

        elif self.__modelId == ClassifierType.NN.value:
            return NeuralNetClassifier(testdata, name, description=description)

        elif self.__modelId == ClassifierType.VOTE.value:
            return MajorityClassifier(name, description)
        elif self.__modelId == ClassifierType.RANDOM.value:
            return RandomKeypointSampler(testdata, Settings.E_MODEL_TYPE, name, description)
Пример #3
0
 def predict_image_folder(self):
     """ Menu for predicting images in a given folder."""
     if MODEL_CONTROLLER.has_tester:
         tester = ModelTester(MODEL_CONTROLLER.model)
     else:
         tester = MODEL_CONTROLLER.tester
     path = utils.value_question("[...]", "Path to image folder", "s")
     tester.classify_image_folder(path)
Пример #4
0
    def test_parameters(self):
        """ Main function to test one or more parameters of a classifier."""

        classifier = MODEL_CONTROLLER.show_model_screen()
        if classifier == -1:
            return
        name = utils.value_question("[?]", "Provide a name for the test run",
                                    "s")
        description = utils.value_question(
            "[?]", "Provide a description for the test run", "s", "(optional)",
            True)

        # TODO: get parameter id
        ts = Testsuite(iterations=-1, random=False)
        ts.add_parameter(4, "Number of keypoints", range(32, 1182, 32))
        tester = ParameterTester(name, description, classifier, ts)
        tester.start_testing()
Пример #5
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)
Пример #6
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)
Пример #7
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)
Пример #8
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)
Пример #9
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
Пример #10
0
    def learn_custom_marker(self):
        """ "Learns a custom rectangular marker object by calculating SIFT keypoints."""

        markerImage = load_image(utils.get_path_via_file_ui(), 0, 1)
        # save image 
        cv.imwrite(utils.get_data_path() + "segmentationMarkerImage.jpg", markerImage)
        sift = cv.SIFT()
        self.CUSTOM_MARKER = sift.detectAndCompute(markerImage, None) # contains keypoints and descriptors
        self.MARKER_SIZE = (utils.value_question("[Marker Size]", "What is the marker width in cm?", "f"), utils.value_question("[Marker Size]", "What is the marker height in cm?", "f"))

        # save marker (not saving keypoints as they are not pickable)
        markerFile = {"marker": self.CUSTOM_MARKER[1], "markerDimension": self.MARKER_SIZE}
        with open(utils.get_data_path() + "segmentationMarker", "wb") as f:
            pickle.dump(markerFile, f)

        raw_input("Learning complete. Press any key to continue")
Пример #11
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"
Пример #12
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.
Пример #13
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))