diff --git a/CMakeLists.txt b/CMakeLists.txt
index 0bb7267c6f63ee13bf57e5dfa6dbd1f86ff071ca..4d89030328c4dfb04d0deb3502b279276f3ea187 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -1,7 +1,7 @@
 project(ImageINSA)
 cmake_minimum_required(VERSION 2.8.11)
 
-set(CMAKE_BUILD_TYPE "Debug")
+#set(CMAKE_BUILD_TYPE "Debug")
 # Find includes in corresponding build directories
 set(CMAKE_INCLUDE_CURRENT_DIR ON)
 # Instruct CMake to run moc automatically when needed.
diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt
index 38bccfa7bf5b1a62abf2afb1df9318e6dab2f2ab..ba856bb854e41a2c0e8e1f6645f8286895b8e1f0 100644
--- a/app/CMakeLists.txt
+++ b/app/CMakeLists.txt
@@ -81,6 +81,10 @@ set(imageinsa_SOURCES
 	Operations/InversePyramidOp.h
 	Operations/MeanSquaredErrorOp.cpp
 	Operations/MeanSquaredErrorOp.h
+	Operations/MedianDialog.cpp
+	Operations/MedianDialog.h
+        Operations/MedianOp.cpp
+        Operations/MedianOp.h
 	Operations/DPCM.cpp
 	Operations/DPCM.h
 	Operations/DPCMDialog.cpp
@@ -160,6 +164,8 @@ set(imageinsa_SOURCES
 	Widgets/ImageZoneSelector.h
 	Widgets/OperationBar.cpp
 	Widgets/OperationBar.h
+        Widgets/Preview.cpp
+        Widgets/Preview.h
 	Widgets/StructElemViewer.cpp
 	Widgets/StructElemViewer.h
 	Widgets/StructElemWindow.cpp
@@ -176,6 +182,7 @@ set(UIS
 	Operations/DPCMDialog.ui
 	Operations/DCTDialog.ui
 	Operations/ColorDialog.ui
+        Operations/MedianDialog.ui
 )
 
 qt5_wrap_ui(WRAPPED_UIS ${UIS})
diff --git a/app/Operations/EntropyOp.cpp b/app/Operations/EntropyOp.cpp
index 6b524ccc06b0f8f55f201313ce1aa4872df91cb6..f978cd4c1243d119bc784e82ae6bdc20ef5ab024 100644
--- a/app/Operations/EntropyOp.cpp
+++ b/app/Operations/EntropyOp.cpp
@@ -40,10 +40,12 @@ void EntropyOp::operator()(const imagein::Image* image, const std::map<const ima
             if(histo[i] > 0) {
                 double p = (double)histo[i] / image->getWidth() /image->getHeight();
                 entropy +=  p * log(p);
+                entropy = - entropy / log(2);
+
             }
+
         }
     }
-    entropy = - entropy / log(2);
     outText(qApp->translate("Operations", "Entropy of the image = %1").arg(entropy).toStdString());
 
 }
diff --git a/app/Operations/Huffman.cpp b/app/Operations/Huffman.cpp
index 01fd42ca3b2e06e278661b4f2a3c78cf64ca044e..95c36ca655a6ecb25294ee96bf8eb56ad8295ec2 100644
--- a/app/Operations/Huffman.cpp
+++ b/app/Operations/Huffman.cpp
@@ -21,6 +21,7 @@
 #include <cstring>
 #include <cstdio>
 #include <cmath>
+#include <algorithm>
 
 using namespace std;
 using namespace imagein;
@@ -63,6 +64,7 @@ string Huffman::execute( const GrayscaleImage *im ) {
     int nbpt;
     long wcounter, hcounter;
     char buffer[255];
+    char c[255];
     std::string returnval;
     Image::depth_t p;
     int i;
@@ -72,7 +74,7 @@ string Huffman::execute( const GrayscaleImage *im ) {
     for( hcounter=0; hcounter< im->getHeight(); hcounter++ ) {
         for( wcounter=0; wcounter< im->getWidth(); wcounter++ ) {
             p = im->getPixel( wcounter, hcounter );
-            if( p != 0 ) {
+            if( p >= 0 ) {
                 nbpt++;
             }
         }
@@ -85,9 +87,11 @@ string Huffman::execute( const GrayscaleImage *im ) {
 
     for(i=0 ; i<nbeff ; i++)
     {
-        sprintf(buffer, "%s",chain+i*nbeff);
+        sprintf(c, "%s", chain+i*nbeff);
+        reverse (c,c+strlen(c));
+        sprintf(buffer, "%s",c);
         returnval = returnval + buffer;
-        sprintf(buffer, "--->%2d bits      Pi[%3d] = %7.5f\n",*(ilon+i),*(indicePi+i),*(Pi+i));
+        sprintf(buffer, "--->%2d bits      Pi[%3d] = %7.5f\n",*(ilon+i),*(indicePi+i)-1,*(Pi+i));
         returnval = returnval + buffer;
     }
     sprintf(buffer, "\n debit(huffman) = %.4f\n",nbbit);
@@ -118,7 +122,7 @@ string Huffman::prob_Pi(const GrayscaleImage *im, int nbpt )
     for( hcounter=0; hcounter< im->getHeight(); hcounter++ ) {
         for( wcounter=0; wcounter< im->getWidth(); wcounter++ ) {
             pixel = im->getPixel( wcounter, hcounter );
-            if((pixel < min) && (pixel != 0))
+            if((pixel < min) && (pixel >= 0))
                 min = pixel;
             if(pixel > max)
                 max = pixel;
@@ -145,7 +149,7 @@ string Huffman::prob_Pi(const GrayscaleImage *im, int nbpt )
     for( hcounter=0; hcounter< im->getHeight(); hcounter++ ) {
         for( wcounter=0; wcounter< im->getWidth(); wcounter++ ) {
             pixel = im->getPixel( wcounter, hcounter );
-            if( pixel != 0 ) {
+            if( pixel >= 0 ) {
                 ind = pixel;
                 p[ind-min]++;
             }
@@ -156,6 +160,7 @@ string Huffman::prob_Pi(const GrayscaleImage *im, int nbpt )
     /**********************************
      *  nbeff : nb effectif
      *  de luminace utile --> Pi != 0
+     *
      *  soit : la lum 'i' existe
      *
      **********************************/
@@ -264,6 +269,7 @@ void Huffman::codhuffman(void)
             }
         }
         nbbit = nbbit + (double)(*(ilon+i))*(*(Pi+i));
+
     }
     delete icod;
 }
diff --git a/app/Operations/MedianDialog.cpp b/app/Operations/MedianDialog.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..bef0e07df0e2d5d932fc1e5c66ccb518d103e730
--- /dev/null
+++ b/app/Operations/MedianDialog.cpp
@@ -0,0 +1,26 @@
+#include "MedianDialog.h"
+#include "ui_MedianDialog.h"
+
+MedianDialog::MedianDialog(QWidget *parent) :
+    QDialog(parent),
+    ui(new Ui::MedianDialog)
+{
+    ui->setupUi(this);
+}
+
+bool MedianDialog::cross() const {
+    return ui->radioButton->isChecked();
+}
+
+bool MedianDialog::square() const {
+    return ui->radioButton_2->isChecked();
+}
+
+unsigned int MedianDialog::getSize() const {
+    return ui->spinBox->value();
+}
+
+MedianDialog::~MedianDialog()
+{
+    delete ui;
+}
diff --git a/app/Operations/MedianDialog.h b/app/Operations/MedianDialog.h
new file mode 100644
index 0000000000000000000000000000000000000000..ffbfb827ab6358d1497bae65b6b1830fd332e36d
--- /dev/null
+++ b/app/Operations/MedianDialog.h
@@ -0,0 +1,26 @@
+#ifndef MEDIANDIALOG_H
+#define MEDIANDIALOG_H
+
+#include <QDialog>
+
+namespace Ui {
+class MedianDialog;
+}
+
+class MedianDialog : public QDialog
+{
+    Q_OBJECT
+
+public:
+    explicit MedianDialog(QWidget *parent = 0);
+    ~MedianDialog();
+
+    bool cross() const;
+    bool square() const;
+    unsigned int getSize() const;
+
+private:
+    Ui::MedianDialog *ui;
+};
+
+#endif // MEDIANDIALOG_H
diff --git a/app/Operations/MedianDialog.ui b/app/Operations/MedianDialog.ui
new file mode 100644
index 0000000000000000000000000000000000000000..4b81d8d775e49d91579d8478d9c025e5db9f3203
--- /dev/null
+++ b/app/Operations/MedianDialog.ui
@@ -0,0 +1,149 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>MedianDialog</class>
+ <widget class="QDialog" name="MedianDialog">
+  <property name="geometry">
+   <rect>
+    <x>0</x>
+    <y>0</y>
+    <width>259</width>
+    <height>180</height>
+   </rect>
+  </property>
+  <property name="windowTitle">
+   <string>Dialog</string>
+  </property>
+  <widget class="QGroupBox" name="Forme">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>10</y>
+     <width>241</width>
+     <height>51</height>
+    </rect>
+   </property>
+   <property name="title">
+    <string>Forme</string>
+   </property>
+   <widget class="QRadioButton" name="radioButton">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>20</y>
+      <width>82</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Croix</string>
+    </property>
+    <property name="checked">
+     <bool>true</bool>
+    </property>
+   </widget>
+   <widget class="QRadioButton" name="radioButton_2">
+    <property name="geometry">
+     <rect>
+      <x>120</x>
+      <y>20</y>
+      <width>82</width>
+      <height>17</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Carré</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QWidget" name="widget" native="true">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>70</y>
+     <width>241</width>
+     <height>41</height>
+    </rect>
+   </property>
+   <widget class="QSpinBox" name="spinBox">
+    <property name="geometry">
+     <rect>
+      <x>190</x>
+      <y>10</y>
+      <width>41</width>
+      <height>22</height>
+     </rect>
+    </property>
+    <property name="minimum">
+     <number>1</number>
+    </property>
+    <property name="maximum">
+     <number>30</number>
+    </property>
+    <property name="value">
+     <number>3</number>
+    </property>
+   </widget>
+   <widget class="QLabel" name="label">
+    <property name="geometry">
+     <rect>
+      <x>10</x>
+      <y>10</y>
+      <width>47</width>
+      <height>13</height>
+     </rect>
+    </property>
+    <property name="text">
+     <string>Taille</string>
+    </property>
+   </widget>
+  </widget>
+  <widget class="QDialogButtonBox" name="buttonBox">
+   <property name="geometry">
+    <rect>
+     <x>10</x>
+     <y>140</y>
+     <width>241</width>
+     <height>23</height>
+    </rect>
+   </property>
+   <property name="standardButtons">
+    <set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
+   </property>
+  </widget>
+ </widget>
+ <resources/>
+ <connections>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>accepted()</signal>
+   <receiver>MedianDialog</receiver>
+   <slot>accept()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>130</x>
+     <y>151</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>129</x>
+     <y>89</y>
+    </hint>
+   </hints>
+  </connection>
+  <connection>
+   <sender>buttonBox</sender>
+   <signal>rejected()</signal>
+   <receiver>MedianDialog</receiver>
+   <slot>reject()</slot>
+   <hints>
+    <hint type="sourcelabel">
+     <x>130</x>
+     <y>151</y>
+    </hint>
+    <hint type="destinationlabel">
+     <x>129</x>
+     <y>89</y>
+    </hint>
+   </hints>
+  </connection>
+ </connections>
+</ui>
diff --git a/app/Operations/MedianOp.cpp b/app/Operations/MedianOp.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..cec2f22d42213927b7c998c505369c30599b1fad
--- /dev/null
+++ b/app/Operations/MedianOp.cpp
@@ -0,0 +1,112 @@
+#include "MedianOp.h"
+#include "MedianDialog.h"
+#include <QApplication>
+#include <vector>
+#include <cstring>
+#include <cstring>
+#include <cstdio>
+#include <cmath>
+#include <algorithm>
+
+
+MedianOp::MedianOp(): Operation(qApp->translate("Operations", "Median Filter").toStdString())
+{
+
+}
+bool MedianOp::needCurrentImg() const {
+    return true;
+}
+
+void MedianOp::operator()(const imagein::Image* image, const std::map<const imagein::Image*, std::string>&) {
+
+    using namespace std;
+    using namespace imagein;
+    Image* resImg = new Image(image->getWidth(), image->getHeight(), image->getNbChannels());
+    int wSide; // taille de la fenetre du filtre
+    vector<int> window; // fenetre du filtre
+    unsigned int imageWidth = image->getWidth();
+    unsigned int imageHeight = image->getHeight();
+    unsigned int nbChannels = image->getNbChannels();
+    int iStart, iStop, jStart, jStop;
+    int i,j;
+
+
+
+    MedianDialog* dialog = new MedianDialog(QApplication::activeWindow());
+    dialog->setWindowTitle(QString(qApp->translate("Operations", "Median Filter")));
+
+    QDialog::DialogCode code = static_cast<QDialog::DialogCode>(dialog->exec());
+
+    if(code!=QDialog::Accepted) return;
+    if(dialog->square()){
+        wSide = dialog->getSize();
+
+        // parcours des composantes de couleur
+     for (int c=0;c<nbChannels;c++){
+
+         // parcours de l'image
+         for (int x=0;x<imageWidth;x++){
+             for(int y=0;y<imageHeight;y++){
+                     //parcours de la fenêtre du filtre
+
+                     x-wSide/2 < 0 ? iStart = 0 : iStart = x-wSide/2;
+                     x+wSide/2 > imageWidth-1 ? iStop = imageWidth : iStop = x+wSide/2+1;
+                     y-wSide/2 < 0 ? jStart = 0 : jStart = y-wSide/2;
+                     y+wSide/2 > imageHeight-1 ? jStop = imageHeight : jStop = y+wSide/2+1;
+
+                     for(i=iStart; i< iStop ; i++){
+                         for(j=jStart;j<jStop;j++){
+                             //remplissage de la fenêtre du filtre
+                             window.push_back(image->getPixelAt(i,j,c));
+                         }//j
+                     }//i
+
+                 size_t size = window.size();
+                 sort(window.begin(), window.begin()+size);
+                 resImg->setPixelAt(x, y, c, window[size/2]);
+                 window.clear();
+             }//y
+         }//x
+     }//c
+    }// if square
+    if(dialog->cross()){
+        wSide = dialog->getSize();
+
+        // parcours des composantes de couleur
+         for (int c=0;c<nbChannels;c++){
+
+             // parcours de l'image
+             for (int x=0;x<imageWidth;x++){
+                 for(int y=0;y<imageHeight;y++){
+                         //parcours de la fenêtre du filtre
+
+                         x-wSide/2 < 0 ? iStart = 0 : iStart = x-wSide/2;
+                         x+wSide/2 > imageWidth-1 ? iStop = imageWidth : iStop = x+wSide/2+1;
+                         y-wSide/2 < 0 ? jStart = 0 : jStart = y-wSide/2;
+                         y+wSide/2 > imageHeight-1 ? jStop = imageHeight : jStop = y+wSide/2+1;
+
+
+                         for(int i=iStart; i< iStop ; i++){
+                             for(int j=jStart;j<jStop;j++){
+                                 //remplissage de la fenêtre du filtre
+                                 if (i==x || j==y)window.push_back(image->getPixelAt(i,j,c));
+
+                             }//j
+                         }//i
+
+                     size_t size = window.size();
+                     sort(window.begin(), window.begin()+size);
+                     resImg->setPixelAt(x, y, c, window[size/2]);
+                     window.clear();
+                 }//y
+             }//x
+         }//c
+    }// if cross
+
+    //conversion de la taille de la fenêtre en string pour l'affichage de l'image résultat
+    string str;
+    ostringstream convert;
+    convert << wSide;
+    str = convert.str();
+    outImage(resImg, "Filtered (median"+str+"x"+str+")");
+}
diff --git a/app/Operations/MedianOp.h b/app/Operations/MedianOp.h
new file mode 100644
index 0000000000000000000000000000000000000000..f35a3717319e248f8308d6bc3c4f3793152d907e
--- /dev/null
+++ b/app/Operations/MedianOp.h
@@ -0,0 +1,16 @@
+#ifndef MEDIANOP_H
+#define MEDIANOP_H
+
+#include "Operation.h"
+
+class MedianOp : public Operation
+{
+public:
+    MedianOp();
+
+    void operator()(const imagein::Image*, const std::map<const imagein::Image*, std::string>&);
+
+    bool needCurrentImg() const;
+};
+
+#endif // MEDIANOP_H
diff --git a/app/Operations/PointOp.cpp b/app/Operations/PointOp.cpp
index 05261d72062e0e31b7d5c02ebf4000899d168a8a..f18d37fd2940f09f2a0a6d0676383cc75e9fc2df 100644
--- a/app/Operations/PointOp.cpp
+++ b/app/Operations/PointOp.cpp
@@ -73,6 +73,8 @@ PointOp::ImageOp* PointOp::ImageOp::fromString(QString op) {
     if(op=="+") return new ImgAdd();
     if(op=="-") return new ImgSub();
     if(op=="&") return new ImgAnd();
+    if(op=="*") return new ImgMul();
+    if(op=="/") return new ImgDiv();
     if(op=="|") return new ImgOr();
     if(op=="^") return new ImgXor();
     if(op=="") return new ImgIdent();
diff --git a/app/Operations/PointOp.h b/app/Operations/PointOp.h
index 9ce41290748a1e18c60cee6f1908037eb45fe09f..7c58dadc27c1f8e5d0c5a78eeff737bd6a6b154c 100644
--- a/app/Operations/PointOp.h
+++ b/app/Operations/PointOp.h
@@ -157,14 +157,23 @@ class PointOp : public GenericOperation {
     };
 
     struct ImgSub : ImageOp {
-        intmax_t op(depth_t pix1, depth_t pix2) { return pix1 - pix2; } 
+        intmax_t op(depth_t pix1, depth_t pix2) { return pix1 - pix2; }
     };
     struct DoubleImgSub : DoubleImageOp {
         double op(double pix1, double pix2) { return pix1 - pix2; }
     };
+
+    struct ImgMul : ImageOp {
+        intmax_t op(depth_t pix1, depth_t pix2) { return pix1 * pix2; }
+    };
     struct DoubleImgMul : DoubleImageOp {
         double op(double pix1, double pix2) { return pix1 * pix2; }
     };
+
+    struct ImgDiv : ImageOp {
+        intmax_t op(depth_t pix1, depth_t pix2) { if(pix2 != 0) {return pix1/pix2*255;} else {return 255;}}
+    };
+
     struct DoubleImgDiv : DoubleImageOp {
         double op(double pix1, double pix2) { return pix1 / pix2; }
     };
diff --git a/app/Operations/Quantification.cpp b/app/Operations/Quantification.cpp
index cf19bcb24cb09b39bdd8aafe195aadbe8c6ab5d3..aa79ecf5ab4c1b2d7fabb09e0cbbec67beabbff2 100644
--- a/app/Operations/Quantification.cpp
+++ b/app/Operations/Quantification.cpp
@@ -173,3 +173,55 @@ Quantification Quantification::nonLinearQuantOptimized(int size, const Image* im
     return quant;
 }
 
+Quantification Quantification::lloydMaxQuant(int size, const Image* image, unsigned int c) {
+
+//    Quantification quant(size);
+
+//    for(int i = 0; i < size - 1; ++i) {
+//        quant._threshold[i] = floor( (i + 1) * (float)N_MAX_THRESHOLD / size + 0.5);
+//    }
+//    if(size > 0) {
+//        quant._values[0] = floor( quant._threshold[0] / 2. + 0.5 );
+//        quant._values[size - 1] = floor( ((float)N_MAX_THRESHOLD + quant._threshold[size - 2]) / 2. + 0.5 );
+//    }
+//    for(int i = 1; i < size - 1; ++i) {
+//        quant._values[i] = floor( (double)(quant._threshold[i] + quant._threshold[i-1]) / 2. + 0.5 );
+//    }
+
+//    return quant;
+
+
+    Histogram histogram = image->getHistogram(c);
+    int som_lum = 0;
+    int nb_points = 0;
+    int cpt = 6;
+
+    // initialisation : repartion lineaire des niveaux de quantification
+    Quantification quant = linearQuant(size);
+
+    while(cpt > 0){
+
+        // calcul des nouveaux seuils de quantification
+        for (int i=0; i<size-2;i++){
+            quant._threshold[i] = (quant._values[i]+quant._values[i+1])/2;
+        }//for (parcours du tableau de seuils)
+
+        // calcul des nouveaux niveaux de quantification
+
+        //calcul pdf
+
+        for (int j=0; j<size-1;j++){
+            for(int i= ((quant._threshold)[j]); i <= ((quant._threshold)[j+1]); i++){
+                som_lum += histogram[i]*i;
+                nb_points += histogram[i];
+            }
+
+        quant._values[j]= (int) quant._values[j]*(som_lum/nb_points) / (som_lum/nb_points);
+        }//for (parcours du tableau de valeurs)
+
+        cpt--;
+
+    }//while
+
+    return quant;
+}
diff --git a/app/Operations/Quantification.h b/app/Operations/Quantification.h
index d15d5a5adcc75a77ed95b9d50bba69a12f917403..fcb98e792fb4a7d8a0a3a196d939e1c7b4877a4f 100644
--- a/app/Operations/Quantification.h
+++ b/app/Operations/Quantification.h
@@ -53,6 +53,7 @@ public:
     static Quantification linearQuant(int size);
     static Quantification nonLinearQuant(int size, const imagein::Image *image, unsigned int c);
     static Quantification nonLinearQuantOptimized(int size, const imagein::Image *image, unsigned int c);
+    static Quantification lloydMaxQuant(int size, const imagein::Image* image, unsigned int c);
 
 private:
     int size;
diff --git a/app/Operations/QuantificationDialog.cpp b/app/Operations/QuantificationDialog.cpp
index 8f904d0c46d0f57a3cfa32f16308644fc6d31e8b..54e4baf02ca1cdbba576b424630f4de7967bf778 100644
--- a/app/Operations/QuantificationDialog.cpp
+++ b/app/Operations/QuantificationDialog.cpp
@@ -56,6 +56,8 @@ QuantificationDialog::QuantificationDialog(QWidget *parent, QString imgName) :
         _quantBox->addItem(tr("Non linear with mean value"));
     }
     _quantBox->addItem(tr("Custom"));
+    _quantBox->addItem(tr("LloydMax"));
+
     layout->insertRow(0, tr("Quantification : "), _quantBox);
     layout->insertRow(1, tr("Number of values : "), _sizeBox);
 
@@ -103,6 +105,8 @@ Quantification QuantificationDialog::getQuantif(const Image* image, unsigned int
         case 1: return Quantification::nonLinearQuant(size, image, c); break;
         case 2: return Quantification::nonLinearQuantOptimized(size, image, c); break;
         case 3: return _quantWidget->getQuantif(); break;
+        case 4: return Quantification::lloydMaxQuant(size, image, c); break;
+
         default: return Quantification::linearQuant(size); break;
     }
 }
diff --git a/app/Operations/SplitHsvOp.h b/app/Operations/SplitHsvOp.h
index 62dab1313aacc289854d90d9e10ebbf558ebf3c9..fc45591b5e580834bea65dbef9f0288ff1f630dc 100644
--- a/app/Operations/SplitHsvOp.h
+++ b/app/Operations/SplitHsvOp.h
@@ -26,6 +26,7 @@
 #include <Image.h>
 
 
+
 class SplitHsvOp : public Operation
 {
 public:
diff --git a/app/Operations/Transforms.cpp b/app/Operations/Transforms.cpp
index 053e25be2b206e5d8f5a8ef1424e021f57d51db4..9eefb95978ef7a3427ceda47e37fbcdd9485df7c 100644
--- a/app/Operations/Transforms.cpp
+++ b/app/Operations/Transforms.cpp
@@ -49,27 +49,19 @@ Image_t<double>* Transforms::hough(const GrayscaleImage *image ) {
                 for(unsigned int i1 = i+1; i1 < image->getWidth(); i1++) {
                     if(image->getPixelAt(i1, j1) == 255) {
                         const double x0 = i;
-                        const double y0 = j;
+                        const double y0 = image->getHeight() -j;
                         const double x1 = i1;
-                        const double y1 = j1;
+                        const double y1 = image->getHeight()-j1;
                         const double l0 = sqrt((double)((y0-y1)*(y0-y1) + (x0-x1)*(x0-x1)));
                         const double l1 = fabs((double)(x0*y1 - x1*y0));
                         const double x2 = l1/l0;
                         double y2;
                         const int i2 = x2 + 0.5;
                         int j2;
-//                        if(x1-x0 != 0) {
-//                            y2 = atan((y1-y0)/(x1-x0));
-//                            j2 = 125 + (int)(y2*124./pid2 + 0.5);
-                            y2 = (x1 != x0) ? atan((y1-y0) / (x1-x0)) : y1 > y0 ? pid2 : -pid2;
-                            j2 = (y2 / pi) * 180. + 90. + 0.5;
-//                            j2 = (x1 != x0) ? 125.5 + atan((y1-y0)/(x1-x0))*124./pid2 : 250;
-//                        }
-//                        else {
-//                            j2 = 250;
-//                        }
-
-//                        itab[j2*width+i2]++;
+
+                            y2 = (x1 != x0) ? atan((y1-y0) / (x1-x0)) : y1 > y0 ? pid2 : pid2;
+                            j2 = (int)(180-((y2 / pi) * 180. + 90. + 0.5)) % 180 +1;
+
                         resImg->setPixelAt(i2, j2, resImg->getPixelAt(i2, j2) + 1.);
                     }
                 }
@@ -78,29 +70,19 @@ Image_t<double>* Transforms::hough(const GrayscaleImage *image ) {
                     for(unsigned int i1 = 0; i1 < image->getWidth(); i1++) {
                         if(image->getPixelAt(i1, j1) == 255) {
                             const double x0 = i;
-                            const double y0 = j;
+                            const double y0 = image->getHeight()-j;//-j
                             const double x1 = i1;
-                            const double y1 = j1;
+                            const double y1 = image->getHeight()-j1;//-j1
                             const double l0 = sqrt((double)((y0-y1)*(y0-y1) + (x0-x1)*(x0-x1)));
                             const double l1 = fabs((double)(x0*y1 - x1*y0));
-                            const double x2 = l1/l0;
-                            double y2;
-                            const int i2 = x2 + 0.5;
-                            int j2;
-//                            if(x1-x0 != 0) {
-//                                y2 = atan((double)(y1-y0)/(x1-x0));
-//                                j2 = 125 + (int)(y2*124./pid2 + 0.5);
-//                            }
-//                            else {
-//                                j2 = 250;
-//                            }
-                            y2 = x1 != x0 ? atan((y1-y0) / (x1-x0)) : y1 > y0 ? pid2 : -pid2;
-//                            j2 = (y2 / pi + 0.5) * image->getHeight() + 0.5;
-//                            j2 = (y2 * 2. + pi)*100.  + 0.5;
-                            y2 == pid2 ? j2 = 179 : j2 = (y2 / pi) * 180. + 90. + 0.5;
-//                            j2 = (x1 != x0) ? 125.5 + atan((y1-y0)/(x1-x0))*124./pid2 : 250;
-
-//                            itab[j2*width+i2]++;
+                            const double x2 = l1/l0; //Rho reel
+                            double y2;//theta radian (enconce tp)
+                            const int i2 = x2 + 0.5; //rho arrondi entier
+                            int j2;// theta degre [0 :180[
+
+                            y2 = x1 != x0 ? atan((y1-y0) / (x1-x0)) : y1 > y0 ? pid2 : pid2;//pid2 dans les deux cas (?)
+                            j2 = (int)(180-((y2 / pi) * 180. + 90. + 0.5)) % 180 +1;//conversion en entier + modulo 180
+
                             resImg->setPixelAt(i2, j2, resImg->getPixelAt(i2, j2) + 1.);
                         }
                     }
diff --git a/app/Services/ImageINSAService.cpp b/app/Services/ImageINSAService.cpp
index 1bf07e86b1d14ca32a5ba1e8ac8175b74e12f4f8..d76cb8b27fc0ec10ca5b41c30eb8228abd5abe38 100644
--- a/app/Services/ImageINSAService.cpp
+++ b/app/Services/ImageINSAService.cpp
@@ -45,6 +45,7 @@ void ImageINSAService::display(GenericInterface* gi)
     statusDock->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Preferred);
     statusDock->setMinimumWidth(128);
     statusDock->setWidget(_statusEdit);
+    statusDock->setFeatures(0x00);
     gi->addDockWidget(Qt::BottomDockWidgetArea, statusDock);
     _statusEdit->hide();
 }
diff --git a/app/Widgets/preview.cpp b/app/Widgets/preview.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..62a5a31c76d9ed49959b57efbcc23dc49c2c3ae6
--- /dev/null
+++ b/app/Widgets/preview.cpp
@@ -0,0 +1,24 @@
+//#include "Preview.h"
+
+
+//Preview::Preview(const imagein::Image* originalImage, Operation * operation){
+
+
+//}
+
+
+//void Preview::updatePreview(){
+//    const imagein::Image * test;
+//    test = new imagein::Image();
+//    if(_activateBox->isChecked())
+//    {
+//       _previewImage->setImage(_operation->operator ()(NULL,NULL,NULL);// _operation->operator ()(test, NULL, NULL);
+//    }
+//    else
+//    {
+//        _previewImage->setImage(_originalImage);
+//    }
+
+//    _previewImage->repaint();
+
+//}
diff --git a/app/Widgets/preview.h b/app/Widgets/preview.h
new file mode 100644
index 0000000000000000000000000000000000000000..252955ec4e56c560fdb7fdf1cbe6ceea32bd72a6
--- /dev/null
+++ b/app/Widgets/preview.h
@@ -0,0 +1,26 @@
+//#ifndef PREVIEW_H
+//#define PREVIEW_H
+
+//#include <QGridLayout>
+//#include <QCheckBox>
+//#include "../../lib/detiq-t/GenericInterface/Widgets/ImageWidgets/ImageWidget.h"
+//#include "../core/Operation.h"
+
+//class Preview : QGridLayout{
+
+//private:
+//    const imagein::Image* _originalImage;
+//    ImageWidget * _previewImage;
+//    QCheckBox * _activateBox;
+//    Operation * _operation;
+
+//public:
+//    Preview(const imagein::Image* originalImage, Operation * operation);
+
+//public slots:
+//    void updatePreview();
+
+
+//};
+
+//#endif // PREVIEW_H
diff --git a/app/imageinsa_en.ts b/app/imageinsa_en.ts
index 0bd2d57c210f9ae2de4561b857f5fe4a7e4f9f47..6d0fc5239857a2a99762e00a77f04c552d73e3f6 100644
--- a/app/imageinsa_en.ts
+++ b/app/imageinsa_en.ts
@@ -313,6 +313,14 @@ Number of classes = %1 </translation>
         <translation>Reconstructed color image</translation>
     </message>
 </context>
+<context>
+    <name>CombineHsvOp</name>
+    <message>
+        <location filename="Operations/CombineHsvOp.cpp" line="101"/>
+        <source>Reconstructed color image</source>
+        <translation>Reconstructed image</translation>
+    </message>
+</context>
 <context>
     <name>CroissanceOp</name>
     <message>
@@ -905,6 +913,7 @@ Number of classes = %1 </translation>
         <location filename="Operations/NoiseOp.cpp" line="49"/>
         <location filename="Operations/IFFTOp.cpp" line="49"/>
         <location filename="Operations/CombineColorOp.cpp" line="49"/>
+        <location filename="Operations/CombineHsvOp.cpp" line="49"/>
         <location filename="Operations/BFlitOp.cpp" line="49"/>
         <source>Parameters</source>
         <translation>Parameters</translation>
@@ -922,6 +931,11 @@ Number of classes = %1 </translation>
         <source>Combine color planes</source>
         <translation>Combine color planes</translation>
     </message>
+    <message>
+        <location filename="Operations/CombineHsv.cpp" line="38"/>
+        <source>Combine HSV planes</source>
+        <translation>Combine HSV planes</translation>
+    </message>
     <message>
         <location filename="Operations/CroissanceOp.cpp" line="37"/>
         <location filename="Operations/CroissanceOp.cpp" line="48"/>
diff --git a/app/imageinsa_fr.ts b/app/imageinsa_fr.ts
index ea1aa45be185fd01e736d19acca4cc5b9c12d129..a7c3b176f23b0d7dfe0f33debb0a0091f91ae305 100644
--- a/app/imageinsa_fr.ts
+++ b/app/imageinsa_fr.ts
@@ -313,6 +313,14 @@ Nombre de classes = %1 </translation>
         <translation>Image couleur reconstituée</translation>
     </message>
 </context>
+<context>
+    <name>CombineHsvOp</name>
+    <message>
+        <location filename="Operations/CombineHsvOp.cpp" line="101"/>
+        <source>Reconstructed image</source>
+        <translation>Image reconstituée</translation>
+    </message>
+</context>
 <context>
     <name>CroissanceOp</name>
     <message>
@@ -905,6 +913,7 @@ Nombre de classes = %1 </translation>
         <location filename="Operations/NoiseOp.cpp" line="49"/>
         <location filename="Operations/IFFTOp.cpp" line="49"/>
         <location filename="Operations/CombineColorOp.cpp" line="49"/>
+        <location filename="Operations/CombineHsvOp.cpp" line="49"/>
         <location filename="Operations/BFlitOp.cpp" line="49"/>
         <source>Parameters</source>
         <translation>Paramètres</translation>
@@ -922,6 +931,11 @@ Nombre de classes = %1 </translation>
         <source>Combine color planes</source>
         <translation>Combiner les plans de couleurs</translation>
     </message>
+    <message>
+        <location filename="Operations/CombineHsvOp.cpp" line="38"/>
+        <source>Combine HSV planes</source>
+        <translation>Combiner les plans TSV</translation>
+    </message>
     <message>
         <location filename="Operations/CroissanceOp.cpp" line="37"/>
         <location filename="Operations/CroissanceOp.cpp" line="48"/>
@@ -1060,6 +1074,11 @@ Nombre de classes = %1 </translation>
         <source>Split color planes</source>
         <translation>Séparer les plans de couleurs </translation>
     </message>
+    <message>
+        <location filename="Operations/SplitHsvOp.cpp" line="33"/>
+        <source>Split HSV planes</source>
+        <translation>Séparer les plans TSV </translation>
+    </message>
     <message>
         <location filename="Operations/FlipOp.cpp" line="30"/>
         <source>Flip %1</source>
diff --git a/app/main.cpp b/app/main.cpp
index 4754a3064ad95117386807d10b91a76df7d15e0d..205a66c9740cd6e11bf395c0fb42cefe3ccf62a6 100644
--- a/app/main.cpp
+++ b/app/main.cpp
@@ -69,6 +69,7 @@
 #include "Operations/ClassAnalysisOp.h"
 #include "Operations/ClassResultOp.h"
 #include "Operations/SeparatorOp.h"
+#include "Operations/MedianOp.h"
 
 
 #include "Services/MorphoMatService.h"
@@ -179,6 +180,7 @@ int main(int argc, char** argv)
 
     BuiltinOpSet* filter = new BuiltinOpSet(qApp->translate("", "Filtering").toStdString());
     filter->addOperation(new BFlitOp());
+    filter->addOperation(new MedianOp());
 
     mainService->addOpSet(image);
     mainService->addOpSet(encode);
diff --git a/lib/detiq-t b/lib/detiq-t
index 7962c9ce567f3072ce6f897b82998ea7430430d7..c29b38e4c5ef852ae3d0f1855701ab18aceaf7d4 160000
--- a/lib/detiq-t
+++ b/lib/detiq-t
@@ -1 +1 @@
-Subproject commit 7962c9ce567f3072ce6f897b82998ea7430430d7
+Subproject commit c29b38e4c5ef852ae3d0f1855701ab18aceaf7d4