Browse Source

Add of sobel based transformation

Jérôme BUISINE 7 months ago
parent
commit
37a4860edd
2 changed files with 92 additions and 10 deletions
  1. 32 9
      classes/Transformation.py
  2. 60 1
      utils/data.py

+ 32 - 9
classes/Transformation.py

@@ -7,9 +7,13 @@ from ipfml.processing import transform
 from ipfml.processing import reconstruction
 from ipfml.filters import convolution, kernels
 from ipfml import utils
+import cv2
 
 from PIL import Image
 
+# modules imports
+from ..utils import data as functions
+
 
 # Transformation class to store transformation method of image and get usefull information
 class Transformation():
@@ -54,19 +58,33 @@ class Transformation():
 
             data = np.array(img_array)
 
-        if self.transformation == 'min_diff_filter':
-            w_size, h_size, stride = list(map(int, self.param.split(',')))
+        if self.transformation == 'sobel_based_filter':
+            k_size, p_limit = list(map(int, self.param.split(',')))
             h, w = list(map(int, self.size.split(',')))
 
-            # bilateral with window of size (`w_size`, `h_size`)
             lab_img = transform.get_LAB_L(img)
-    
-            img_filter = convolution.convolution2D(lab_img, kernels.min_bilateral_diff, (w_size, h_size), stride)
-            diff_array = np.array(img_filter*255, 'uint8')
-            diff_img = Image.fromarray(diff_array)
-            diff_img.thumbnail((h, w))
+
+            weight, height = lab_img.shape
+
+            sobelx = cv2.Sobel(lab_img, cv2.CV_64F, 1, 0, ksize=k_size)
+            sobely = cv2.Sobel(lab_img, cv2.CV_64F, 0, 1,ksize=k_size)
+
+            sobel_mag = np.array(np.hypot(sobelx, sobely), 'uint8')  # magnitude
+            sobel_mag_limit = functions.remove_pixel(sobel_mag, p_limit)
+
+            # use distribution value of pixel to fill `0` values
+            sobel_mag_limit_without_0 = [x for x in sobel_mag_limit.reshape((weight*height)) if x != 0]  
+            distribution = functions.distribution_from_data(sobel_mag_limit_without_0)
+            min_value = int(min(sobel_mag_limit_without_0))
+            l = lambda: functions.get_random_value(distribution) + min_value
+            img_reconstructed = functions.fill_image_with_rand_value(sobel_mag_limit, l, 0)
+            
+            img_reconstructed_norm = utils.normalize_2D_arr(img_reconstructed)
+            img_reconstructed_norm = np.array(img_reconstructed_norm*255, 'uint8')
+            sobel_reconstructed = Image.fromarray(img_reconstructed_norm)
+            sobel_reconstructed.thumbnail((h, w))
         
-            data = np.array(diff_img)
+            data = np.array(sobel_reconstructed)
             
         if self.transformation == 'static':
             # static content, we keep input as it is
@@ -98,6 +116,11 @@ class Transformation():
             w, h = list(map(int, self.size.split(',')))
             path = os.path.join(path, 'W_' + str(w_size)) + '_' + str(h_size) + '_Stride_' + str(stride) + '_S_' + str(w) + '_' + str(h)
 
+        if self.transformation == 'sobel_based_filter':
+            k_size, p_limit = list(map(int, self.param.split(',')))
+            h, w = list(map(int, self.size.split(',')))
+            path = os.path.join(path, 'K_' + str(k_size)) + '_L' + str(p_limit) + '_S_' + str(w) + '_' + str(h)
+
         if self.transformation == 'static':
             # param contains image name to find for each scene
             path = self.param

+ 60 - 1
utils/data.py

@@ -1,7 +1,12 @@
+# main imports
 import os
+import numpy as np
+import random
 
+# image processing imports
 from PIL import Image
 
+# modules imports
 from ..config.cnn_config import *
 
 
@@ -79,4 +84,58 @@ def augmented_data_image(block, output_folder, prefix_image_name):
             output_reconstructed_path = os.path.join(output_folder, output_reconstructed_filename)
 
             if not os.path.exists(output_reconstructed_path):
-                rotated_output_img.save(output_reconstructed_path)
+                rotated_output_img.save(output_reconstructed_path)
+
+
+def remove_pixel(img, limit):
+    
+    width, height = img.shape
+    
+    output = np.zeros((width, height))
+    
+    for i in range(width):
+        for j in range(height):
+            
+            if img[i,j] <= limit:
+                output[i,j] = img[i,j]
+                
+    return output
+
+
+def get_random_value(distribution):
+    rand = random.uniform(0, 1)
+    prob_sum = 0.
+    
+    for id, prob in enumerate(distribution):
+        
+        prob_sum += prob
+        
+        if prob_sum >= rand:
+            return id
+        
+    return len(distribution) - 1
+
+
+def distribution_from_data(data):
+    
+    occurences = np.array([data.count(x) for x in set(data)])
+    max_occurences = sum(occurences)
+    
+    return occurences / max_occurences
+
+
+def fill_image_with_rand_value(img, func, value_to_replace):
+    
+    width, height = img.shape
+    
+    output = np.zeros((width, height))
+    
+    for i in range(width):
+        for j in range(height):
+            
+            if img[i,j] == value_to_replace:
+                output[i, j] = func()
+            else:
+                output[i, j] = img[i, j]
+                
+    return output