Parcourir la source

Merge branch 'feature/NoiseImprovment' into develop

Jérôme BUISINE il y a 5 ans
Parent
commit
93befeca9a

+ 3 - 2
README.md

@@ -1,8 +1,9 @@
 Image Processing For Machine Learning
 =====================================
 
-![ipfml_logo](ipfml_logo.png)
-
+<p align="center">
+    <img src="ipfml_logo.png" width="40%">
+</p>
 
 Installation
 ------------

+ 4 - 6
README.rst

@@ -1,15 +1,13 @@
 Image Processing For Machine Learning
 =====================================
 
-.. image:: ipfml_logo.png
-
 This is a package developed during a thesis project.
 
 Installation
 ------------
 
 .. code:: bash
-   
+
    pip install ifpml
 
 How to use ?
@@ -18,7 +16,7 @@ How to use ?
 To use, simply do :
 
 .. code:: python
-   
+
    from PIL import Image
    from ipfml import processing
    img = Image.open('path/to/image.png')
@@ -39,6 +37,6 @@ All these modules will be enhanced during development of the package.
 Documentation
 -------------
 
-For more information about package, documentation_ is available. 
+For more information about package, documentation_ is available.
 
-.. _documentation: https://jbuisine.github.io/IPFML/  
+.. _documentation: https://jbuisine.github.io/IPFML/

BIN
docs/build/doctrees/contributing.doctree


BIN
docs/build/doctrees/description.doctree


BIN
docs/build/doctrees/environment.pickle


BIN
docs/build/doctrees/index.doctree


BIN
docs/build/doctrees/ipfml.doctree


+ 3 - 0
docs/build/html/_sources/contributing.rst.txt

@@ -2,6 +2,9 @@ Contributing
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
+
 
 
 Using GitHub

+ 4 - 3
docs/build/html/_sources/description.rst.txt

@@ -2,7 +2,8 @@ Description
 =====================================
 
 .. image:: _static/ipfml_logo.png
-
+   :width: 400 px
+   :align: center
 
 Installation
 ------------
@@ -22,6 +23,6 @@ To use, simply do :
 .. code:: python
     
    from PIL import Image
-   from ipfml import image_processing
+   from ipfml import processing
    img = Image.open('path/to/image.png')
-   s = image_processing.get_LAB_L_SVD_s(img)
+   s = processing.get_LAB_L_SVD_s(img)

+ 2 - 0
docs/build/html/_sources/index.rst.txt

@@ -7,6 +7,8 @@ Image Processing For Machine Learning
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
 
 What's IPFML ?
 =================

+ 1 - 0
docs/build/html/_sources/ipfml.rst.txt

@@ -21,6 +21,7 @@ ipfml.filters
 
 ipfml.filters.noise
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
 .. automodule:: ipfml.filters.noise
     :members:
     :show-inheritance:

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

@@ -156,7 +156,7 @@
             
   <div class="section" id="contributing">
 <h1>Contributing<a class="headerlink" href="#contributing" title="Permalink to this headline">¶</a></h1>
-<img alt="_images/ipfml_logo.png" src="_images/ipfml_logo.png" />
+<a class="reference internal image-reference" href="_images/ipfml_logo.png"><img alt="_images/ipfml_logo.png" class="align-center" src="_images/ipfml_logo.png" style="width: 400px;" /></a>
 <div class="section" id="using-github">
 <h2>Using GitHub<a class="headerlink" href="#using-github" title="Permalink to this headline">¶</a></h2>
 <p>This git project uses <a class="reference external" href="https://danielkummer.github.io/git-flow-cheatsheet/">git-flow</a> implementation. You are free to contribute to it.</p>

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

@@ -158,7 +158,7 @@
             
   <div class="section" id="description">
 <h1>Description<a class="headerlink" href="#description" title="Permalink to this headline">¶</a></h1>
-<img alt="_images/ipfml_logo.png" src="_images/ipfml_logo.png" />
+<a class="reference internal image-reference" href="_images/ipfml_logo.png"><img alt="_images/ipfml_logo.png" class="align-center" src="_images/ipfml_logo.png" style="width: 400px;" /></a>
 <div class="section" id="installation">
 <h2>Installation<a class="headerlink" href="#installation" title="Permalink to this headline">¶</a></h2>
 <p>Just install package using pip</p>
@@ -170,9 +170,9 @@
 <h2>How to use ?<a class="headerlink" href="#how-to-use" title="Permalink to this headline">¶</a></h2>
 <p>To use, simply do :</p>
 <div class="code python highlight-default notranslate"><div class="highlight"><pre><span></span><span class="kn">from</span> <span class="nn">PIL</span> <span class="k">import</span> <span class="n">Image</span>
-<span class="kn">from</span> <span class="nn">ipfml</span> <span class="k">import</span> <span class="n">image_processing</span>
+<span class="kn">from</span> <span class="nn">ipfml</span> <span class="k">import</span> <span class="n">processing</span>
 <span class="n">img</span> <span class="o">=</span> <span class="n">Image</span><span class="o">.</span><span class="n">open</span><span class="p">(</span><span class="s1">&#39;path/to/image.png&#39;</span><span class="p">)</span>
-<span class="n">s</span> <span class="o">=</span> <span class="n">image_processing</span><span class="o">.</span><span class="n">get_LAB_L_SVD_s</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
+<span class="n">s</span> <span class="o">=</span> <span class="n">processing</span><span class="o">.</span><span class="n">get_LAB_L_SVD_s</span><span class="p">(</span><span class="n">img</span><span class="p">)</span>
 </pre></div>
 </div>
 </div>

+ 9 - 0
docs/build/html/genindex.html

@@ -161,6 +161,7 @@
  | <a href="#M"><strong>M</strong></a>
  | <a href="#N"><strong>N</strong></a>
  | <a href="#R"><strong>R</strong></a>
+ | <a href="#S"><strong>S</strong></a>
  | <a href="#W"><strong>W</strong></a>
  
 </div>
@@ -292,6 +293,14 @@
   </ul></td>
 </tr></table>
 
+<h2 id="S">S</h2>
+<table style="width: 100%" class="indextable genindextable"><tr>
+  <td style="width: 33%; vertical-align: top;"><ul>
+      <li><a href="ipfml.html#ipfml.filters.noise.salt_pepper_noise">salt_pepper_noise() (in module ipfml.filters.noise)</a>
+</li>
+  </ul></td>
+</tr></table>
+
 <h2 id="W">W</h2>
 <table style="width: 100%" class="indextable genindextable"><tr>
   <td style="width: 33%; vertical-align: top;"><ul>

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

@@ -153,7 +153,7 @@
             
   <div class="section" id="image-processing-for-machine-learning">
 <h1>Image Processing For Machine Learning<a class="headerlink" href="#image-processing-for-machine-learning" title="Permalink to this headline">¶</a></h1>
-<img alt="_images/ipfml_logo.png" src="_images/ipfml_logo.png" />
+<a class="reference internal image-reference" href="_images/ipfml_logo.png"><img alt="_images/ipfml_logo.png" class="align-center" src="_images/ipfml_logo.png" style="width: 400px;" /></a>
 </div>
 <div class="section" id="what-s-ipfml">
 <h1>What’s IPFML ?<a class="headerlink" href="#what-s-ipfml" title="Permalink to this headline">¶</a></h1>

Fichier diff supprimé car celui-ci est trop grand
+ 33 - 0
docs/build/html/ipfml.html


+ 3 - 3
docs/build/html/objects.inv

@@ -2,6 +2,6 @@
 # Project: IPFML
 # Version: 0.2.0
 # The remainder of this file is compressed using zlib.
-xÚ¥”MOã0†ïù–Øk#ºGn,]¤•Š„„¨€‹å8Sg´þˆl‡~ý&qC‚–ŠØ½%ã÷y=¶gë½’ù¥ërmЩÛ+eÊF¹$8¬W^É‹[ý «ÿ§rÎ^µôÃbßhîÑh²ž›œ¢kœC¦SyÉjÉ8$ãFt¨UL¦:¨ÆÓC…>9…HX�·ÈÝâÇ:êsžn¯El1"t›±¨ˆ…v›„>¦@»ÈÅBOÏ/	}J�žS èô
-ôŽ¢±œ4‡4Ö²–zC•ãz	W[áBZ,nª	ÉK|Å(jZHÃÿº¸§[ZʧØe5}’Þ�EÇž:Œ\|úsC™µÉø™,= ¯¨eZ@¤�E_cá
-ú*=‡+=ÍCXhÏ´ø¾U¸Ñ]w�ïÛÄùòª4œ¬ÖdÔäfÉJpÜb=xΨY8@›)�ÁSµ7ÆXPÿ>þe4êÞ©dÈ^<FƒøOÿ™M²£ã\¡X÷þ÷Ó¸5–Ü1^¡²fu”áB>9|ÜÙÞ(О
èÆÅYÕíj\Ð]˜4!?×mëÏDˆñCX¿ï2ÍþØwa
+xÚ¥”MkÜ0†ïþ‚öº¦é1·4ÛBa�Ð%ÉEÈò¬<T_Hr7ί¯m­c‡f©¥½Ù£÷y5’fíAÉò€2€ó¥6è�ØîZ™º•@¾×› ä§Û|&›ÿ¥JÎZÞtôÍâÐjÐhrµ49GÖz�Lçò’YÉ8dãFô¨SLæ:¨6Ðcƒ!;Ïd ¬—k‘¸¿‚à�ûÕï}Ò—ÝÝ|KØbBè.b9P•
+=ì·ý•ís Ÿ
+=>=g ô1zÊ�’Ó«0xŠJ¤rÒóXÇ:Užë5œu†C?Ç´XÝT3RÖøk ¨i%
ÿíÓvœ{lm)Ÿc×ÕôYz�zê8µñè×-eÎeã²ôˆ¡¡Ži‰6NTC�Å+ªô~ªô<á »Ðâÿ­Â�jÃÐ&>Ô×µádsE–ñQMn‘¢ÏÚÑsA-ÂÚÎ�^˜²ü˜bQýýôWШkx¥’U ñ�âŸÃg1ËNŽK…býûßÏcà‡qäŽñ5�0§‡£ŒòÎáí†ÈÖðV�l<@?.>ÈÊv›i!BwqÒÄü|¿
oÞ1Åqý¾Ï´ø¹Ô�é

Fichier diff supprimé car celui-ci est trop grand
+ 1 - 1
docs/build/html/searchindex.js


+ 3 - 0
docs/source/contributing.rst

@@ -2,6 +2,9 @@ Contributing
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
+
 
 
 Using GitHub

+ 2 - 1
docs/source/description.rst

@@ -2,7 +2,8 @@ Description
 =====================================
 
 .. image:: _static/ipfml_logo.png
-
+   :width: 400 px
+   :align: center
 
 Installation
 ------------

+ 2 - 0
docs/source/index.rst

@@ -7,6 +7,8 @@ Image Processing For Machine Learning
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
 
 What's IPFML ?
 =================

+ 113 - 69
ipfml/filters/noise.py

@@ -1,24 +1,17 @@
 import numpy as np
+import random
+
 from ipfml import processing
 
 
-def _global_noise_filter(image,
-                         n,
-                         generator,
-                         updator,
-                         identical=False,
-                         distribution_interval=(-0.5, 0.5),
-                         k=0.2):
+def _global_noise_filter(image, generator, updator, identical=False):
     """White noise filter to apply on image
 
     Args:
         image: image used as input (2D or 3D image representation)
-        n: used to set importance of noise [1, 999]
         generator: lambda function used to generate random numpy array with specific distribution
         updator: lambda function used to update pixel value
         identical: keep or not identical noise distribution for each canal if RGB Image (default False)
-        distribution_interval: tuple which set the distribution interval of uniform distribution (default (-0.5, 0.5))
-        k: variable that specifies the amount of noise to be taken into account in the output image (default 0.2)
 
     Returns:
         2D Numpy array with specified noise applied
@@ -28,9 +21,11 @@ def _global_noise_filter(image,
     >>> from ipfml.filters.noise import _global_noise_filter as gf
     >>> import numpy as np
     >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
-    >>> generator = lambda x: np.random.uniform(-0.5, 0.5, x)
-    >>> updator = lambda x, n, k, noise: x + n * k * noise
-    >>> noisy_image = gf(image, 10, generator, updator)
+    >>> generator = lambda w, h: np.random.uniform(-0.5, 0.5, (w, h))
+    >>> n = 10
+    >>> k = 0.2
+    >>> updator = lambda x, noise: x + n * k * noise
+    >>> noisy_image = gf(image, generator, updator)
     >>> noisy_image.shape
     (100, 100)
     """
@@ -43,53 +38,53 @@ def _global_noise_filter(image,
     else:
         width, height, nb_chanel = image_array.shape
 
-    a, b = distribution_interval
-    nb_pixels = width * height
-
-    if identical:
-        noise_filter = generator(nb_pixels)
+    if nb_chanel == 1 or identical:
+        noise_filter = generator(width, height)
 
     # final output numpy array
     output_array = []
 
-    for chanel in range(0, nb_chanel):
+    # check number of chanel
+    if nb_chanel == 1:
 
-        # getting flatten information from image and noise
-        if nb_chanel == 3:
-            image_array_flatten = image_array[:, :, chanel].reshape(nb_pixels)
-        else:
-            image_array_flatten = image_array.reshape(nb_pixels)
+        image_array_flatten = image_array
+
+        noisy_image = np.array(
+            list(map(updator, image_array_flatten, noise_filter)))
+
+        return np.array(noisy_image, 'uint8')
+
+    else:
+        # final output numpy array
+        output_array = []
 
-        # redefine noise if necessary
-        if not identical:
-            noise_filter = generator(nb_pixels)
+        for chanel in range(0, nb_chanel):
 
-        # compute new pixel value
-        # n * k * white_noise_filter[i]
-        noisy_image = np.asarray([
-            updator(image_array_flatten[i], n, k, noise_filter[i])
-            for i in range(0, nb_pixels)
-        ])
+            # getting flatten information from image and noise
+            image_array_flatten = image_array[:, :, chanel]
 
-        # reshape and normalize new value
-        noisy_image = noisy_image.reshape((width, height))
+            # redefine noise if necessary
+            if not identical:
+                noise_filter = generator(width, height)
 
-        noisy_image = np.asarray(noisy_image, 'uint8')
+            # compute new pixel value
+            # x + n * k * white_noise_filter[i] as example
+            noisy_image = np.array(
+                list(map(updator, image_array_flatten, noise_filter)))
 
-        # in order to concatenae output array
-        if nb_chanel == 3:
+            # set uint8 values
+            noisy_image = np.array(noisy_image, 'uint8')
+
+            # in order to concatenate output array
             noisy_image = noisy_image[:, :, np.newaxis]
 
-        # append new chanel
-        output_array.append(noisy_image)
+            # append new chanel
+            output_array.append(noisy_image)
 
-    # concatenate RGB image
-    if nb_chanel == 3:
+        # concatenate RGB image
         output_array = np.concatenate(output_array, axis=2)
-    else:
-        output_array = np.asarray(output_array).reshape(width, height)
 
-    return output_array
+        return output_array
 
 
 def white_noise(image,
@@ -120,12 +115,11 @@ def white_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.uniform(a, b, x)
+    generator = lambda w, h: np.random.uniform(a, b, (w, h))
 
-    updator = lambda x, n, k, noise: x + n * k * noise
+    updator = lambda x, noise: x + n * k * noise
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, generator, updator, identical)
 
 
 def gaussian_noise(image,
@@ -156,12 +150,11 @@ def gaussian_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.normal(a, b, x)
+    generator = lambda w, h: np.random.normal(a, b, (w, h))
 
-    updator = lambda x, n, k, noise: x + n * k * noise
+    updator = lambda x, noise: x + n * k * noise
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, generator, updator, identical)
 
 
 def laplace_noise(image,
@@ -192,12 +185,11 @@ def laplace_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.laplace(a, b, x)
+    generator = lambda w, h: np.random.laplace(a, b, (w, h))
 
-    updator = lambda x, n, k, noise: x + n * k * noise
+    updator = lambda x, noise: x + n * k * noise
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, generator, updator, identical)
 
 
 def cauchy_noise(image,
@@ -228,12 +220,11 @@ def cauchy_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.standard_cauchy(x)
+    generator = lambda w, h: np.random.standard_cauchy((w, h))
 
-    updator = lambda x, n, k, noise: x + n * k * noise
+    updator = lambda x, noise: x + n * k * noise
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, generator, updator, identical)
 
 
 def log_normal_noise(image,
@@ -264,12 +255,11 @@ def log_normal_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.lognormal(a, b, x)
+    generator = lambda w, h: np.random.lognormal(a, b, (w, h))
 
-    updator = lambda x, n, k, noise: x + n * k * noise
+    updator = lambda x, noise: x + n * k * noise
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, generator, updator, identical)
 
 
 def mut_white_noise(image,
@@ -300,9 +290,63 @@ def mut_white_noise(image,
     """
 
     a, b = distribution_interval
-    generator = lambda x: np.random.uniform(a, b, x)
+    generator = lambda w, h: np.random.uniform(a, b, (w, h))
+
+    updator = lambda x, noise: x * n * k * noise
+
+    return _global_noise_filter(image, generator, updator, identical)
+
 
-    updator = lambda x, n, k, noise: x * n * k * noise
+def salt_pepper_noise(image, n, identical=False, p=0.1, k=0.5):
+    """Pepper salt noise filter to apply on image
+
+    Args:
+        image: image used as input (2D or 3D image representation)
+        n: used to set importance of noise [1, 999]
+        identical: keep or not identical noise distribution for each canal if RGB Image (default False)
+        p: probability to increase pixel value otherwise decrease it
+        k: variable that specifies the amount of noise to be taken into account in the output image (default 0.5)
+
+    Returns:
+        2D Numpy array with salt and pepper noise applied
+
+    Example:
+
+    >>> from ipfml.filters.noise import salt_pepper_noise
+    >>> import numpy as np
+    >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
+    >>> noisy_image = salt_pepper_noise(image, 10)
+    >>> noisy_image.shape
+    (100, 100)
+    """
+
+    def _generator(w, h):
+
+        x = w * h
+        nb_elem = int(p * x)
+
+        elements = np.full(x, 0)
+        elements[0:nb_elem] = 1
+        np.random.shuffle(elements)
+
+        return elements.reshape(w, h)
+
+    # here noise variable is boolean to update or not pixel value
+    def _updator(x, noise):
+
+        # apply specific changes to each value of 1D array
+        if isinstance(x, np.ndarray):
+            return np.array(list(map(_updator, x, noise)))
+
+        # probabilty to increase or decrease pixel value
+        rand = random.uniform(0, 1)
+
+        if noise:
+            if rand > 0.5:
+                return x + n * k
+            else:
+                return x - n * k
+        else:
+            return x
 
-    return _global_noise_filter(image, n, generator, updator, identical,
-                                distribution_interval, k)
+    return _global_noise_filter(image, _generator, _updator, identical)