Browse Source

Kernels and convolution sub package added

Jérôme BUISINE 1 year ago
parent
commit
a76d66a818
37 changed files with 309 additions and 64 deletions
  1. BIN
      docs/build/doctrees/environment.pickle
  2. 1 1
      docs/build/html/.buildinfo
  3. 2 2
      docs/build/html/_modules/index.html
  4. 2 2
      docs/build/html/_modules/ipfml/exceptions.html
  5. 2 2
      docs/build/html/_modules/ipfml/filters/noise.html
  6. 2 2
      docs/build/html/_modules/ipfml/iqa/fr.html
  7. 2 2
      docs/build/html/_modules/ipfml/metrics.html
  8. 2 2
      docs/build/html/_modules/ipfml/processing/compression.html
  9. 2 2
      docs/build/html/_modules/ipfml/processing/movement.html
  10. 2 2
      docs/build/html/_modules/ipfml/processing/reconstruction.html
  11. 2 2
      docs/build/html/_modules/ipfml/processing/segmentation.html
  12. 2 2
      docs/build/html/_modules/ipfml/processing/transform.html
  13. 2 2
      docs/build/html/_modules/ipfml/utils.html
  14. 1 1
      docs/build/html/_static/documentation_options.js
  15. 2 2
      docs/build/html/contributing.html
  16. 2 2
      docs/build/html/description.html
  17. 2 2
      docs/build/html/examples.html
  18. 2 2
      docs/build/html/genindex.html
  19. 2 2
      docs/build/html/index.html
  20. 2 2
      docs/build/html/ipfml.html
  21. 2 2
      docs/build/html/ipfml/ipfml.exceptions.html
  22. 2 2
      docs/build/html/ipfml/ipfml.filters.noise.html
  23. 2 2
      docs/build/html/ipfml/ipfml.iqa.fr.html
  24. 2 2
      docs/build/html/ipfml/ipfml.metrics.html
  25. 2 2
      docs/build/html/ipfml/ipfml.processing.compression.html
  26. 2 2
      docs/build/html/ipfml/ipfml.processing.movement.html
  27. 2 2
      docs/build/html/ipfml/ipfml.processing.reconstruction.html
  28. 2 2
      docs/build/html/ipfml/ipfml.processing.segmentation.html
  29. 2 2
      docs/build/html/ipfml/ipfml.processing.transform.html
  30. 2 2
      docs/build/html/ipfml/ipfml.utils.html
  31. BIN
      docs/build/html/objects.inv
  32. 2 2
      docs/build/html/py-modindex.html
  33. 2 2
      docs/build/html/search.html
  34. 2 2
      docs/source/conf.py
  35. 65 0
      ipfml/filters/convolution.py
  36. 176 0
      ipfml/filters/kernels.py
  37. 6 2
      setup.py

BIN
docs/build/doctrees/environment.pickle


+ 1 - 1
docs/build/html/.buildinfo

@@ -1,4 +1,4 @@
 # Sphinx build info version 1
 # This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
-config: ebc7f0fe0f0f35c210a1cdf4bb8dc7ef
+config: ab7df74f90d59db7127f81213334c1ef
 tags: 645f666f9bcd5a90fca523b33c5a78b7

+ 2 - 2
docs/build/html/_modules/index.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Overview: module code &mdash; ipfml v0.4.2 documentation</title>
+  <title>Overview: module code &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/exceptions.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.exceptions &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.exceptions &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/filters/noise.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.filters.noise &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.filters.noise &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/iqa/fr.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.iqa.fr &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.iqa.fr &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/metrics.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.metrics &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.metrics &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/processing/compression.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.compression &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.compression &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/processing/movement.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.movement &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.movement &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/processing/reconstruction.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.reconstruction &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.reconstruction &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/processing/segmentation.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.segmentation &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.segmentation &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/processing/transform.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.transform &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.transform &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/_modules/ipfml/utils.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.utils &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.utils &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 1 - 1
docs/build/html/_static/documentation_options.js

@@ -1,6 +1,6 @@
 var DOCUMENTATION_OPTIONS = {
     URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
-    VERSION: 'v0.4.2',
+    VERSION: 'v0.4.3',
     LANGUAGE: 'None',
     COLLAPSE_INDEX: false,
     FILE_SUFFIX: '.html',

+ 2 - 2
docs/build/html/contributing.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Contributing &mdash; ipfml v0.4.2 documentation</title>
+  <title>Contributing &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/description.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Description &mdash; ipfml v0.4.2 documentation</title>
+  <title>Description &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/examples.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Examples &mdash; ipfml v0.4.2 documentation</title>
+  <title>Examples &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/genindex.html

@@ -9,7 +9,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Index &mdash; ipfml v0.4.2 documentation</title>
+  <title>Index &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/index.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Image Processing For Machine Learning &mdash; ipfml v0.4.2 documentation</title>
+  <title>Image Processing For Machine Learning &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Documentation &mdash; ipfml v0.4.2 documentation</title>
+  <title>Documentation &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.exceptions.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.exceptions &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.exceptions &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.filters.noise.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.filters.noise &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.filters.noise &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.iqa.fr.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.iqa.fr &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.iqa.fr &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.metrics.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.metrics &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.metrics &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.processing.compression.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.compression &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.compression &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.processing.movement.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.movement &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.movement &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.processing.reconstruction.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.reconstruction &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.reconstruction &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.processing.segmentation.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.segmentation &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.segmentation &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.processing.transform.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.processing.transform &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.processing.transform &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/ipfml/ipfml.utils.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>ipfml.utils &mdash; ipfml v0.4.2 documentation</title>
+  <title>ipfml.utils &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

BIN
docs/build/html/objects.inv


+ 2 - 2
docs/build/html/py-modindex.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Python Module Index &mdash; ipfml v0.4.2 documentation</title>
+  <title>Python Module Index &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -59,7 +59,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/build/html/search.html

@@ -8,7 +8,7 @@
   
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   
-  <title>Search &mdash; ipfml v0.4.2 documentation</title>
+  <title>Search &mdash; ipfml v0.4.3 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.4.2
+                0.4.3
               </div>
             
           

+ 2 - 2
docs/source/conf.py

@@ -24,9 +24,9 @@ copyright = '2019, Jérôme BUISINE'
 author = 'Jérôme BUISINE'
 
 # The short X.Y version
-version = '0.4.2'
+version = '0.4.3'
 # The full version, including alpha/beta/rc tags
-release = 'v0.4.2'
+release = 'v0.4.3'
 
 
 # -- General configuration ---------------------------------------------------

+ 65 - 0
ipfml/filters/convolution.py

@@ -0,0 +1,65 @@
+"""
+Convolution functions to apply on images
+"""
+
+# main imports
+import numpy as np
+
+
+def convolution2D(image, kernel, kernel_size=(5, 5)):
+    """Apply 2D convolution on image using specific kernel from `ipfml.filters.kernels`
+
+    Args:
+        image: 2D image to apply convolution on
+        kernel: specific kernel from `ipfml.filters.kernels` to use
+        kernel_size: 
+
+    Returns:
+        2D numpy array obtained from image using kernel
+
+    Example:
+
+    >>> from ipfml.filters.convolution import convolution2D
+    >>> from ipfml.filters.kernels import plane_mean
+    >>> import numpy as np
+    >>> image = np.arange(81).reshape([9, 9])
+    >>> convolved_image = convolution2D(image, plane_mean, (3, 3)) 
+    >>> convolved_image.shape
+    (7, 7)
+    """
+
+    img = np.array(image)
+
+    width, height = img.shape
+
+    kernel_width, kernel_height = kernel_size
+
+    if kernel_width % 2 == 0 or kernel_height % 2 == 0:
+        raise ValueError("Invalid kernel size, need to be of odd size")
+
+    padding_height = (kernel_width - 1) / 2
+    padding_width = (kernel_width - 1) / 2
+
+    img_diff = []
+    for i in range(width):
+
+        if i >= padding_width and i < (width - padding_width):
+
+            row_diff = []
+
+            for j in range(height):
+
+                if j >= padding_height and j < (height - padding_height):
+
+                    # pixel in the center of kernel window size, need to extract window from img
+                    window = img[int(i - padding_width):int(i + padding_width +
+                                                            1),
+                                 int(j - padding_height
+                                     ):int(j + padding_height + 1)]
+
+                    diff = kernel(window)
+                    row_diff.append(diff)
+
+            img_diff.append(row_diff)
+
+    return np.array(img_diff)

+ 176 - 0
ipfml/filters/kernels.py

@@ -0,0 +1,176 @@
+"""
+Kernel to apply on images using convolution
+"""
+
+# main imports
+import numpy as np
+
+
+def plane_mean(window):
+    """Plane mean kernel to use with convolution process on image
+
+    Args:
+        window: the window part to use from image
+
+    Returns:
+        Normalized residual error from mean plane
+
+    Example:
+
+    >>> from ipfml.filters.kernels import plane_mean
+    >>> import numpy as np
+    >>> window = np.arange(9).reshape([3, 3])
+    >>> result = plane_mean(window)
+    >>> (result < 0.0001)
+    True
+    """
+
+    window = np.array(window)
+
+    width, height = window.shape
+
+    # prepare data
+    nb_elem = width * height
+    xs = [int(i / height) for i in range(nb_elem)]
+    ys = [i % height for i in range(nb_elem)]
+    zs = np.array(window).flatten().tolist()
+
+    # get residual (error) from mean plane computed
+    tmp_A = []
+    tmp_b = []
+
+    for i in range(len(xs)):
+        tmp_A.append([xs[i], ys[i], 1])
+        tmp_b.append(zs[i])
+
+    b = np.matrix(tmp_b).T
+    A = np.matrix(tmp_A)
+
+    fit = (A.T * A).I * A.T * b
+
+    errors = b - A * fit
+    residual = np.linalg.norm(errors)
+
+    return residual
+
+
+# return difference between min and max errors
+def plane_max_error(window):
+    """Plane max error kernel to use with convolution process on image
+
+    Args:
+        window: the window part to use from image
+
+    Returns:
+        Difference between max and min error from mean plane
+
+    Example:
+
+    >>> from ipfml.filters.kernels import plane_max_error
+    >>> import numpy as np
+    >>> window = np.arange(9).reshape([3, 3])
+    >>> result = plane_max_error(window)
+    >>> (result < 0.0001)
+    True
+    """
+
+    window = np.array(window)
+
+    width, height = window.shape
+
+    # prepare data
+    nb_elem = width * height
+    xs = [int(i / height) for i in range(nb_elem)]
+    ys = [i % height for i in range(nb_elem)]
+    zs = np.array(window).flatten().tolist()
+
+    # get residual (error) from mean plane computed
+    tmp_A = []
+    tmp_b = []
+
+    for i in range(len(xs)):
+        tmp_A.append([xs[i], ys[i], 1])
+        tmp_b.append(zs[i])
+
+    b = np.matrix(tmp_b).T
+    A = np.matrix(tmp_A)
+
+    fit = (A.T * A).I * A.T * b
+
+    errors = b - A * fit
+
+    # get absolute values from errors
+    errors = abs(np.array(errors))
+
+    return (errors.max() - errors.min())
+
+
+def bilateral_diff(window, func=max):
+    """Bilaeral difference kernel to use with convolution process on image
+       Apply difference pixel to pixel and keep max on min difference before applying mean
+
+    Args:
+        window: the window part to use from image
+        func: max or min function to get difference between pixels
+
+    Returns:
+        mean of max or min difference of pixels
+
+    Example:
+
+    >>> from ipfml.filters.kernels import bilateral_diff
+    >>> import numpy as np
+    >>> window = np.arange(9).reshape([3, 3])
+    >>> result = bilateral_diff(window)
+    >>> result
+    3.0
+    """
+
+    window = np.array(window)
+
+    width, height = window.shape
+
+    total_row_diff_list = []
+    total_col_diff_list = []
+
+    for i in range(width):
+
+        row_diff_list = []
+        col_diff_list = []
+
+        for j in range(height):
+
+            diff_row = 0
+
+            if i == 0:
+                diff_row = abs(window[i][j] - window[i + 1][j])
+
+            elif i == width - 1:
+                diff_row = abs(window[i][j] - window[i - 1][j])
+
+            else:
+                diff1 = abs(window[i][j] - window[i - 1][j])
+                diff2 = abs(window[i][j] - window[i + 1][j])
+                diff_row = func(diff1, diff2)
+
+            if j == 0:
+                diff_col = abs(window[i][j] - window[i][j + 1])
+
+            elif j == height - 1:
+                diff_col = abs(window[i][j] - window[i][j - 1])
+
+            else:
+                diff1 = abs(window[i][j] - window[i][j - 1])
+                diff2 = abs(window[i][j] - window[i][j + 1])
+                diff_col = func(diff1, diff2)
+
+            row_diff_list.append(diff_row)
+            col_diff_list.append(diff_col)
+
+        total_row_diff_list.append(sum(row_diff_list) / len(row_diff_list))
+        total_col_diff_list.append(sum(col_diff_list) / len(col_diff_list))
+
+    row_diff = sum(total_row_diff_list) / len(total_row_diff_list)
+    col_diff = sum(total_col_diff_list) / len(total_col_diff_list)
+
+    return func(row_diff, col_diff)

+ 6 - 2
setup.py

@@ -13,8 +13,10 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
         # run tests using doctest
         import doctest
         
-        # noise folder
+        # filters folder
         from ipfml.filters import noise as noise_filters
+        from ipfml.filters import kernels as kernels_filters
+        from ipfml.filters import convolution as convolution_filters
         
         # iqa folder
         from ipfml.iqa import fr as fr_iqa
@@ -37,6 +39,8 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
 
         # noise folder
         doctest.testmod(noise_filters)
+        doctest.testmod(kernels_filters)
+        doctest.testmod(convolution_filters)
 
         # iqa folder
         doctest.testmod(fr_iqa)
@@ -59,7 +63,7 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
 
 setup(
     name='ipfml',
-    version='0.4.2',
+    version='0.4.3',
     description='Image Processing For Machine Learning',
     long_description=readme(),
     classifiers=[