Parcourir la source

Merge branch 'release/v0.2.1'

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

+ 160 - 0
CONTRIBUTING.md

@@ -0,0 +1,160 @@
+Contribution guidelines
+=====================================
+
+<p align="center">
+    <img src="ipfml_logo.png" width="30%">
+    <br />
+    Image Processing For Machine Learning
+</p>
+
+
+# Welcome !
+
+Thank you for taking the time to read this guide for the package's contribution. I'm glad to know that you may bring a lot to the IPFML package. This document will show you the good development practices used in the project and how you can easily participate in its evolution!
+
+# Table of contents
+
+1. [Naming conventions](#naming-conventions)
+
+    1.1. [Git naming conventions](#git-naming-conventions)
+
+    1.2. [Package modules conventions](#package-modules-conventions)
+
+2. [Coding conventions](#coding-conventions)
+
+    2.1. [Python conventions](#python-conventions)
+
+    2.3  [Code documentation](#code-documentation)
+
+    2.2. [Test implementation](#test-implementation)
+
+3. [Submission process](#submission-process)
+
+    3.1. [Build package](#build-package)
+
+    3.2. [Pull request](#pull-request)
+
+4. [Request an enhancement or report a bug](#request-an-enhancement-or-report-a-bug)
+
+# Naming conventions
+
+## Git naming conventions
+
+This project uses the naming conventions of the git branches set up by the [git-flow](https://danielkummer.github.io/git-flow-cheatsheet/) interface. To make your contribution as easy as possible to inject into the project, you will need to name your git branch as follows:
+
+```bash
+git branch feature/YourFeatureBranchName
+```
+
+Using git-flow interface:
+
+```bash
+git flow feature start YourFeatureBranchName
+```
+
+## Package modules conventions
+
+As you perhaps already saw, package contains multiples modules and submodules. It's really import to be well organized package and let it intuitive to access as possible to features.
+
+For the moment there are no precise conventions on the naming of new modules or sub-modules, it must just in a first step respect the hierarchy already in place and avoid any redundancies.
+
+In order to facilitate the integration of new modules, do not hesitate to let me know the name it could have beforehand.
+
+# Coding conventions
+
+## Python conventions
+
+This project follows the [coding conventions](http://google.github.io/styleguide/pyguide.html) implemented by Google. To help you to format **\*.py** files, it is possible to use the [yapf](https://github.com/google/yapf/) package developed by Google.
+
+Note that the **yapf** package is used during build process of **ipfml** package to format the whole code following these conventions.
+
+## Code documentation
+
+In order to allow quick access to the code, the project follows the documentation conventions (docstring) proposed by Google. Here an example:
+
+```python
+'''Divide image into equal size blocks
+
+  Args:
+      image: PIL Image or Numpy array
+      block: tuple (width, height) representing the size of each dimension of the block
+      pil: block type returned (default True)
+
+  Returns:
+      list containing all 2D Numpy blocks (in RGB or not)
+
+  Raises:
+      ValueError: If `image_width` or `image_heigt` are not compatible to produce correct block sizes
+'''
+```
+
+You can generate documentation and display updates using these following commands:
+
+```
+bash build.sh
+firefox docs/index.html
+```
+
+## Test implementation
+
+This project use the [doctest](https://docs.python.org/3/library/doctest.html) package which enables to write tests into documentation as shown in example below:
+
+```python
+"""Cauchy 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)
+      distribution_interval: set the distribution interval of normal law distribution (default (0, 1))
+      k: variable that specifies the amount of noise to be taken into account in the output image (default 0.0002)
+
+  Returns:
+      2D Numpy array with Cauchy noise applied
+
+  Example:
+
+  >>> from ipfml.filters.noise import cauchy_noise
+  >>> import numpy as np
+  >>> image = np.random.uniform(0, 255, 10000).reshape((100, 100))
+  >>> noisy_image = cauchy_noise(image, 10)
+  >>> noisy_image.shape
+  (100, 100)
+"""
+```
+
+Moreover, tests written are displayed into generated documentation and let examples of how to use the developed function.
+
+# Submission process
+
+## Build pakcage
+
+One thing to do before submit your feature is to build the package:
+
+```bash
+python setup.py build
+```
+
+This command do a lot of thing for you:
+  - Runs the tests from documentation and raise errors if there are.
+  - Formats all **\*.py** inside *ipfml* folder using **yapf**.
+  - Generate new documentation output inside **docs** folder.
+
+## Pull request
+
+Once you have built the package following previous instructions. You can make a pull request using GitHub. A [documentation](https://help.github.com/articles/about-pull-requests/) about pull requests is available.
+
+# Request an enhancement or report a bug
+
+To enhance the package, do not hesitate to report bug or missing feature. To do that, just submit an issue using at one of this labels:
+
+- **feature** or **idea**: for new an enhancement to develop
+- **bug:** for a detected bug
+
+You can also add your own labels too or add priority label:
+
+- prio:**low**
+- prio:**normal**
+- prio:**high**
+
+Whatever the problem reported, I will thank you for your contribution to this project. So do not hesitate.

+ 4 - 3
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
 ------------
@@ -37,7 +38,7 @@ All these modules will be enhanced during development of the package. Documentat
 How to contribute
 -----------------
 
-This git project uses [git-flow](https://danielkummer.github.io/git-flow-cheatsheet/) implementation. You are free to contribute to it.
+Please refer to the [CONTRIBUTION.md](https://github.com/jbuisine/IPFML/blob/master/LICENSE) file if you want to contribute!
 
 ## Contributors
 

+ 9 - 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,11 @@ 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/
+
+Contribution
+------------
 
-.. _documentation: https://jbuisine.github.io/IPFML/  
+Please refer to the [CONTRIBUTION.md](https://github.com/jbuisine/IPFML/blob/master/LICENSE) file if you want to contribute!

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


+ 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: 69203b98984ddfbab21b49127519dae7
+config: a6aa4eab4e3241e33dfb446b986ce947
 tags: 645f666f9bcd5a90fca523b33c5a78b7

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

@@ -2,6 +2,8 @@ Contributing
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
 
 
 Using GitHub
@@ -9,7 +11,6 @@ Using GitHub
 
 This git project uses git-flow_ implementation. You are free to contribute to it.
 
-.. _git-flow: https://danielkummer.github.io/git-flow-cheatsheet/    
-
-You just have to create your own feature branch and make a pull request.
+.. _git-flow: https://danielkummer.github.io/git-flow-cheatsheet/
 
+Please refer to the [CONTRIBUTION.md](https://github.com/jbuisine/IPFML/blob/master/LICENSE) guidelines file if you want more information about process!

+ 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/_static/documentation_options.js

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

+ 4 - 4
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.2.0 documentation</title>
+  <title>Contributing &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           
@@ -156,11 +156,11 @@
             
   <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>
-<p>You just have to create your own feature branch and make a pull request.</p>
+<p>Please refer to the [CONTRIBUTION.md](<a class="reference external" href="https://github.com/jbuisine/IPFML/blob/master/LICENSE">https://github.com/jbuisine/IPFML/blob/master/LICENSE</a>) guidelines file if you want more information about process!</p>
 </div>
 </div>
 

+ 5 - 5
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.2.0 documentation</title>
+  <title>Description &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           
@@ -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>

+ 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.2.0 documentation</title>
+  <title>Examples &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -58,7 +58,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           

+ 11 - 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.2.0 documentation</title>
+  <title>Index &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           
@@ -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>

+ 3 - 3
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.2.0 documentation</title>
+  <title>Image Processing For Machine Learning &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -57,7 +57,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           
@@ -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
+ 35 - 2
docs/build/html/ipfml.html


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

@@ -1,7 +1,7 @@
 # Sphinx inventory version 2
 # Project: IPFML
-# Version: 0.2.0
+# Version: 0.2.1
 # 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ý¾Ï´ø¹Ô�é

+ 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.2.0 documentation</title>
+  <title>Python Module Index &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -59,7 +59,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </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.2.0 documentation</title>
+  <title>Search &mdash; IPFML v0.2.1 documentation</title>
   
 
   
@@ -56,7 +56,7 @@
             
             
               <div class="version">
-                0.2.0
+                0.2.1
               </div>
             
           

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


+ 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.2.0'
+version = '0.2.1'
 # The full versiabson, including alpha/beta/rc tags
-release = 'v0.2.0'
+release = 'v0.2.1'
 
 
 # -- General configuration ---------------------------------------------------

+ 4 - 3
docs/source/contributing.rst

@@ -2,6 +2,8 @@ Contributing
 =====================================
 
 .. image:: _static/ipfml_logo.png
+   :width: 400 px
+   :align: center
 
 
 Using GitHub
@@ -9,7 +11,6 @@ Using GitHub
 
 This git project uses git-flow_ implementation. You are free to contribute to it.
 
-.. _git-flow: https://danielkummer.github.io/git-flow-cheatsheet/    
-
-You just have to create your own feature branch and make a pull request.
+.. _git-flow: https://danielkummer.github.io/git-flow-cheatsheet/
 
+Please refer to the [CONTRIBUTION.md](https://github.com/jbuisine/IPFML/blob/master/LICENSE) guidelines file if you want more information about process!

+ 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 ?
 =================

+ 115 - 71
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 h, w: np.random.uniform(-0.5, 0.5, (h, w))
+    >>> n = 10
+    >>> k = 0.2
+    >>> updator = lambda x, noise: x + n * k * noise
+    >>> noisy_image = gf(image, generator, updator)
     >>> noisy_image.shape
     (100, 100)
     """
@@ -39,57 +34,57 @@ def _global_noise_filter(image,
     nb_chanel = 1
 
     if image_array.ndim != 3:
-        width, height = image_array.shape
+        height, width = image_array.shape
     else:
-        width, height, nb_chanel = image_array.shape
-
-    a, b = distribution_interval
-    nb_pixels = width * height
+        height, width, nb_chanel = image_array.shape
 
-    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(height, width)
 
-        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 h, w: np.random.uniform(a, b, (h, w))
 
-    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 h, w: np.random.normal(a, b, (h, w))
 
-    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 h, w: np.random.laplace(a, b, (h, w))
 
-    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 h, w: np.random.standard_cauchy((h, w))
 
-    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 h, w: np.random.lognormal(a, b, (h, w))
 
-    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 h, w: np.random.uniform(a, b, (h, w))
+
+    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(h, w):
+
+        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(h, w)
+
+    # 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)

+ 1 - 0
requirements.txt

@@ -8,3 +8,4 @@ scipy
 opencv-python
 scipy
 yapf
+doctest

+ 4 - 4
setup.py

@@ -17,7 +17,7 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
         from ipfml.filters import noise as noise_filters
 
         print("==============================")
-        print("Run test command...")
+        print("Runs test command...")
         doctest.testmod(processing)
         doctest.testmod(metrics)
         doctest.testmod(noise_filters)
@@ -25,7 +25,7 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
         # Run format code using ypaf
         try:
             print("==============================")
-            print("Run format code command...")
+            print("Runs format code command...")
             self.spawn(['yapf', '-ir', '-vv', 'ipfml'])
         except RuntimeError:
             self.warn('format pakcage code failed')
@@ -33,7 +33,7 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
         # Run update auto generated documentation
         try:
             print("==============================")
-            print("Run update of auto generated documentation...")
+            print("Runs update of auto generated documentation...")
             self.spawn(['bash', './build.sh'])
         except RuntimeError:
             self.warn('Error during documentation rendering')
@@ -43,7 +43,7 @@ class BuildTestCommand(setuptools.command.build_py.build_py):
 
 setup(
     name='ipfml',
-    version='0.2.0',
+    version='0.2.1',
     description='Image Processing For Machine Learning',
     long_description=readme(),
     classifiers=[