Parcourir la source

Update of dataset generation

Jérôme BUISINE il y a 4 ans
Parent
commit
3fcd2818bf

+ 3 - 0
.gitmodules

@@ -0,0 +1,3 @@
+[submodule "modules"]
+	path = modules
+	url = https://github.com/prise-3d/Thesis-DeepLearning-modules.git

+ 45 - 1
README.md

@@ -14,11 +14,55 @@ or other information...
 Output :
 Output :
 - Reference image
 - Reference image
 
 
+## Requirements
+
+```bash
+git clone --recursive https://github.com/prise-3d/Thesis-Denoising-autoencoder.git XXXXX
+```
+
+```bash
+pip install -r requirements.txt
+```
+
 ## How to use ?
 ## How to use ?
 
 
 [Autoencoder keras documentation](https://blog.keras.io/building-autoencoders-in-keras.html)
 [Autoencoder keras documentation](https://blog.keras.io/building-autoencoders-in-keras.html)
 
 
-Detailed later...
+Generate reconstructed data from specific method of reconstruction (run only once time or clean data folder before):
+```
+python generate_reconstructed_data.py -h
+```
+
+Generate custom dataset from one reconstructed method or multiples (implemented later)
+```
+python generate_dataset.py -h
+```
+
+### Reconstruction parameter (--params)
+
+List of expected parameter by reconstruction method:
+- **svd_reconstruction:** Singular Values Decomposition
+  - Param definition: *interval data used for reconstruction (begin, end)*
+  - Example: *"100, 200"*
+- **ipca_reconstruction:** Iterative Principal Component Analysis
+  - Param definition: *number of components used for compression and batch size*
+  - Example: *"30, 35"*
+- **fast_ica_reconstruction:**  Fast Iterative Component Analysis
+  - Param definition: *number of components used for compression*
+  - Example: *"50"*
+- **static** Use static file to manage (such as z-buffer, normals card...)
+  - Param definition: *Name of image of scene need to be in {sceneName}/static/xxxx.png*
+  - Example: *"img.png"*
+
+**__Example:__**
+```bash
+python generate_dataset.py --output data/output_data_filename --metrics "svd_reconstruction, ipca_reconstruction, fast_ica_reconstruction" --renderer "maxwell" --scenes "A, D, G, H" --params "100, 200 :: 50, 10 :: 50" --nb_zones 10 --random 1 --only_noisy 1
+```
+
+Then, run the model:
+```bash
+python image_denoising --data data/my_dataset --output output_model_name
+```
 
 
 ## License
 ## License
 
 

+ 71 - 15
generate_dataset.py

@@ -13,13 +13,12 @@ import time
 import json
 import json
 
 
 from PIL import Image
 from PIL import Image
-from ipfml import processing, metrics, utils
+from ipfml.processing.segmentation import divide_in_blocks
 from skimage import color
 from skimage import color
 
 
 from modules.utils import config as cfg
 from modules.utils import config as cfg
 from modules.utils import data as dt
 from modules.utils import data as dt
 
 
-from transformation_functions import svd_reconstruction
 from modules.classes.Transformation import Transformation
 from modules.classes.Transformation import Transformation
 
 
 # getting configuration information
 # getting configuration information
@@ -95,7 +94,7 @@ def generate_data_model(_scenes_list, _filename, _transformations, _scenes, _nb_
             for i in learned_zones_indices:
             for i in learned_zones_indices:
                 f.write(str(i) + ';')
                 f.write(str(i) + ';')
 
 
-        ref_image_blocks = processing.divide_in_blocks(Image.open(ref_image_path), cfg.keras_img_size)
+        ref_image_blocks = divide_in_blocks(Image.open(ref_image_path), cfg.keras_img_size)
 
 
         for id_zone, index_folder in enumerate(zones_indices):
         for id_zone, index_folder in enumerate(zones_indices):
 
 
@@ -107,21 +106,56 @@ def generate_data_model(_scenes_list, _filename, _transformations, _scenes, _nb_
             zone_path = os.path.join(scene_path, current_zone_folder)
             zone_path = os.path.join(scene_path, current_zone_folder)
 
 
             # path of zone of reference image
             # path of zone of reference image
-            ref_image_block_path = os.path.join(zone_path, last_image_name)
+            # ref_image_block_path = os.path.join(zone_path, last_image_name)
 
 
-            if not os.path.exists(ref_image_block_path):
-                ref_image_blocks[id_zone].save(ref_image_block_path)
+            # compute augmented images for ref image
+            current_ref_zone_image = ref_image_blocks[id_zone]
+
+            ref_image_name_prefix = last_image_name.replace('.png', '')
+            dt.augmented_data_image(current_ref_zone_image, zone_path, ref_image_name_prefix)
+
+            # get list of all augmented ref images
+            ref_augmented_images = [os.path.join(zone_path, f) for f in os.listdir(zone_path) if ref_image_name_prefix in f]
 
 
             # custom path for interval of reconstruction and metric
             # custom path for interval of reconstruction and metric
             metrics_path = []
             metrics_path = []
 
 
             for transformation in _transformations:
             for transformation in _transformations:
-                metric_interval_path = os.path.join(zone_path, transformation.getTransformationPath())
-                metrics_path.append(metric_interval_path)
+                
+                # check if it's a static content and create augmented images if necessary
+                if transformation.getName() == 'static':
+                    
+                    # {sceneName}/zoneXX/static
+                    static_metric_path = os.path.join(zone_path, transformation.getName())
+
+                    # img.png
+                    image_name = transformation.getParam().split('/')[-1]
+
+                    # {sceneName}/zoneXX/static/img
+                    image_prefix_name = image_name.replace('.png', '')
+                    image_folder_path = os.path.join(static_metric_path, image_prefix_name)
+                    
+                    if not os.path.exists(image_folder_path):
+                        os.makedirs(image_folder_path)
+
+                    metrics_path.append(image_folder_path)
+
+                    # get image path to manage
+                    # {sceneName}/static/img.png
+                    transform_image_path = os.path.join(scene_path, transformation.getName(), image_name) 
+                    static_transform_image = Image.open(transform_image_path)
+
+                    static_transform_image_block = divide_in_blocks(static_transform_image, cfg.keras_img_size)[id_zone]
+
+                    # generate augmented data
+                    dt.augmented_data_image(static_transform_image_block, image_folder_path, image_prefix_name)
+
+                else:
+                    metric_interval_path = os.path.join(zone_path, transformation.getTransformationPath())
+                    metrics_path.append(metric_interval_path)
 
 
             # as labels are same for each metric
             # as labels are same for each metric
             for label in os.listdir(metrics_path[0]):
             for label in os.listdir(metrics_path[0]):
-                
 
 
                 if (label == cfg.not_noisy_folder and _only_noisy == 0) or label == cfg.noisy_folder:
                 if (label == cfg.not_noisy_folder and _only_noisy == 0) or label == cfg.noisy_folder:
                     
                     
@@ -134,22 +168,44 @@ def generate_data_model(_scenes_list, _filename, _transformations, _scenes, _nb_
                     # getting images list for each metric
                     # getting images list for each metric
                     metrics_images_list = []
                     metrics_images_list = []
                         
                         
-                    for label_path in label_metrics_path:
-                        images = sorted(os.listdir(label_path))
-                        metrics_images_list.append(images)
+                    for index_metric, label_path in enumerate(label_metrics_path):
+
+                        if _transformations[index_metric].getName() == 'static':
+                            # by default append nothing..
+                            metrics_images_list.append([])
+                        else:
+                            images = sorted(os.listdir(label_path))
+                            metrics_images_list.append(images)
 
 
                     # construct each line using all images path of each
                     # construct each line using all images path of each
                     for index_image in range(0, len(metrics_images_list[0])):
                     for index_image in range(0, len(metrics_images_list[0])):
                         
                         
                         images_path = []
                         images_path = []
 
 
+                        # get information about rotation and flip from first transformation (need to be a not static transformation)
+                        current_post_fix =  metrics_images_list[0][index_image].split(cfg.post_image_name_separator)[-1]
 
 
                         # getting images with same index and hence name for each metric (transformation)
                         # getting images with same index and hence name for each metric (transformation)
                         for index_metric in range(0, len(metrics_path)):
                         for index_metric in range(0, len(metrics_path)):
-                            img_path = metrics_images_list[index_metric][index_image]
-                            images_path.append(os.path.join(label_metrics_path[index_metric], img_path))
 
 
-                        line = ref_image_block_path + ';'
+                            # custom behavior for static transformation (need to check specific image)
+                            if _transformations[index_metric].getName() == 'static':
+                                # add static path with selecting correct data augmented image
+                                image_name = _transformations[index_metric].getParam().split('/')[-1].replace('.png', '')
+                                img_path = os.path.join(metrics_path[index_metric], image_name + cfg.post_image_name_separator + current_post_fix)
+                                images_path.append(img_path)
+                            else:
+                                img_path = metrics_images_list[index_metric][index_image]
+                                images_path.append(os.path.join(label_metrics_path[index_metric], img_path))
+
+                        # get information about rotation and flip
+                        current_post_fix = images_path[0].split(cfg.post_image_name_separator)[-1]
+
+                        # get ref block which matchs we same information about rotation and flip
+                        augmented_ref_image_block_path = next(img for img in ref_augmented_images 
+                                                              if img.split(cfg.post_image_name_separator)[-1] == current_post_fix)
+
+                        line = augmented_ref_image_block_path + ';'
 
 
                         # compute line information with all images paths
                         # compute line information with all images paths
                         for id_path, img_path in enumerate(images_path):
                         for id_path, img_path in enumerate(images_path):

+ 2 - 2
generate_reconstructed_data.py

@@ -158,8 +158,8 @@ def generate_data(transformation):
                     for rotation in rotations:
                     for rotation in rotations:
                         rotated_output_img = flip.rotate(rotation)
                         rotated_output_img = flip.rotate(rotation)
 
 
-                        output_reconstructed_filename = img_path.split('/')[-1].replace('.png', '') + '_' + zones_folder[id_block]
-                        output_reconstructed_filename = output_reconstructed_filename + '_' + img_flip_labels[id] + '_' + str(rotation) + '.png'
+                        output_reconstructed_filename = img_path.split('/')[-1].replace('.png', '') + '_' + zones_folder[id_block] + cfg.post_image_name_separator
+                        output_reconstructed_filename = output_reconstructed_filename + img_flip_labels[id] + '_' + str(rotation) + '.png'
                         output_reconstructed_path = os.path.join(label_path, output_reconstructed_filename)
                         output_reconstructed_path = os.path.join(label_path, output_reconstructed_filename)
 
 
                         rotated_output_img.save(output_reconstructed_path)
                         rotated_output_img.save(output_reconstructed_path)

+ 33 - 17
image_denoising.py

@@ -3,35 +3,41 @@ from keras.models import Model
 from keras import backend as K
 from keras import backend as K
 from keras.callbacks import TensorBoard
 from keras.callbacks import TensorBoard
 
 
+import os
+import json
 import pandas as pd
 import pandas as pd
 import numpy as np
 import numpy as np
+import argparse
+
 from sklearn.utils import shuffle
 from sklearn.utils import shuffle
+import cv2
 
 
 from modules.utils import config as cfg
 from modules.utils import config as cfg
-import cv2
 
 
-import argparse
+def generate_model(input_shape):
 
 
-def generate_model(input_shape=(3, 200, 200)):
-    print(input_shape)
     input_img = Input(shape=input_shape)  # adapt this if using `channels_first` image data format
     input_img = Input(shape=input_shape)  # adapt this if using `channels_first` image data format
 
 
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(input_img)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(input_img)
     x = MaxPooling3D((1, 2, 2), padding='same')(x)
     x = MaxPooling3D((1, 2, 2), padding='same')(x)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
+    x = MaxPooling3D((1, 2, 2), padding='same')(x)
+    x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
     encoded = MaxPooling3D((1, 2, 2), padding='same')(x)
     encoded = MaxPooling3D((1, 2, 2), padding='same')(x)
 
 
+    print(encoded)
 
 
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(encoded)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(encoded)
     x = UpSampling3D((1, 2, 2))(x)
     x = UpSampling3D((1, 2, 2))(x)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
     x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
     x = UpSampling3D((1, 2, 2))(x)
     x = UpSampling3D((1, 2, 2))(x)
-    decoded = Conv3D(1, (1, 3, 3), activation='sigmoid', padding='same')(x)
+    x = Conv3D(32, (1, 3, 3), activation='relu', padding='same')(x)
+    x = UpSampling3D((1, 2, 2))(x)
+    decoded = Conv3D(3, (1, 3, 3), activation='sigmoid', padding='same')(x)
 
 
     autoencoder = Model(input_img, decoded)
     autoencoder = Model(input_img, decoded)
 
 
-    # TODO : check if 
-    autoencoder.compile(optimizer='adadelta', loss='binary_crossentropy')
+    autoencoder.compile(optimizer='adadelta', loss='mse')
 
 
     return autoencoder
     return autoencoder
 
 
@@ -102,16 +108,12 @@ def main():
     y_dataset_train = dataset_train[0].apply(lambda x: cv2.imread(x).reshape(input_shape))
     y_dataset_train = dataset_train[0].apply(lambda x: cv2.imread(x).reshape(input_shape))
     y_dataset_test = dataset_test[0].apply(lambda x: cv2.imread(x).reshape(input_shape))
     y_dataset_test = dataset_test[0].apply(lambda x: cv2.imread(x).reshape(input_shape))
 
 
-    # format correct data
-    x_data_train = np.array([item for item in x_dataset_train.values])
-    #x_data_train = np.array(x_dataset_train.values)
-    x_data_test = np.array([item for item in x_dataset_test.values])
-    #x_data_test = np.array(x_dataset_test.values)
+    # format data correctly
+    x_data_train = np.array([item[0].reshape(input_shape) for item in x_dataset_train.values])
+    x_data_test = np.array([item[0].reshape(input_shape) for item in x_dataset_test.values])
 
 
-    y_data_train = np.array([item for item in y_dataset_train.values])
-    #y_data_train = np.array(y_dataset_train.values)
-    y_data_test = np.array([item for item in y_dataset_test.values])
-    #y_data_test = np.array(y_dataset_test.values)
+    y_data_train = np.array([item[0].reshape(input_shape) for item in y_dataset_train.values])
+    y_data_test = np.array([item[0].reshape(input_shape) for item in y_dataset_test.values])
 
 
     # load model
     # load model
     autoencoder = generate_model(input_shape)
     autoencoder = generate_model(input_shape)
@@ -124,7 +126,21 @@ def main():
                     validation_data=(x_data_test, y_data_test),
                     validation_data=(x_data_test, y_data_test),
                     callbacks=[TensorBoard(log_dir='/tmp/autoencoder', histogram_freq=0, write_graph=False)])
                     callbacks=[TensorBoard(log_dir='/tmp/autoencoder', histogram_freq=0, write_graph=False)])
 
 
-    # save model
+    ##############
+    # save model #
+    ##############
+    if not os.path.exists(cfg.saved_models_folder):
+        os.makedirs(cfg.saved_models_folder)
+
+    # save the model into HDF5 file
+    model_output_path = os.path.join(cfg.saved_models_folder, p_output + '.json')
+    json_model_content = autoencoder.to_json()
+
+    with open(model_output_path, 'w') as f:
+        print("Model saved into ", model_output_path)
+        json.dump(json_model_content, f, indent=4)
+
+    autoencoder.save_weights(model_output_path.replace('.json', '.h5'))
     
     
 if __name__ == "__main__":
 if __name__ == "__main__":
     main()
     main()

+ 1 - 0
modules

@@ -0,0 +1 @@
+Subproject commit 670ff4f4b984534d477ebee6616197427b4833f2

+ 0 - 0
modules/__init__.py


+ 0 - 53
modules/classes/Transformation.py

@@ -1,53 +0,0 @@
-import os
-
-from transformation_functions import svd_reconstruction, fast_ica_reconstruction, ipca_reconstruction
-
-# Transformation class to store transformation method of image and get usefull information
-class Transformation():
-
-    def __init__(self, _transformation, _param):
-        self.transformation = _transformation
-        self.param = _param
-
-    def getTransformedImage(self, img):
-
-        if self.transformation == 'svd_reconstruction':
-            begin, end = list(map(int, self.param.split(',')))
-            data = svd_reconstruction(img, [begin, end])
-
-        if self.transformation == 'ipca_reconstruction':
-            n_components, batch_size = list(map(int, self.param.split(',')))
-            data = ipca_reconstruction(img, n_components, batch_size)
-
-        if self.transformation == 'fast_ica_reconstruction':
-            n_components = self.param
-            data = fast_ica_reconstruction(img, n_components)
-
-        return data
-    
-    def getTransformationPath(self):
-
-        path = self.transformation
-
-        if self.transformation == 'svd_reconstruction':
-            begin, end = list(map(int, self.param.split(',')))
-            path = os.path.join(path, str(begin) + '_' + str(end))
-
-        if self.transformation == 'ipca_reconstruction':
-            n_components, batch_size = list(map(int, self.param.split(',')))
-            path = os.path.join(path, 'N' + str(n_components) + '_' + str(batch_size))
-
-        if self.transformation == 'fast_ica_reconstruction':
-            n_components = self.param
-            path = os.path.join(path, 'N' + str(n_components))
-
-        return path
-
-    def getName(self):
-        return self.transformation
-
-    def getParam(self):
-        return self.param
-
-    def __str__( self ):
-        return self.transformation + ' transformation with parameter : ' + self.param

+ 0 - 0
modules/classes/__init__.py


+ 0 - 0
modules/utils/__init__.py


+ 0 - 47
modules/utils/config.py

@@ -1,47 +0,0 @@
-import numpy as np
-
-zone_folder                     = "zone"
-output_data_folder              = 'data'
-dataset_path                    = 'dataset'
-threshold_map_folder            = 'threshold_map'
-models_information_folder       = 'models_info'
-saved_models_folder             = 'saved_models'
-min_max_custom_folder           = 'custom_norm'
-learned_zones_folder            = 'learned_zones'
-correlation_indices_folder      = 'corr_indices'
-
-csv_model_comparisons_filename  = "models_comparisons.csv"
-seuil_expe_filename             = 'seuilExpe'
-min_max_filename_extension      = "_min_max_values"
-config_filename                 = "config"
-
-noisy_folder                    = 'noisy'
-not_noisy_folder                = 'notNoisy'
-
-models_names_list               = ["svm_model","ensemble_model","ensemble_model_v2","deep_keras"]
-
-# define all scenes values
-renderer_choices                = ['all', 'maxwell', 'igloo', 'cycle']
-
-scenes_names                    = ['Appart1opt02', 'Bureau1', 'Cendrier', 'Cuisine01', 'EchecsBas', 'PNDVuePlongeante', 'SdbCentre', 'SdbDroite', 'Selles']
-scenes_indices                  = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I']
-
-maxwell_scenes_names            = ['Appart1opt02', 'Cuisine01', 'SdbCentre', 'SdbDroite']
-maxwell_scenes_indices          = ['A', 'D', 'G', 'H']
-
-igloo_scenes_names              = ['Bureau1', 'PNDVuePlongeante']
-igloo_scenes_indices            = ['B', 'F']
-
-cycle_scenes_names              = ['EchecBas', 'Selles']
-cycle_scenes_indices            = ['E', 'I']
-
-normalization_choices           = ['svd', 'svdn', 'svdne']
-zones_indices                   = np.arange(16)
-
-metric_choices_labels           = ['all', 'svd_reconstruction', 'fast_ica_reconstruction', 'ipca_reconstruction']
-
-keras_epochs                    = 30
-keras_batch                     = 32
-val_dataset_size                = 0.2
-
-keras_img_size                  = (200, 200)

+ 0 - 44
modules/utils/data.py

@@ -1,44 +0,0 @@
-from ipfml import processing, metrics, utils
-from modules.utils.config import *
-from transformation_functions import svd_reconstruction
-
-from PIL import Image
-from skimage import color
-from sklearn.decomposition import FastICA
-from sklearn.decomposition import IncrementalPCA
-from sklearn.decomposition import TruncatedSVD
-from numpy.linalg import svd as lin_svd
-
-from scipy.signal import medfilt2d, wiener, cwt
-import pywt
-
-import numpy as np
-
-
-_scenes_names_prefix   = '_scenes_names'
-_scenes_indices_prefix = '_scenes_indices'
-
-# store all variables from current module context
-context_vars = vars()
-
-
-def get_renderer_scenes_indices(renderer_name):
-
-    if renderer_name not in renderer_choices:
-        raise ValueError("Unknown renderer name")
-
-    if renderer_name == 'all':
-        return scenes_indices
-    else:
-        return context_vars[renderer_name + _scenes_indices_prefix]
-
-def get_renderer_scenes_names(renderer_name):
-
-    if renderer_name not in renderer_choices:
-        raise ValueError("Unknown renderer name")
-
-    if renderer_name == 'all':
-        return scenes_names
-    else:
-        return context_vars[renderer_name + _scenes_names_prefix]
-

+ 8 - 0
requirements.txt

@@ -0,0 +1,8 @@
+Pillow
+keras
+tensorflow
+sklearn
+matplotlib
+path.py
+ipfml
+cv2