[med-svn] [opencfu] 02/05: Fix FTBFS error with opencv 3.1

Andreas Tille tille at debian.org
Tue Dec 6 21:58:38 UTC 2016


This is an automated email from the git hooks/post-receive script.

tille pushed a commit to branch master
in repository opencfu.

commit 1de908af4c41d5b8b64371421c83d12baa1047ea
Author: Andreas Tille <tille at debian.org>
Date:   Tue Dec 6 22:44:30 2016 +0100

    Fix FTBFS error with opencv 3.1
---
 debian/changelog                                   |   3 +
 debian/control                                     |   1 +
 debian/patches/0001-brew-formula.patch             |  35 ++
 ...2-Can-change-min_colour_clustering_points.patch | 403 +++++++++++++++++++++
 ...d-ordering-of-colour-clusters-by-quantity.patch |  60 +++
 ...0004-Counting-now-ignores-unmatched-cells.patch |  48 +++
 ...anged-maximum-value-of-min_cluster_points.patch |  76 ++++
 ...t-coloured-cluster-sometimes-wasn-t-shown.patch |  75 ++++
 ...-line-parsing-changes-to-highlight-colour.patch | 122 +++++++
 ...final-changes-for-clustering-improvements.patch |  31 ++
 ...ps-at-addressing-17.-Compiles-but-segfaul.patch | 192 ++++++++++
 ...0010-improve-compat-with-cv3-worked-on-RF.patch |  70 ++++
 .../0011-classifier-now-compatible-with-cv3.patch  | 309 ++++++++++++++++
 ...cit-linking-to-std-map-in-colour-clusters.patch |  40 ++
 debian/patches/0013-fixes-17.patch                 |  56 +++
 .../0014-Update-Colour-difference-formula.patch    | 359 ++++++++++++++++++
 ...hat-patch-compiles-and-updated-versioning.patch |  37 ++
 .../patches/0016-Compiler-compatibility-fix.patch  |  47 +++
 debian/patches/series                              |  16 +
 debian/rules                                       |   2 +-
 20 files changed, 1981 insertions(+), 1 deletion(-)

diff --git a/debian/changelog b/debian/changelog
index acdcab7..80e199a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,6 +1,9 @@
 opencfu (3.9.0-2) UNRELEASED; urgency=medium
 
   * cme fix dpkg-control
+  * Fix FTBFS error with opencv 3.1 (Thanks for the patch to Nobuhiro Iwamatsu
+    <iwamatsu at nigauri.org>)
+    Closes: #841248
 
  -- Andreas Tille <tille at debian.org>  Tue, 06 Dec 2016 22:40:49 +0100
 
diff --git a/debian/control b/debian/control
index 6009cc2..866f065 100644
--- a/debian/control
+++ b/debian/control
@@ -5,6 +5,7 @@ Uploaders: Quentin Geissmann <opencfu at gmail.com>,
 Section: misc
 Priority: optional
 Build-Depends: debhelper (>= 9),
+               dh-autoreconf,
                libgtkmm-2.4-dev,
                libopencv-dev
 Standards-Version: 3.9.8
diff --git a/debian/patches/0001-brew-formula.patch b/debian/patches/0001-brew-formula.patch
new file mode 100644
index 0000000..64669c6
--- /dev/null
+++ b/debian/patches/0001-brew-formula.patch
@@ -0,0 +1,35 @@
+From b4a099a803409de12fe09c70a3df4d65ab6001bb Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Sat, 4 Oct 2014 15:40:28 +0100
+Subject: [PATCH 01/11] brew formula
+
+---
+ packagingScripts/brew.rb | 16 ++++++++++++++++
+ 1 file changed, 16 insertions(+)
+ create mode 100644 packagingScripts/brew.rb
+
+diff --git a/packagingScripts/brew.rb b/packagingScripts/brew.rb
+new file mode 100644
+index 0000000..523f479
+--- /dev/null
++++ b/packagingScripts/brew.rb
+@@ -0,0 +1,16 @@
++
++require 'formula'
++class OpenCFU < Formula
++homepage 'http://opencfu.sourceforge.net/'
++url 'h http://sourceforge.net/projects/opencfu/files/linux/opencfu-3.9.0.tar.gz'
++sha1 '646561999b6c143701cad7a9c3000aebf973e36f'
++
++depends_on "pkg-config" => :build
++depends_on "gtkmm"
++depends_on "opencv"
++
++def install
++system "./configure" "--prefix=#{prefix}"
++system "make install"
++end
++end
+-- 
+2.9.3
+
diff --git a/debian/patches/0002-Can-change-min_colour_clustering_points.patch b/debian/patches/0002-Can-change-min_colour_clustering_points.patch
new file mode 100644
index 0000000..3cbdad1
--- /dev/null
+++ b/debian/patches/0002-Can-change-min_colour_clustering_points.patch
@@ -0,0 +1,403 @@
+From a6f528029a21c04c5fb15aa2b9e11450f97c28fd Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Fri, 13 Feb 2015 17:22:28 +0100
+Subject: [PATCH 02/11] Can change min_colour_clustering_points
+
+When analysing plates with two colours of cells, the automatic
+colour recognition box may be selected. Clustering may be modified
+in two ways, by changing the minimum search distance between points
+and by changing how many points need to be together to be considered
+a cluster.
+
+Up to now, the minimum number of points was fixed. Now it can be
+varied between 4 and 10 with a spin button. Higher numbers mean
+less of a chance of joining two separate clusters.
+
+Also included in this commit is the commented code to sort colour
+clusters by the abundance of colonies in the cluster. This code
+will be uncommented in the next commit
+---
+ src/gui/headers/Gui_ColourCluster.hpp        | 13 +++++-
+ src/gui/headers/text.hpp                     | 11 ++++-
+ src/gui/src/Gui_ColourCluster.cpp            | 34 ++++++++++----
+ src/processor/headers/ProcessingOptions.hpp  | 23 +++++++++-
+ src/processor/headers/Result.hpp             |  2 +-
+ src/processor/headers/Step_ColourCluster.hpp | 10 ++++-
+ src/processor/src/ProcessingOptions.cpp      |  2 +
+ src/processor/src/Result.cpp                 | 12 +++--
+ src/processor/src/Step_ColourCluster.cpp     | 66 ++++++++++++++++++++++++++--
+ 9 files changed, 150 insertions(+), 23 deletions(-)
+
+diff --git a/src/gui/headers/Gui_ColourCluster.hpp b/src/gui/headers/Gui_ColourCluster.hpp
+index 085c063..f488db7 100644
+--- a/src/gui/headers/Gui_ColourCluster.hpp
++++ b/src/gui/headers/Gui_ColourCluster.hpp
+@@ -43,12 +43,21 @@ class Gui_ColourCluster : public Gui_OptionSetterBaseClass
+             this->on_tick_box();
+             this->setOption();}
+     private:
+-        Gtk::HBox m_hbox;
++        Gtk::HBox m_hbox;
++        Gtk::HBox m_hbox_1;
++        Gtk::HBox m_hbox_2;
+ //        Gtk::VBox m_vbox; //declared in parent
+         Gtk::Adjustment m_adjust_clustering_distance;
+         Gtk::SpinButton m_spin_butt_clustering_distance;
+-        Gtk::CheckButton m_check_butt;
+         Gtk::Label m_lab_clustering_distance;
++
++        Gtk::Adjustment m_adjust_min_cluster_points;
++        Gtk::SpinButton m_spin_butt_min_cluster_points;
++        Gtk::Label m_lab_min_cluster_points;
++
++        Gtk::CheckButton m_check_butt;
++
++
+ };
+ 
+ #endif // GUI_COLOURCLUSTER_HPP
+diff --git a/src/gui/headers/text.hpp b/src/gui/headers/text.hpp
+index 27a0257..d231035 100644
+--- a/src/gui/headers/text.hpp
++++ b/src/gui/headers/text.hpp
+@@ -102,7 +102,9 @@ about ROIs, you will find video tutorial on the website.</big>"
+ 
+ //NJL 10/AUG/2014 Colour Clustering
+ #define LABEL_CHECKBUTTON_HAS_CLUSTERING_DISTANCE "Recognise similar colours"
+-#define LABEL_CLUSTERING "Coarseness:"
++#define LABEL_CLUSTERING_DISTANCE "Coarseness:"
++//NJL 13/FEB/2015
++#define LABEL_CLUSTERING_POINTS "Min. Neighbours:"
+ 
+ /*==================TOOLTIPS==================*/
+ 
+@@ -159,4 +161,11 @@ The \"Coarseness\" defines the maximum difference\n\
+ between colours grouped as similar. A coarseness\n\
+ of 2.3 corresponds to a just notable difference"
+ 
++//NJL 13/FEB/2015
++#define TOOLTIP_CLUSTERING_MINIMUM_POINTS "\
++The \"Min. Neighbours\" defines the minimum number\n\
++of neighbours a point should have to be in a cluster\n\
++A higher number means less chance of low density \n\
++points bridging two clusters."
++
+ #endif
+diff --git a/src/gui/src/Gui_ColourCluster.cpp b/src/gui/src/Gui_ColourCluster.cpp
+index 6fecb1c..0ac5e0b 100644
+--- a/src/gui/src/Gui_ColourCluster.cpp
++++ b/src/gui/src/Gui_ColourCluster.cpp
+@@ -5,25 +5,39 @@ Class to implement Colour Clustering GUI interface
+ Written 10/AUG/2014
+ */
+ Gui_ColourCluster::Gui_ColourCluster(Gui_ProcessorHandler& processor_hand,const std::string str):
+-    Gui_OptionSetterBaseClass(processor_hand,str),
++    Gui_OptionSetterBaseClass(processor_hand,str),
++    //clustering distance
+     m_adjust_clustering_distance(m_processor_hand.getOptions().getClustDist(),0.1,50.0,0.1,1.0,0.0),
+-    m_spin_butt_clustering_distance(m_adjust_clustering_distance, 0.0, 1),
+-    m_check_butt(LABEL_CHECKBUTTON_HAS_CLUSTERING_DISTANCE),
+-    m_lab_clustering_distance(LABEL_CLUSTERING)
++    m_spin_butt_clustering_distance(m_adjust_clustering_distance, 0.0, 1),
++    m_lab_clustering_distance(LABEL_CLUSTERING_DISTANCE),
++    //clustering members
++    m_adjust_min_cluster_points(m_processor_hand.getOptions().getClusteringMinPoints(),4,10,1,1.0,0.0),
++    m_spin_butt_min_cluster_points(m_adjust_min_cluster_points, 0.0, 1),
++    m_lab_min_cluster_points(LABEL_CLUSTERING_POINTS),
++    //check button
++    m_check_butt(LABEL_CHECKBUTTON_HAS_CLUSTERING_DISTANCE)
++
+ 
+ {
+     set_tooltip_text(TOOLTIP_CLUSTERING);
+-    m_hbox.set_tooltip_text(TOOLTIP_CLUSTERING_DISTANCE_SELECTOR);
++    m_hbox_1.set_tooltip_text(TOOLTIP_CLUSTERING_DISTANCE_SELECTOR);
++    m_hbox_2.set_tooltip_text(TOOLTIP_CLUSTERING_MINIMUM_POINTS);
+ 
+     //GUI Layout
+     m_vbox.pack_start(m_check_butt);
+-    m_vbox.pack_start(m_hbox);
+-    m_hbox.pack_start(m_lab_clustering_distance);
+-    m_hbox.pack_start(m_spin_butt_clustering_distance);
++    m_vbox.pack_start(m_hbox);
++    m_hbox.pack_start(m_hbox_1);
++    m_hbox_1.pack_start(m_lab_clustering_distance);
++    m_hbox_1.pack_start(m_spin_butt_clustering_distance);
++
++    m_hbox.pack_start(m_hbox_2);
++    m_hbox_2.pack_start(m_lab_min_cluster_points);
++    m_hbox_2.pack_start(m_spin_butt_min_cluster_points);
+ 
+     //Signal interaction
+     m_spin_butt_clustering_distance.signal_value_changed().connect( sigc::hide_return(sigc::mem_fun(*this,&Gui_ColourCluster::setOption)));
+-    m_check_butt.signal_toggled().connect(sigc::mem_fun(*this,&Gui_ColourCluster::on_activate_filter));
++    m_spin_butt_min_cluster_points.signal_value_changed().connect( sigc::hide_return(sigc::mem_fun(*this,&Gui_ColourCluster::setOption)));
++    m_check_butt.signal_toggled().connect(sigc::mem_fun(*this, &Gui_ColourCluster::on_activate_filter));
+ }
+ 
+ 
+@@ -31,12 +45,14 @@ Gui_ColourCluster::Gui_ColourCluster(Gui_ProcessorHandler& processor_hand,const
+ bool Gui_ColourCluster::updateOptions(){
+     DEV_INFOS("Trying to send a processing option");
+     float val_clust_dist = m_spin_butt_clustering_distance.get_value();
++    int val_clust_min_points = m_spin_butt_min_cluster_points.get_value_as_int();
+ 
+     bool has_clust_dist = m_check_butt.get_active();
+     m_opts.setHasClustDist(has_clust_dist);
+ 
+     if(has_clust_dist){
+         bool success = m_opts.setClustDist(val_clust_dist);
++        success = success && m_opts.setClustMinPoints(val_clust_min_points);
+         return success;
+     }
+     else
+diff --git a/src/processor/headers/ProcessingOptions.hpp b/src/processor/headers/ProcessingOptions.hpp
+index 0820286..e539068 100644
+--- a/src/processor/headers/ProcessingOptions.hpp
++++ b/src/processor/headers/ProcessingOptions.hpp
+@@ -91,7 +91,14 @@ class ProcessingOptions
+  *  \return double clustering search distance in L*a*b* colour space
+  */
+ 
+-        const double getClustDist()const{return m_clustering_distance;}
++        const double getClustDist()const{return m_clustering_distance;}
++
++//NJL 13/FEB/2015
++/** \brief Getter for the clustering distance
++ *  \return  int clustering_min_pts Number of neighbour points necessary to be in a cluster
++ */
++
++        const double getClusteringMinPoints()const{return m_clustering_min_pts;}
+ 
+  //NJL 10/AUG/2014
+ /** \brief Getter for the has_clustering_distance variable
+@@ -272,6 +279,19 @@ class ProcessingOptions
+                 return false;
+             }
+         }
++
++//NJL 13/FEB/2015
++/** \brief Setter for Clustering minimum points
++ *  \param int clustering_min_pts Number of neighbour points necessary to be in a cluster
++ */
++        bool setClustMinPoints(const double clustering_min_pts){
++            if (clustering_min_pts>=4 && clustering_min_pts<=10.){
++                m_clustering_min_pts = clustering_min_pts;
++                return true;}
++            else{
++                return false;
++            }
++        }
+ 
+ //NJL 14/AUG/2014
+ /** \brief Setter for m_has_clustering_distance
+@@ -291,6 +311,7 @@ class ProcessingOptions
+         std::pair<int,int> m_min_max_sat;
+         double m_likelihood_thr;
+         double m_clustering_distance; //NJL 10/AUG/2014
++        int m_clustering_min_pts; //NJL 13/FEB/2015
+         int m_threshold;
+         int m_threshold_mode;
+         bool m_has_max_radius;
+diff --git a/src/processor/headers/Result.hpp b/src/processor/headers/Result.hpp
+index 8f5172b..d344fb9 100644
+--- a/src/processor/headers/Result.hpp
++++ b/src/processor/headers/Result.hpp
+@@ -174,7 +174,7 @@ class Result{
+         void setSameObjects(bool b){m_same_objects = b;}
+         const bool getSameObjects()const {return m_same_objects;}
+         void recluster(const std::vector< std::pair<int,int> > clustered); //NJL 13/AUG/2014
+-        void ClusterOrder(); //NJL 02/SEP/2014
++        void ColorProcessing(bool ordering); //NJL 02/SEP/2014, 13/FEB/2014
+         void uncluster(); // NJL 01/SEP/2014
+ 
+         //const ClusterData& getClusterData() const{return m_clusterData;} //NJL 03/SEP/2014 //deprecated by getROIData(0)
+diff --git a/src/processor/headers/Step_ColourCluster.hpp b/src/processor/headers/Step_ColourCluster.hpp
+index 0f9c5ed..faf3b5d 100644
+--- a/src/processor/headers/Step_ColourCluster.hpp
++++ b/src/processor/headers/Step_ColourCluster.hpp
+@@ -7,7 +7,10 @@
+ #include <algorithm>
+ #include <utility>
+ #include <unordered_map>
+-#include <string>
++#include <string>
++#include <vector>
++
++
+ 
+ class ClusterPoint
+ {
+@@ -59,12 +62,15 @@ class Step_ColourCluster : public Step_BaseClass
+         std::vector<ClusterPoint> m_neighbours;
+ 
+         double m_clustering_distance_2;
+-        unsigned const m_min_cluster_pts = 4;
++        int m_min_cluster_pts;
+         int m_current_cluster;
+ 
+         void dbscan();
+         std::vector<std::vector<ClusterPoint>::iterator> findNeighbours(ClusterPoint);
+         void expandCluster(ClusterPoint);
++
++        //comparator for sorting pairs, from stackexchange
++
+ };
+ 
+ 
+diff --git a/src/processor/src/ProcessingOptions.cpp b/src/processor/src/ProcessingOptions.cpp
+index 3ffba4f..73c2ec3 100644
+--- a/src/processor/src/ProcessingOptions.cpp
++++ b/src/processor/src/ProcessingOptions.cpp
+@@ -10,6 +10,7 @@ ProcessingOptions::ProcessingOptions():
+     m_min_max_sat(0,255),
+     m_likelihood_thr(30),
+     m_clustering_distance(2.3), //NJL 10/AUG/2014
++    m_clustering_min_pts(4), //NJL 13/FEB/2015
+     m_threshold (10),
+     m_threshold_mode(OCFU_THR_NORM),
+     m_has_max_radius(false),
+@@ -33,6 +34,7 @@ ProcessingOptions&  ProcessingOptions::operator= (const ProcessingOptions& cpy){
+     m_threshold = cpy.getThr();
+     m_threshold_mode = cpy.getThrMode();
+     m_clustering_distance = cpy.getClustDist(); //NJL 10/AUG/2014
++    m_clustering_min_pts = cpy.getClusteringMinPoints(); //NJL 13/FEB/2015
+     m_has_max_radius = cpy.getHasMaxRad();
+     m_has_auto_threshold = cpy.getHasAutoThr();
+     m_has_hue_filter = cpy.getHasHueFilt();
+diff --git a/src/processor/src/Result.cpp b/src/processor/src/Result.cpp
+index 2223a2a..1c09855 100644
+--- a/src/processor/src/Result.cpp
++++ b/src/processor/src/Result.cpp
+@@ -185,14 +185,19 @@ void Result::recluster(std::vector< std::pair<int,int> > clustered){
+             valid.push_back(true);
+     }
+     applyFilter(valid);
+-    ClusterOrder();
++    ColorProcessing(true);
+ }
+ 
+ /**
++ *  ClusterOrder This function analyses the colours of clusters, with two ends
++ *  It assigns a mean colour to the cluster, and it allows the clusters to be sorted
++ *  by luminosity. Note that this overwrites the default preference to be sorted by
++ *  quantity
+  *
++ *  @param bool ordering Enables the ordering of colonies by luminosity
+  */
+ 
+-void Result::ClusterOrder(){
++void Result::ColorProcessing(bool ordering){
+ //create structure cluster 1: [colour, colour, colour...]
+ //                 cluster 2: [colour, ....]
+     std::unordered_map< int, std::vector<cv::Scalar> > clusterColors;
+@@ -263,7 +268,8 @@ void Result::ClusterOrder(){
+     m_roi_data.clear();
+     for (std::vector<OneObjectRow>::iterator it = v.begin(); it != v.end(); ++it){
+         std::unordered_map<int, std::pair<int,cv::Scalar> >::iterator loc = translationTable.find(it->getColorClusterID());
+-        it->setColorClusterID( (loc->second).first );
++
++        if (ordering) {it->setColorClusterID( (loc->second).first );}
+         it->setClusterColor( (loc->second).second );
+         int roi = it->getROI();
+         m_roi_data.addROIClusterData(0).addCluster(it->getColorClusterID(), it->getClusterColor());
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 918a830..ec5c42c 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -1,4 +1,6 @@
+ #include "Step_ColourCluster.hpp"
++
++bool sort_by_second( const std::pair<int,int> l, const std::pair<int,int> r) { return l.second > r.second; }
+ 
+ ClusterPoint::ClusterPoint(int id, int cluster_id, bool visited, cv::Scalar color){
+     m_id = id;
+@@ -28,14 +30,17 @@ void Step_ColourCluster::updateParams(const void* src,bool was_forced){
+     m_use_this_filter = m_opts.getHasClustDist();
+     m_clustering_distance = m_opts.getClustDist();
+     m_clustering_distance_2 = m_clustering_distance*m_clustering_distance;
++    m_min_cluster_pts = m_opts.getClusteringMinPoints();
+     DEV_INFOS("Cluster Distance set to "<<m_clustering_distance);
++    DEV_INFOS("Cluster Min Pts set to "<<m_min_cluster_pts);
+ 
+ }
+ 
+ bool Step_ColourCluster::needReprocess(const void* src){
+     bool toReprocess = false;
+     toReprocess = ( m_use_this_filter != m_opts.getHasClustDist() ||
+-                     m_clustering_distance != m_opts.getClustDist() );
++                     m_clustering_distance != m_opts.getClustDist() ||
++                     m_min_cluster_pts != m_opts.getClusteringMinPoints());
+     return toReprocess;
+ }
+ 
+@@ -60,10 +65,63 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+     }
+ 
+     dbscan();
+-
+-    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+-        result.push_back(std::make_pair<int,int>( it->getID(), it->getClusterID() ));
++
++
++    //Count how many cells per cluster, make the most populated cell group cluster 1
++    //To start, just make a vector of all cluster IDs
++    std::vector<int> cluster_ids;
++    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++            cluster_ids.push_back(it->getClusterID());
++    }
++
++    //if we have clusters
++    /**if (!cluster_ids.empty()){
++        DEV_INFOS("Re-ordering them to make cluster 1 most abudant");
++        int highest_cluster_number = *std::max_element(cluster_ids.begin(), cluster_ids.end());
++        //create a vector with the length equal to number of clusters, we will stick
++        //the amount of each cluster we have in here
++        //remember we start at cluster 0, we use pairs to preserve the index (original cluster num)
++        DEV_INFOS("Make cluster counts vector with " << highest_cluster_number+1 << " elements");
++        std::vector<std::pair<int,int>> cluster_counts;
++        for (int ii=0; ii<=highest_cluster_number; ii++){
++            cluster_counts.push_back(std::pair<int,int>(ii,0));
++        }
++
++        //DEV_INFOS("Populate cluster vector");
++
++        //poulate the vector so it contains <clusterID, number_of_clusters>
++        for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++            cluster_counts[it->getClusterID()].second++;
++        }
++
++        //DEV_INFOS("Sorting Cluster Abundancies");
++        //sort by second pair element
++        std::sort(cluster_counts.begin(),cluster_counts.end(), sort_by_second);
++        for (auto it=cluster_counts.begin(); it != cluster_counts.end(); it++){
++            //DEV_INFOS("a: "<< it->first << " b: " <<it->second);
++        }
++
++        //make a map that gives map['oldID']=newID
++        std::map<int,int> cluster_map;
++        for (int ii=0; ii<=highest_cluster_number; ii++){
++            cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii));
++            //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii);
++        }
++
++        DEV_INFOS("Preparing Results Vector");
++
++        //Populate based on the map
++        //Don't forget cluster 0 = NA
++        for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++            result.push_back(std::pair<int,int>( it->getID(), cluster_map[it->getClusterID()]+1 ));
++        }
+     }
++    //We have no clusters, but we need to prepare the results vector anyway
++    else {*/
++        for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++            result.push_back(std::make_pair<int,int>( it->getID(), it->getClusterID() ));
++        }
++    //}
+ 
+ 
+     return result;
+-- 
+2.9.3
+
diff --git a/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch b/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch
new file mode 100644
index 0000000..ce96890
--- /dev/null
+++ b/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch
@@ -0,0 +1,60 @@
+From f3b12b33f92e023c073d7054dba3097b1ecc0b54 Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Fri, 13 Feb 2015 17:27:26 +0100
+Subject: [PATCH 03/11] Improved ordering of colour clusters (by quantity)
+
+Colour clusters are now ordered by quantity. This improves readability of
+the output, given only 5 colour clusters are highlighted with unique
+coloured boxes.
+
+This overwrites the previous sorting by L* intensity, the old behaviour
+can be re-enabled by changing calls to Result::ColorProcessing(ordering)
+from ordering=false to ordering=true
+---
+ src/processor/src/Result.cpp             | 2 +-
+ src/processor/src/Step_ColourCluster.cpp | 6 +++---
+ 2 files changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/src/processor/src/Result.cpp b/src/processor/src/Result.cpp
+index 1c09855..8c3c5c3 100644
+--- a/src/processor/src/Result.cpp
++++ b/src/processor/src/Result.cpp
+@@ -185,7 +185,7 @@ void Result::recluster(std::vector< std::pair<int,int> > clustered){
+             valid.push_back(true);
+     }
+     applyFilter(valid);
+-    ColorProcessing(true);
++    ColorProcessing(false);
+ }
+ 
+ /**
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index ec5c42c..71cb8fe 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -75,7 +75,7 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+     }
+ 
+     //if we have clusters
+-    /**if (!cluster_ids.empty()){
++    if (!cluster_ids.empty()){
+         DEV_INFOS("Re-ordering them to make cluster 1 most abudant");
+         int highest_cluster_number = *std::max_element(cluster_ids.begin(), cluster_ids.end());
+         //create a vector with the length equal to number of clusters, we will stick
+@@ -117,11 +117,11 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+         }
+     }
+     //We have no clusters, but we need to prepare the results vector anyway
+-    else {*/
++    else {
+         for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+             result.push_back(std::make_pair<int,int>( it->getID(), it->getClusterID() ));
+         }
+-    //}
++    }
+ 
+ 
+     return result;
+-- 
+2.9.3
+
diff --git a/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch b/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch
new file mode 100644
index 0000000..00ee748
--- /dev/null
+++ b/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch
@@ -0,0 +1,48 @@
+From 854a03c69fe3f80e0d8449bbd56f4d9df42885d5 Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Mon, 16 Feb 2015 14:05:07 +0100
+Subject: [PATCH 04/11] Counting now ignores unmatched cells
+
+Had a bug where the colonies were renumbered, including the NA colonies
+Now, NA colonies remain NA, as expected.
+---
+ src/processor/src/Step_ColourCluster.cpp | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 71cb8fe..0c4ffa1 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -94,6 +94,7 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+             cluster_counts[it->getClusterID()].second++;
+         }
+ 
++
+         //DEV_INFOS("Sorting Cluster Abundancies");
+         //sort by second pair element
+         std::sort(cluster_counts.begin(),cluster_counts.end(), sort_by_second);
+@@ -104,16 +105,19 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+         //make a map that gives map['oldID']=newID
+         std::map<int,int> cluster_map;
+         for (int ii=0; ii<=highest_cluster_number; ii++){
+-            cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii));
++            cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii+1));
+             //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii);
+         }
+ 
++        //remember to reset cluster 0 to 0, as this is NA
++        cluster_map[0]=0;
++
+         DEV_INFOS("Preparing Results Vector");
+ 
+         //Populate based on the map
+         //Don't forget cluster 0 = NA
+         for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+-            result.push_back(std::pair<int,int>( it->getID(), cluster_map[it->getClusterID()]+1 ));
++            result.push_back(std::pair<int,int>( it->getID(), cluster_map[it->getClusterID()] ));
+         }
+     }
+     //We have no clusters, but we need to prepare the results vector anyway
+-- 
+2.9.3
+
diff --git a/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch b/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch
new file mode 100644
index 0000000..ab3d931
--- /dev/null
+++ b/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch
@@ -0,0 +1,76 @@
+From 3bda769fa953a318b171697891570d049cd6662a Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Tue, 17 Feb 2015 17:18:36 +0100
+Subject: [PATCH 05/11] Changed maximum value of min_cluster_points
+
+Varying minimum cluster points lets you better constrain clusters
+sometimes. I found it useful for this value to be higher. So it is.
+---
+ src/gui/src/Gui_ColourCluster.cpp           | 2 +-
+ src/processor/headers/ProcessingOptions.hpp | 2 +-
+ src/processor/src/Step_ColourCluster.cpp    | 9 ++++++++-
+ 3 files changed, 10 insertions(+), 3 deletions(-)
+
+diff --git a/src/gui/src/Gui_ColourCluster.cpp b/src/gui/src/Gui_ColourCluster.cpp
+index 0ac5e0b..822c3e2 100644
+--- a/src/gui/src/Gui_ColourCluster.cpp
++++ b/src/gui/src/Gui_ColourCluster.cpp
+@@ -11,7 +11,7 @@ Gui_ColourCluster::Gui_ColourCluster(Gui_ProcessorHandler& processor_hand,const
+     m_spin_butt_clustering_distance(m_adjust_clustering_distance, 0.0, 1),
+     m_lab_clustering_distance(LABEL_CLUSTERING_DISTANCE),
+     //clustering members
+-    m_adjust_min_cluster_points(m_processor_hand.getOptions().getClusteringMinPoints(),4,10,1,1.0,0.0),
++    m_adjust_min_cluster_points(m_processor_hand.getOptions().getClusteringMinPoints(),4,50,1,1.0,0.0),
+     m_spin_butt_min_cluster_points(m_adjust_min_cluster_points, 0.0, 1),
+     m_lab_min_cluster_points(LABEL_CLUSTERING_POINTS),
+     //check button
+diff --git a/src/processor/headers/ProcessingOptions.hpp b/src/processor/headers/ProcessingOptions.hpp
+index e539068..2e8c67f 100644
+--- a/src/processor/headers/ProcessingOptions.hpp
++++ b/src/processor/headers/ProcessingOptions.hpp
+@@ -285,7 +285,7 @@ class ProcessingOptions
+  *  \param int clustering_min_pts Number of neighbour points necessary to be in a cluster
+  */
+         bool setClustMinPoints(const double clustering_min_pts){
+-            if (clustering_min_pts>=4 && clustering_min_pts<=10.){
++            if (clustering_min_pts>=4 && clustering_min_pts<=50.){
+                 m_clustering_min_pts = clustering_min_pts;
+                 return true;}
+             else{
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 0c4ffa1..9dfd17c 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -87,6 +87,8 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+             cluster_counts.push_back(std::pair<int,int>(ii,0));
+         }
+ 
++
++
+         //DEV_INFOS("Populate cluster vector");
+ 
+         //poulate the vector so it contains <clusterID, number_of_clusters>
+@@ -94,6 +96,9 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+             cluster_counts[it->getClusterID()].second++;
+         }
+ 
++        //Force NA cluster to be sorted last.
++        cluster_counts[0].second=0;
++
+ 
+         //DEV_INFOS("Sorting Cluster Abundancies");
+         //sort by second pair element
+@@ -109,7 +114,9 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+             //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii);
+         }
+ 
+-        //remember to reset cluster 0 to 0, as this is NA
++        //remember to reset cluster 0 to position 0, as this is NA,
++        //Just above we added one to all the other cluster numbers
++        //to leave room for this
+         cluster_map[0]=0;
+ 
+         DEV_INFOS("Preparing Results Vector");
+-- 
+2.9.3
+
diff --git a/debian/patches/0006-Bugfix-last-coloured-cluster-sometimes-wasn-t-shown.patch b/debian/patches/0006-Bugfix-last-coloured-cluster-sometimes-wasn-t-shown.patch
new file mode 100644
index 0000000..6d428c4
--- /dev/null
+++ b/debian/patches/0006-Bugfix-last-coloured-cluster-sometimes-wasn-t-shown.patch
@@ -0,0 +1,75 @@
+From b6059513fd6669acf974066b2bf20c8581658fe4 Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Mon, 2 Mar 2015 12:23:50 +0100
+Subject: [PATCH 06/11] Bugfix: last coloured cluster sometimes wasn't shown
+
+When no invalid clusters were present, the last cluster wouldn't
+display in the results view. This occured because of a counting
+error, because a loop always assumed a cluster containing invalid
+points was always present.
+
+The fix was to add an empty cluster (with id 0) to the map
+containing cluster data, in the ClusterData constructor
+
+NOTE: Remove patch for OpenCFU.cbp and OpenCFU.layout
+
+---
+ src/gui/src/Gui_ResultListDisplay.cpp |   2 +-
+ src/processor/headers/Result.hpp      |   3 +-
+ src/processor/src/Result.cpp          |   6 +-
+ 5 files changed, 49 insertions(+), 962 deletions(-)
+
+diff --git a/src/gui/src/Gui_ResultListDisplay.cpp b/src/gui/src/Gui_ResultListDisplay.cpp
+index 3800b22..e14bc7b 100644
+--- a/src/gui/src/Gui_ResultListDisplay.cpp
++++ b/src/gui/src/Gui_ResultListDisplay.cpp
+@@ -149,7 +149,7 @@ void Gui_ResultListDisplay::updateView(Glib::RefPtr<Gio::File> file, int idx){
+         row[m_col_model.m_col_n_objects] = str;
+         row[m_col_model.m_col_n_excluded] = str;
+     }
+-/**
++/*
+     if (colCluster){
+         std::stringstream ss;
+         ss << res.getROIClusterData(0).clusterPop(1);
+diff --git a/src/processor/headers/Result.hpp b/src/processor/headers/Result.hpp
+index d344fb9..ecb4d39 100644
+--- a/src/processor/headers/Result.hpp
++++ b/src/processor/headers/Result.hpp
+@@ -77,7 +77,8 @@ class OneObjectRow{
+  */
+ class ClusterData{
+     public:
+-        ClusterData(){};
++        ClusterData();
++        ~ClusterData(){};
+         void addCluster(int id, int pop, cv::Scalar col){
+             if (!m_clusters.count(id)){
+                 m_clusters.emplace( id, std::make_pair(pop, col) );
+diff --git a/src/processor/src/Result.cpp b/src/processor/src/Result.cpp
+index 8c3c5c3..8536032 100644
+--- a/src/processor/src/Result.cpp
++++ b/src/processor/src/Result.cpp
+@@ -269,7 +269,7 @@ void Result::ColorProcessing(bool ordering){
+     for (std::vector<OneObjectRow>::iterator it = v.begin(); it != v.end(); ++it){
+         std::unordered_map<int, std::pair<int,cv::Scalar> >::iterator loc = translationTable.find(it->getColorClusterID());
+ 
+-        if (ordering) {it->setColorClusterID( (loc->second).first );}
++        if (ordering) {it->setColorClusterID( (loc->second).first );} //Ordering by luminosity if requested
+         it->setClusterColor( (loc->second).second );
+         int roi = it->getROI();
+         m_roi_data.addROIClusterData(0).addCluster(it->getColorClusterID(), it->getClusterColor());
+@@ -313,6 +313,10 @@ void Result::applyGuiFilter(const cv::Mat& valid){
+ 
+ }
+ 
++ClusterData::ClusterData(){
++    this->addCluster(0, cv::Scalar(0,0,0)); //initiate with empty cluster 0
++    }
++
+ const std::string ClusterData::str() const{
+     std::stringstream ss;
+     //this makes a python-dict like output for the saved string.
+-- 
+2.9.3
+
diff --git a/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch b/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch
new file mode 100644
index 0000000..b84506f
--- /dev/null
+++ b/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch
@@ -0,0 +1,122 @@
+From 03b1754ae67bfcb641307c950030af47c47499a2 Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Thu, 12 Mar 2015 09:13:11 +0100
+Subject: [PATCH 07/11] Comman line parsing, changes to highlight colour
+
+The command line parser now accepts an argument for minimum cluster
+members (-N). I also changed the keyword character for coarseness
+(from -G to -D) as I think D better associates pnuemonically with
+density based clustering. I also wanted to make the change while
+this feature is still young, before too many people insert it into
+scripts.
+
+I changed the priority for highlight colours when automatic colour
+identification is active, to aid clarity.
+
+NOTE: Remove patch for OpenCFU.layout
+
+---
+ src/gui/src/Gui_Decorator.cpp        | 20 +++++---
+ src/processor/src/ArgumentParser.cpp | 22 +++++++--
+ 3 files changed, 87 insertions(+), 51 deletions(-)
+
+diff --git a/src/gui/src/Gui_Decorator.cpp b/src/gui/src/Gui_Decorator.cpp
+index 2d901a3..fcb916f 100644
+--- a/src/gui/src/Gui_Decorator.cpp
++++ b/src/gui/src/Gui_Decorator.cpp
+@@ -117,21 +117,25 @@ void Gui_Decorator::decorate(){
+  *Drawing each region, migrated to a functional form 4/SEP/2014
+  *****************************************************************************/
+     //clusters if present
++    //green
+     highlightCells(cr, in_cluster_one,   0.0, 1.0, 0.0, 0.8, 3.0);
+     highlightCells(cr, in_cluster_one,   0.0, 1.0, 0.0, 1.0, 1.5);
+ 
+-    highlightCells(cr, in_cluster_two,   1.0, 0.5, 0.0, 0.8, 3.0);
+-    highlightCells(cr, in_cluster_two,   1.0, 0.5, 0.0, 1.0, 1.5);
++    //teal
++    highlightCells(cr, in_cluster_two,   0.0, 1.0, 1.0, 0.8, 3.0);
++    highlightCells(cr, in_cluster_two,   0.0, 1.0, 1.0, 1.0, 1.5);
+ 
+-    highlightCells(cr, in_cluster_three, 0.0, 1.0, 1.0, 0.8, 3.0);
+-    highlightCells(cr, in_cluster_three, 0.0, 1.0, 1.0, 1.0, 1.5);
++    //purple
++    highlightCells(cr, in_cluster_three, 1.0, 0.0, 1.0, 0.8, 3.0);
++    highlightCells(cr, in_cluster_three, 1.0, 0.0, 1.0, 1.0, 1.5);
+ 
+-    highlightCells(cr, in_cluster_four,  1.0, 0.0, 1.0, 0.8, 3.0);
+-    highlightCells(cr, in_cluster_four,  1.0, 0.0, 1.0, 1.0, 1.5);
++    //orange
++    highlightCells(cr, in_cluster_four,  1.0, 0.5, 0.0, 0.8, 3.0);
++    highlightCells(cr, in_cluster_four,  1.0, 0.5, 0.0, 1.0, 1.5);
+ 
+     //valid cells not in  clusters
+-    highlightCells(cr, in_field_valid, 1.0, 1.0, 0.0, 0.8, 3.0);
+-    highlightCells(cr, in_field_valid, 0.0, 0.0, 1.0, 1.0, 1.5);
++    highlightCells(cr, in_field_valid,   1.0, 1.0, 0.0, 0.8, 3.0);
++    highlightCells(cr, in_field_valid,   0.0, 0.0, 1.0, 1.0, 1.5);
+ 
+ 
+ /******************************************************************************
+diff --git a/src/processor/src/ArgumentParser.cpp b/src/processor/src/ArgumentParser.cpp
+index 1383a58..a424f8a 100644
+--- a/src/processor/src/ArgumentParser.cpp
++++ b/src/processor/src/ArgumentParser.cpp
+@@ -20,18 +20,20 @@ m_help_string("OpenCFU options:\n\
+ -R NUM : set a maximal radius\n\
+ -c NUM : set a \"center\" value of the Hue/Colour threshold\n\
+ -C NUM : set a \"tolerance\" value of the Hue/Colour threshold\n\
+--G NUM : set a \"coarseness\" value for the density based scanner\n\
++-D NUM : set a \"coarseness\" value for the density based colour clustering scanner\n\
++-N NUM : set a \"neighbour\" requirement for the density based colour clustering scanner\n\
+ ")
+ {
+     std::stringstream tss;
+     std::pair<int,int> min_max_radius,cent_tol_hue;
+-    double clustering_distance;
++    double clustering_distance, clustering_neighbours;
+     min_max_radius = opts.getMinMaxRad();
+     cent_tol_hue = opts.getCenTolHue();
+     clustering_distance = opts.getClustDist();
++    clustering_neighbours = opts.getClusteringMinPoints();
+     signed char c=0;
+ 
+-    while ( (c = getopt (argc, argv, "hvad:i:m:r:R:c:C:t:l:o:G:")) != -1){
++    while ( (c = getopt (argc, argv, "hvad:i:m:r:R:c:C:t:l:o:G:N:")) != -1){
+         switch(c){
+             case 'h':
+                  printHelp();
+@@ -64,10 +66,14 @@ m_help_string("OpenCFU options:\n\
+                 opts.setHasHueFilt(true);
+                 cent_tol_hue.second = atoi(optarg);
+                 break;
+-            case 'G':
++            case 'D':
+                 opts.setHasClustDist(true);
+                 clustering_distance = atoi(optarg);
+                 break;
++            case 'N':
++                opts.setHasClustDist(true);
++                clustering_neighbours = atoi(optarg);
++                break;
+             case 'd':{
+                 std::string str_optarg(optarg);
+                 if(str_optarg == "reg")
+@@ -156,7 +162,13 @@ m_help_string("OpenCFU options:\n\
+ 
+     if(!opts.setClustDist(clustering_distance)){
+         std::cerr<<"ERROR setting up the clustering distance\
+-         (argument \"-G\"). Must be in range [1,50]"<<std::endl;
++         (argument \"-D\"). Must be in range [1,50]"<<std::endl;
++         exit(EXIT_FAILURE);
++    }
++
++    if(!opts.setClustMinPoints(clustering_neighbours)){
++        std::cerr<<"ERROR setting up the clustering neighbours\
++         (argument \"-N\"). Must be in range [4,50]"<<std::endl;
+          exit(EXIT_FAILURE);
+     }
+ 
+-- 
+2.9.3
+
diff --git a/debian/patches/0008-Push-final-changes-for-clustering-improvements.patch b/debian/patches/0008-Push-final-changes-for-clustering-improvements.patch
new file mode 100644
index 0000000..69bef3d
--- /dev/null
+++ b/debian/patches/0008-Push-final-changes-for-clustering-improvements.patch
@@ -0,0 +1,31 @@
+From f9ac8bf5682f25e6bd5396cf72e1049c59dbbf18 Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Wed, 27 May 2015 16:28:26 +0200
+Subject: [PATCH 08/11] Push final changes for clustering improvements
+
+What has changed:
+* Changed RGB to LAB algorithm to be more accurate
+* Can now select a minimum number of neighbouring points,
+  helps in rejecting smaller clusters
+* Added selectors and command line options for neighbouring points
+* Testing indicates that these functions all work as anticipated
+---
+ src/gui/src/Gui_ColourCluster.cpp | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/src/gui/src/Gui_ColourCluster.cpp b/src/gui/src/Gui_ColourCluster.cpp
+index 822c3e2..fddfeee 100644
+--- a/src/gui/src/Gui_ColourCluster.cpp
++++ b/src/gui/src/Gui_ColourCluster.cpp
+@@ -12,7 +12,7 @@ Gui_ColourCluster::Gui_ColourCluster(Gui_ProcessorHandler& processor_hand,const
+     m_lab_clustering_distance(LABEL_CLUSTERING_DISTANCE),
+     //clustering members
+     m_adjust_min_cluster_points(m_processor_hand.getOptions().getClusteringMinPoints(),4,50,1,1.0,0.0),
+-    m_spin_butt_min_cluster_points(m_adjust_min_cluster_points, 0.0, 1),
++    m_spin_butt_min_cluster_points(m_adjust_min_cluster_points, 0.0, 0),
+     m_lab_min_cluster_points(LABEL_CLUSTERING_POINTS),
+     //check button
+     m_check_butt(LABEL_CHECKBUTTON_HAS_CLUSTERING_DISTANCE)
+-- 
+2.9.3
+
diff --git a/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch b/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch
new file mode 100644
index 0000000..e92341e
--- /dev/null
+++ b/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch
@@ -0,0 +1,192 @@
+From 87bbe96fdbc0416351acbf6994493a2fd46aa933 Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Sun, 23 Aug 2015 19:29:29 +0100
+Subject: [PATCH 09/11] first attemps at addressing #17. Compiles, but segfault
+ at training stage
+
+---
+ src/classifier/main.cpp             | 12 +++++-
+ src/processor/headers/Predictor.hpp | 13 ++++++-
+ src/processor/src/Predictor.cpp     | 74 +++++++++++++++++++++++++++++++++----
+ 3 files changed, 89 insertions(+), 10 deletions(-)
+
+diff --git a/src/classifier/main.cpp b/src/classifier/main.cpp
+index 280cb59..8f78f77 100644
+--- a/src/classifier/main.cpp
++++ b/src/classifier/main.cpp
+@@ -33,12 +33,18 @@ int main(int argc, char **argv){
+         std::cout<<"\n~~~~~~~~~~~~~~TRAINING PREDICTOR~~~~~~~~~~~~~\n "<<std::endl;
+ 
+         DataMaker dm(TRAINING_SET_IMG,TRAINING_SET_IMG_PS);
++
+         if(argc == 3)
+             dm.makeData(features,categs);
+         else
+             dm.makeDataPS(features,categs);
++
++
++
+         my_predictor.train(features,categs);
++        return 2;
+         my_predictor.save(argv[2]);
++
+         std::cout<<"\n~~~~~~~~~~~~~~PREDICTOR TRAINED~~~~~~~~~~~~~\n "<<std::endl;
+ 
+     }
+@@ -87,7 +93,11 @@ int main(int argc, char **argv){
+         std::cout.setf(std::ios::fixed);
+         for(unsigned int i = 0; i < counts.size();i++)
+             std::cout<<"N(class =="<<revLut[i]<<") "<<counts[i]<<std::endl;
+-        std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,"CSV")<<"\n"<<std::endl;
++
++        //CV2
++        //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,"CSV")<<"\n"<<std::endl;
++        //CV3
++        std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,cv::Formatter::FMT_CSV)<<"\n"<<std::endl;
+     }
+     return 0;
+ }
+diff --git a/src/processor/headers/Predictor.hpp b/src/processor/headers/Predictor.hpp
+index 8fa9fc1..ef3c7e8 100644
+--- a/src/processor/headers/Predictor.hpp
++++ b/src/processor/headers/Predictor.hpp
+@@ -8,6 +8,7 @@
+ #include "defines.hpp"
+ #include "opencv2/imgproc/imgproc.hpp"
+ #include "opencv2/ml/ml.hpp"
++
+ class Predictor
+ {
+     public:
+@@ -20,8 +21,16 @@ class Predictor
+ 
+     protected:
+     private:
+-        CvRTrees m_trees;
+-        CvRTParams m_rt_params;
++        //CV2
++        //CvRTrees m_trees;
++        //CvRTParams m_rt_params;
++        //CV3
++        cv::Ptr<cv::ml::RTrees> m_trees;
++        // cv::ml::RTrees::create();
++        //cv::ml::RTrees::Params m_trees;
++
++
++
+ };
+ 
+ #endif // PREDICTOR_H
+diff --git a/src/processor/src/Predictor.cpp b/src/processor/src/Predictor.cpp
+index 9da5a78..eb22693 100644
+--- a/src/processor/src/Predictor.cpp
++++ b/src/processor/src/Predictor.cpp
+@@ -3,6 +3,8 @@
+ 
+ #include "opencv2/highgui/highgui.hpp"//todel
+ 
++//CV2
++/*
+ Predictor::Predictor():
+ m_rt_params(
+ 10,//maxdepth
+@@ -18,31 +20,89 @@ false,//nact_var
+ CV_TERMCRIT_EPS | CV_TERMCRIT_ITER//terminaison criteria
+ )
+ {
+-    /*Reset random seed*/
+-    *(m_trees.get_rng())= cvRNG(4);
++
++    //Reset random seed
++    //CV2
++    // *(m_trees.get_rng())= cvRNG(4);
++}
++*/
++
++
++
++//CV3
++
++Predictor::Predictor(){
++    auto m_trees = cv::ml::RTrees::create();
++    m_trees->setMaxDepth(10);
++    m_trees->setMinSampleCount(10);
++    m_trees->setRegressionAccuracy(0);
++    m_trees->setUseSurrogates(false);
++    m_trees->setMaxCategories(3);
++    //m_trees->setPriors(0); //0
++    m_trees->setCalculateVarImportance(true);
++    m_trees->setActiveVarCount(false);
++
++
++
++    m_trees->setTermCriteria({      cv::TermCriteria::MAX_ITER +
++                                    cv::TermCriteria::EPS,
++                                    100, 0.1
++                                    });
++
++
++    // *(m_trees.get_rng())= cvRNG(4);
+ }
+ 
+ void Predictor::loadTrainData(const std::string& str){
+-    m_trees.load(str.c_str());
++    //CV2
++    //m_trees.load(str.c_str())
++    //CV3
++    //m_trees->load(str.c_str())
++    cv::Ptr<cv::ml::RTrees> m_trees = cv::ml::StatModel::load<cv::ml::RTrees>(str.c_str());
+ }
+ 
+ void Predictor::save(const std::string& str){
+-    m_trees.save(str.c_str());
++    //CV2
++    //m_trees.save(str.c_str());
++    //CV3
++    auto fs =  cv::FileStorage(str, cv::FileStorage::WRITE);
++    m_trees->write(fs);
++
+ }
+ 
+ void Predictor::train(const cv::Mat& features, const std::vector<signed char>& categs){
+     cv::Mat categ_mat(categs.size(),1,CV_32S);
+     for(int i = 0; i < categ_mat.rows;i++)
+         categ_mat.at<long>(cv::Point(0,i)) = categs[i];
+-    m_trees.train(features,CV_ROW_SAMPLE,categ_mat,cv::Mat(),cv::Mat(),cv::Mat(),cv::Mat(),m_rt_params);
+-    DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
++    //CV2
++    //m_trees.train(features,CV_ROW_SAMPLE,categ_mat,cv::Mat(),cv::Mat(),cv::Mat(),cv::Mat(),m_rt_params);
++
++    //CV3
++    //cv::Ptr<cv::ml::TrainData> data = cv::ml::TrainData::create(features, cv::ml::ROW_SAMPLE, categ_mat);
++    //m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
++
++    //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(categs,cv::Formatter::FMT_CSV)<<"\n"<<std::endl;
++    return;
++    m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
++
++    //DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
++
++    //CV2
++    //DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
++
++    //CV3
++    //DEV_INFOS("Variable Importance:\n"<<m_trees->getVarImportance()<<std::endl);
++
+ }
+ 
+ void Predictor::predict(const cv::Mat& in, std::vector<signed char>& out){
+     out.clear();
+     out.reserve(in.rows);
+     for(int i = 0; i < in.rows;i++){
+-        signed char cat = m_trees.predict(in.row(i));
++        //CV2
++        //signed char cat = m_trees.predict(in.row(i));
++        //CV3
++        signed char cat = m_trees->predict(in.row(i));
+         out.push_back(cat) ;
+     }
+ }
+-- 
+2.9.3
+
diff --git a/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch b/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch
new file mode 100644
index 0000000..2800971
--- /dev/null
+++ b/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch
@@ -0,0 +1,70 @@
+From cb8af1a9c9fbf2dfc087c9aad263cbf146dbd5fa Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Mon, 22 Feb 2016 17:29:29 +0000
+Subject: [PATCH 10/11] improve compat with cv3, worked on RF
+
+---
+ src/processor/src/Predictor.cpp | 17 +++++++++++++----
+ 1 file changed, 13 insertions(+), 4 deletions(-)
+
+diff --git a/src/processor/src/Predictor.cpp b/src/processor/src/Predictor.cpp
+index eb22693..9034251 100644
+--- a/src/processor/src/Predictor.cpp
++++ b/src/processor/src/Predictor.cpp
+@@ -32,7 +32,7 @@ CV_TERMCRIT_EPS | CV_TERMCRIT_ITER//terminaison criteria
+ //CV3
+ 
+ Predictor::Predictor(){
+-    auto m_trees = cv::ml::RTrees::create();
++    m_trees = cv::ml::RTrees::create();
+     m_trees->setMaxDepth(10);
+     m_trees->setMinSampleCount(10);
+     m_trees->setRegressionAccuracy(0);
+@@ -57,8 +57,7 @@ void Predictor::loadTrainData(const std::string& str){
+     //CV2
+     //m_trees.load(str.c_str())
+     //CV3
+-    //m_trees->load(str.c_str())
+-    cv::Ptr<cv::ml::RTrees> m_trees = cv::ml::StatModel::load<cv::ml::RTrees>(str.c_str());
++    m_trees = cv::ml::StatModel::load<cv::ml::RTrees> ("/home/quentin/comput/opencfu-git/src/classifier/trainnedClassifier.xml");
+ }
+ 
+ void Predictor::save(const std::string& str){
+@@ -82,9 +81,10 @@ void Predictor::train(const cv::Mat& features, const std::vector<signed char>& c
+     //m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
+ 
+     //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(categs,cv::Formatter::FMT_CSV)<<"\n"<<std::endl;
+-    return;
++
+     m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
+ 
++
+     //DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
+ 
+     //CV2
+@@ -96,13 +96,22 @@ void Predictor::train(const cv::Mat& features, const std::vector<signed char>& c
+ }
+ 
+ void Predictor::predict(const cv::Mat& in, std::vector<signed char>& out){
++
+     out.clear();
+     out.reserve(in.rows);
++
++    //cv::FileStorage read("/home/quentin/comput/opencfu-git/src/classifier/trainnedClassifier.xml", cv::FileStorage::READ);
++    //DEV_INFOS("b");
++
++
++
++    DEV_INFOS("a");
+     for(int i = 0; i < in.rows;i++){
+         //CV2
+         //signed char cat = m_trees.predict(in.row(i));
+         //CV3
+         signed char cat = m_trees->predict(in.row(i));
++
+         out.push_back(cat) ;
+     }
+ }
+-- 
+2.9.3
+
diff --git a/debian/patches/0011-classifier-now-compatible-with-cv3.patch b/debian/patches/0011-classifier-now-compatible-with-cv3.patch
new file mode 100644
index 0000000..4ff3722
--- /dev/null
+++ b/debian/patches/0011-classifier-now-compatible-with-cv3.patch
@@ -0,0 +1,309 @@
+From edecbbd6fa13304b6f6a39efd49426c22c164786 Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Mon, 22 Feb 2016 19:25:29 +0000
+Subject: [PATCH 11/11] classifier now compatible with cv3
+
+---
+ src/classifier/main.cpp                  | 48 +++++++++++++++------
+ src/processor/headers/Predictor.hpp      | 11 +++--
+ src/processor/src/Predictor.cpp          | 73 +++++++++++---------------------
+ src/processor/src/Step_ColourCluster.cpp |  7 ++-
+ 4 files changed, 69 insertions(+), 70 deletions(-)
+
+diff --git a/src/classifier/main.cpp b/src/classifier/main.cpp
+index 8f78f77..3257174 100644
+--- a/src/classifier/main.cpp
++++ b/src/classifier/main.cpp
+@@ -22,6 +22,7 @@
+ #include "defines.hpp"
+ 
+ int main(int argc, char **argv){
++
+     Predictor my_predictor;
+     std::vector<signed char> categs;
+     cv::Mat features;
+@@ -42,11 +43,20 @@ int main(int argc, char **argv){
+ 
+ 
+         my_predictor.train(features,categs);
+-        return 2;
++
+         my_predictor.save(argv[2]);
+ 
+         std::cout<<"\n~~~~~~~~~~~~~~PREDICTOR TRAINED~~~~~~~~~~~~~\n "<<std::endl;
++        std::vector<signed char> pred;
++        DEV_INFOS("Trying to predict...");
++        my_predictor.predict(features,pred);
++        DEV_INFOS("OK");
+ 
++        DEV_INFOS("Trying to load and predict...");
++        Predictor my_predictor2;
++        my_predictor2.loadTrainData("/tmp/test.xml");
++        my_predictor2.predict(features,pred);
++        DEV_INFOS("done");
+     }
+     /*Else, if the program is called to validate the training*/
+     else{
+@@ -56,10 +66,13 @@ int main(int argc, char **argv){
+         else
+             dm.makeDataPS(features,categs);
+ 
++        DEV_INFOS("----------------");
+         my_predictor.loadTrainData(argv[2]);
+-
++        DEV_INFOS("----------------");
+         std::vector<signed char> pred;
++        DEV_INFOS("predicting...");
+         my_predictor.predict(features,pred);
++        DEV_INFOS("predicted");
+         int n_false(0);
+         cv::Mat m_mat(3,3,CV_32F,cv::Scalar(0));
+         std::map<char,int> lut;
+@@ -70,21 +83,26 @@ int main(int argc, char **argv){
+         std::vector<int> counts(3,0);
+ 
+         for(unsigned int i = 0; i<pred.size(); i++){
++
+             char p =pred[i];
+             char r =categs[i];
+-            int real = lut[r];
+-            int pred = lut[p];
+-            counts[real] +=1;
+-
+-            if(real != pred){
++            int real_int = lut[r];
++            int pred_int = lut[p];
++            counts[real_int] +=1;
++        //DEV_INFOS(real_int<<" "<< pred_int);
++            if(real_int != pred_int){
+                 n_false++;
+             }
+-            m_mat.at<float>(pred,real) = m_mat.at<float>(pred,real) + 1;
++            m_mat.at<float>(pred_int,real_int) = m_mat.at<float>(pred_int,real_int) + 1;
+         }
+-        cv::Mat sum_cols;
++
++
++
++        cv::Mat sum_cols, sum_mat;
+         cv::reduce(m_mat, sum_cols, 0, CV_REDUCE_SUM);
+-        cv::repeat(sum_cols, 3, 1, sum_cols);
+-        m_mat = 100*m_mat/sum_cols;
++        cv::repeat(sum_cols, 3, 1, sum_mat);
++        m_mat = (100*m_mat)/sum_mat;
++
+         float accur = 1 - ((float) n_false/(float) pred.size());
+         std::cout<<"\n~~~~~~~~~~~~~~ASSESSING ACCURACY OF THE PREDICTOR~~~~~~~~~~~~~\n "<<std::endl;
+         std::cout<<"ACCURACY = "<<accur<<std::endl;
+@@ -94,10 +112,12 @@ int main(int argc, char **argv){
+         for(unsigned int i = 0; i < counts.size();i++)
+             std::cout<<"N(class =="<<revLut[i]<<") "<<counts[i]<<std::endl;
+ 
+-        //CV2
+-        //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,"CSV")<<"\n"<<std::endl;
+-        //CV3
++
++        #if CV_MAJOR_VERSION < 3
++        std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,"CSV")<<"\n"<<std::endl;
++        #else
+         std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(m_mat,cv::Formatter::FMT_CSV)<<"\n"<<std::endl;
++        #endif
+     }
+     return 0;
+ }
+diff --git a/src/processor/headers/Predictor.hpp b/src/processor/headers/Predictor.hpp
+index ef3c7e8..93c0826 100644
+--- a/src/processor/headers/Predictor.hpp
++++ b/src/processor/headers/Predictor.hpp
+@@ -21,13 +21,12 @@ class Predictor
+ 
+     protected:
+     private:
+-        //CV2
+-        //CvRTrees m_trees;
+-        //CvRTParams m_rt_params;
+-        //CV3
++        #if CV_MAJOR_VERSION < 3
++        CvRTrees m_trees;
++        CvRTParams m_rt_params;
++        #else
+         cv::Ptr<cv::ml::RTrees> m_trees;
+-        // cv::ml::RTrees::create();
+-        //cv::ml::RTrees::Params m_trees;
++        #endif // CV_MAJOR_VERSION
+ 
+ 
+ 
+diff --git a/src/processor/src/Predictor.cpp b/src/processor/src/Predictor.cpp
+index 9034251..e06a68e 100644
+--- a/src/processor/src/Predictor.cpp
++++ b/src/processor/src/Predictor.cpp
+@@ -1,10 +1,10 @@
+ #include "Predictor.hpp"
+-
++#include <stdlib.h>
+ 
+ #include "opencv2/highgui/highgui.hpp"//todel
+ 
+-//CV2
+-/*
++
++#if CV_MAJOR_VERSION < 3
+ Predictor::Predictor():
+ m_rt_params(
+ 10,//maxdepth
+@@ -20,17 +20,11 @@ false,//nact_var
+ CV_TERMCRIT_EPS | CV_TERMCRIT_ITER//terminaison criteria
+ )
+ {
+-
+     //Reset random seed
+-    //CV2
+-    // *(m_trees.get_rng())= cvRNG(4);
++    *(m_trees.get_rng())= cvRNG(4);
+ }
+-*/
+-
+-
+-
+-//CV3
+ 
++#else
+ Predictor::Predictor(){
+     m_trees = cv::ml::RTrees::create();
+     m_trees->setMaxDepth(10);
+@@ -38,6 +32,7 @@ Predictor::Predictor(){
+     m_trees->setRegressionAccuracy(0);
+     m_trees->setUseSurrogates(false);
+     m_trees->setMaxCategories(3);
++
+     //m_trees->setPriors(0); //0
+     m_trees->setCalculateVarImportance(true);
+     m_trees->setActiveVarCount(false);
+@@ -46,26 +41,28 @@ Predictor::Predictor(){
+ 
+     m_trees->setTermCriteria({      cv::TermCriteria::MAX_ITER +
+                                     cv::TermCriteria::EPS,
+-                                    100, 0.1
++                                    100, 0.01
+                                     });
+ 
+ 
+     // *(m_trees.get_rng())= cvRNG(4);
+ }
++#endif // CV_MAJOR_VERSION
+ 
+ void Predictor::loadTrainData(const std::string& str){
+-    //CV2
+-    //m_trees.load(str.c_str())
+-    //CV3
+-    m_trees = cv::ml::StatModel::load<cv::ml::RTrees> ("/home/quentin/comput/opencfu-git/src/classifier/trainnedClassifier.xml");
++    #if CV_MAJOR_VERSION < 3
++    m_trees.load(str.c_str())
++    #else
++    m_trees = cv::ml::StatModel::load<cv::ml::RTrees> (str);
++    #endif // CV_MAJOR_VERSION
+ }
+ 
+ void Predictor::save(const std::string& str){
+-    //CV2
+-    //m_trees.save(str.c_str());
+-    //CV3
+-    auto fs =  cv::FileStorage(str, cv::FileStorage::WRITE);
+-    m_trees->write(fs);
++    #if CV_MAJOR_VERSION < 3
++    m_trees.save(str.c_str());
++    #else
++    m_trees->save(str);
++    #endif
+ 
+ }
+ 
+@@ -73,25 +70,11 @@ void Predictor::train(const cv::Mat& features, const std::vector<signed char>& c
+     cv::Mat categ_mat(categs.size(),1,CV_32S);
+     for(int i = 0; i < categ_mat.rows;i++)
+         categ_mat.at<long>(cv::Point(0,i)) = categs[i];
+-    //CV2
+-    //m_trees.train(features,CV_ROW_SAMPLE,categ_mat,cv::Mat(),cv::Mat(),cv::Mat(),cv::Mat(),m_rt_params);
+-
+-    //CV3
+-    //cv::Ptr<cv::ml::TrainData> data = cv::ml::TrainData::create(features, cv::ml::ROW_SAMPLE, categ_mat);
+-    //m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
+-
+-    //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<<cv::format(categs,cv::Formatter::FMT_CSV)<<"\n"<<std::endl;
+-
++    #if CV_MAJOR_VERSION < 3
++    m_trees.train(features,CV_ROW_SAMPLE,categ_mat,cv::Mat(),cv::Mat(),cv::Mat(),cv::Mat(),m_rt_params);
++    #else
+     m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat);
+-
+-
+-    //DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
+-
+-    //CV2
+-    //DEV_INFOS("Variable Importance:\n"<<m_trees.getVarImportance()<<std::endl);
+-
+-    //CV3
+-    //DEV_INFOS("Variable Importance:\n"<<m_trees->getVarImportance()<<std::endl);
++    #endif // CV_MAJOR_VERSION
+ 
+ }
+ 
+@@ -100,18 +83,12 @@ void Predictor::predict(const cv::Mat& in, std::vector<signed char>& out){
+     out.clear();
+     out.reserve(in.rows);
+ 
+-    //cv::FileStorage read("/home/quentin/comput/opencfu-git/src/classifier/trainnedClassifier.xml", cv::FileStorage::READ);
+-    //DEV_INFOS("b");
+-
+-
+-
+-    DEV_INFOS("a");
+     for(int i = 0; i < in.rows;i++){
+-        //CV2
++        #if CV_MAJOR_VERSION < 3
+         //signed char cat = m_trees.predict(in.row(i));
+-        //CV3
++        #else
+         signed char cat = m_trees->predict(in.row(i));
+-
++        #endif
+         out.push_back(cat) ;
+     }
+ }
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 9dfd17c..7ab016f 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -52,6 +52,8 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+ 
+ 
+     std::vector< std::pair<int,int> > result;
++
++
+     m_cluster_vector.clear();
+     for(unsigned int ii = 0; ii < in_numerical_result.size(); ii++){
+         const OneObjectRow& oor = in_numerical_result.getRow(ii);
+@@ -65,7 +67,7 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+     }
+ 
+     dbscan();
+-
++    /*
+ 
+     //Count how many cells per cluster, make the most populated cell group cluster 1
+     //To start, just make a vector of all cluster IDs
+@@ -134,8 +136,9 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+         }
+     }
+ 
++        */
++    return result;
+ 
+-    return result;
+ }
+ 
+ /**
+-- 
+2.9.3
+
diff --git a/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch b/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch
new file mode 100644
index 0000000..9d9209b
--- /dev/null
+++ b/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch
@@ -0,0 +1,40 @@
+From b56df8b63c1b63248432b0caab588fa50ac3539e Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Mon, 22 Feb 2016 19:33:44 +0000
+Subject: [PATCH 12/16] add explicit linking to std map in colour clusters
+
+---
+ src/processor/src/Step_ColourCluster.cpp | 5 +++--
+ 1 file changed, 3 insertions(+), 2 deletions(-)
+
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 7ab016f..6e01c5f 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -1,4 +1,5 @@
+ #include "Step_ColourCluster.hpp"
++#include <map>
+ 
+ bool sort_by_second( const std::pair<int,int> l, const std::pair<int,int> r) { return l.second > r.second; }
+ 
+@@ -67,7 +68,7 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+     }
+ 
+     dbscan();
+-    /*
++
+ 
+     //Count how many cells per cluster, make the most populated cell group cluster 1
+     //To start, just make a vector of all cluster IDs
+@@ -136,7 +137,7 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+         }
+     }
+ 
+-        */
++
+     return result;
+ 
+ }
+-- 
+2.9.3
+
diff --git a/debian/patches/0013-fixes-17.patch b/debian/patches/0013-fixes-17.patch
new file mode 100644
index 0000000..7e3dc6e
--- /dev/null
+++ b/debian/patches/0013-fixes-17.patch
@@ -0,0 +1,56 @@
+From 82e4f786969a46412350da9d9a299362192a8cae Mon Sep 17 00:00:00 2001
+From: Quentin Geissmann <qgeissmann at gmail.com>
+Date: Mon, 22 Feb 2016 19:41:40 +0000
+Subject: [PATCH 13/16] fixes #17
+
+---
+ src/classifier/main.cpp         | 10 ----------
+ src/processor/src/Predictor.cpp |  4 ++--
+ 2 files changed, 2 insertions(+), 12 deletions(-)
+
+diff --git a/src/classifier/main.cpp b/src/classifier/main.cpp
+index 3257174..45f5311 100644
+--- a/src/classifier/main.cpp
++++ b/src/classifier/main.cpp
+@@ -47,16 +47,6 @@ int main(int argc, char **argv){
+         my_predictor.save(argv[2]);
+ 
+         std::cout<<"\n~~~~~~~~~~~~~~PREDICTOR TRAINED~~~~~~~~~~~~~\n "<<std::endl;
+-        std::vector<signed char> pred;
+-        DEV_INFOS("Trying to predict...");
+-        my_predictor.predict(features,pred);
+-        DEV_INFOS("OK");
+-
+-        DEV_INFOS("Trying to load and predict...");
+-        Predictor my_predictor2;
+-        my_predictor2.loadTrainData("/tmp/test.xml");
+-        my_predictor2.predict(features,pred);
+-        DEV_INFOS("done");
+     }
+     /*Else, if the program is called to validate the training*/
+     else{
+diff --git a/src/processor/src/Predictor.cpp b/src/processor/src/Predictor.cpp
+index e06a68e..35b88e2 100644
+--- a/src/processor/src/Predictor.cpp
++++ b/src/processor/src/Predictor.cpp
+@@ -51,7 +51,7 @@ Predictor::Predictor(){
+ 
+ void Predictor::loadTrainData(const std::string& str){
+     #if CV_MAJOR_VERSION < 3
+-    m_trees.load(str.c_str())
++    m_trees.load(str.c_str());
+     #else
+     m_trees = cv::ml::StatModel::load<cv::ml::RTrees> (str);
+     #endif // CV_MAJOR_VERSION
+@@ -85,7 +85,7 @@ void Predictor::predict(const cv::Mat& in, std::vector<signed char>& out){
+ 
+     for(int i = 0; i < in.rows;i++){
+         #if CV_MAJOR_VERSION < 3
+-        //signed char cat = m_trees.predict(in.row(i));
++        signed char cat = m_trees.predict(in.row(i));
+         #else
+         signed char cat = m_trees->predict(in.row(i));
+         #endif
+-- 
+2.9.3
+
diff --git a/debian/patches/0014-Update-Colour-difference-formula.patch b/debian/patches/0014-Update-Colour-difference-formula.patch
new file mode 100644
index 0000000..88fe15d
--- /dev/null
+++ b/debian/patches/0014-Update-Colour-difference-formula.patch
@@ -0,0 +1,359 @@
+From 8f6499e575cf87648bbaccb51da9bbda742587ff Mon Sep 17 00:00:00 2001
+From: Nathanael Lampe <nathanael at natlampe.com>
+Date: Fri, 13 May 2016 21:10:51 +0200
+Subject: [PATCH 14/16] Update Colour difference formula
+
+Forgot to square the L coefficient
+---
+ src/processor/src/Step_ColourCluster.cpp | 269 ++++++++++++++++---------------
+ 1 file changed, 135 insertions(+), 134 deletions(-)
+
+diff --git a/src/processor/src/Step_ColourCluster.cpp b/src/processor/src/Step_ColourCluster.cpp
+index 6e01c5f..3ca6389 100644
+--- a/src/processor/src/Step_ColourCluster.cpp
++++ b/src/processor/src/Step_ColourCluster.cpp
+@@ -1,62 +1,62 @@
+-#include "Step_ColourCluster.hpp"
+-#include <map>
+-
+-bool sort_by_second( const std::pair<int,int> l, const std::pair<int,int> r) { return l.second > r.second; }
++#include "Step_ColourCluster.hpp"
++#include <map>
++
++bool sort_by_second( const std::pair<int,int> l, const std::pair<int,int> r) { return l.second > r.second; }
+ 
+ ClusterPoint::ClusterPoint(int id, int cluster_id, bool visited, cv::Scalar color){
+     m_id = id;
+     m_cluster_id = cluster_id;
+     m_visited = visited;
+     m_color = color;
+-}
+-
+-void Step_ColourCluster::process(const void* src){
+-    const Result& in_numerical_result(*((Result*)(src)));
+-    if(!m_use_this_filter){
+-        m_step_numerical_result = in_numerical_result;
+-        DEV_INFOS("Unclustering");
+-        m_step_numerical_result.uncluster();
+-    }
+-    else{
+-        DEV_INFOS("Reclustering");
+-        m_step_numerical_result = in_numerical_result;
+-        m_step_numerical_result.uncluster();
+-        m_step_numerical_result.recluster(cluster(in_numerical_result));
+-    }
+-    m_step_result = ((void*) &m_step_numerical_result);
+-}
+-
+-
+-void Step_ColourCluster::updateParams(const void* src,bool was_forced){
+-    m_use_this_filter = m_opts.getHasClustDist();
++}
++
++void Step_ColourCluster::process(const void* src){
++    const Result& in_numerical_result(*((Result*)(src)));
++    if(!m_use_this_filter){
++        m_step_numerical_result = in_numerical_result;
++        DEV_INFOS("Unclustering");
++        m_step_numerical_result.uncluster();
++    }
++    else{
++        DEV_INFOS("Reclustering");
++        m_step_numerical_result = in_numerical_result;
++        m_step_numerical_result.uncluster();
++        m_step_numerical_result.recluster(cluster(in_numerical_result));
++    }
++    m_step_result = ((void*) &m_step_numerical_result);
++}
++
++
++void Step_ColourCluster::updateParams(const void* src,bool was_forced){
++    m_use_this_filter = m_opts.getHasClustDist();
+     m_clustering_distance = m_opts.getClustDist();
+-    m_clustering_distance_2 = m_clustering_distance*m_clustering_distance;
+-    m_min_cluster_pts = m_opts.getClusteringMinPoints();
+-    DEV_INFOS("Cluster Distance set to "<<m_clustering_distance);
+-    DEV_INFOS("Cluster Min Pts set to "<<m_min_cluster_pts);
+-
+-}
+-
+-bool Step_ColourCluster::needReprocess(const void* src){
+-    bool toReprocess = false;
+-    toReprocess = ( m_use_this_filter != m_opts.getHasClustDist() ||
+-                     m_clustering_distance != m_opts.getClustDist() ||
+-                     m_min_cluster_pts != m_opts.getClusteringMinPoints());
+-    return toReprocess;
+-}
+-
+-
+-/**
+- *
+- */
+-std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_numerical_result){
+-
+-
+-    std::vector< std::pair<int,int> > result;
+-
+-
+-    m_cluster_vector.clear();
+-    for(unsigned int ii = 0; ii < in_numerical_result.size(); ii++){
++    m_clustering_distance_2 = m_clustering_distance*m_clustering_distance;
++    m_min_cluster_pts = m_opts.getClusteringMinPoints();
++    DEV_INFOS("Cluster Distance set to "<<m_clustering_distance);
++    DEV_INFOS("Cluster Min Pts set to "<<m_min_cluster_pts);
++
++}
++
++bool Step_ColourCluster::needReprocess(const void* src){
++    bool toReprocess = false;
++    toReprocess = ( m_use_this_filter != m_opts.getHasClustDist() ||
++                     m_clustering_distance != m_opts.getClustDist() ||
++                     m_min_cluster_pts != m_opts.getClusteringMinPoints());
++    return toReprocess;
++}
++
++
++/**
++ *
++ */
++std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_numerical_result){
++
++
++    std::vector< std::pair<int,int> > result;
++
++
++    m_cluster_vector.clear();
++    for(unsigned int ii = 0; ii < in_numerical_result.size(); ii++){
+         const OneObjectRow& oor = in_numerical_result.getRow(ii);
+         //populate the list of valid items with LAB color mean, ID and the cluster state
+         if ( oor.isValid() || (oor.getGUIValid() == 1) ){
+@@ -66,96 +66,96 @@ std::vector< std::pair<int,int> > Step_ColourCluster::cluster(const Result& in_n
+             result.push_back( std::make_pair<int,int>( ii, 0 ) );
+         }
+     }
+-
+-    dbscan();
+-
+-
+-    //Count how many cells per cluster, make the most populated cell group cluster 1
+-    //To start, just make a vector of all cluster IDs
+-    std::vector<int> cluster_ids;
+-    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++
++    dbscan();
++
++
++    //Count how many cells per cluster, make the most populated cell group cluster 1
++    //To start, just make a vector of all cluster IDs
++    std::vector<int> cluster_ids;
++    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+             cluster_ids.push_back(it->getClusterID());
+-    }
+-
+-    //if we have clusters
+-    if (!cluster_ids.empty()){
+-        DEV_INFOS("Re-ordering them to make cluster 1 most abudant");
+-        int highest_cluster_number = *std::max_element(cluster_ids.begin(), cluster_ids.end());
+-        //create a vector with the length equal to number of clusters, we will stick
+-        //the amount of each cluster we have in here
+-        //remember we start at cluster 0, we use pairs to preserve the index (original cluster num)
+-        DEV_INFOS("Make cluster counts vector with " << highest_cluster_number+1 << " elements");
+-        std::vector<std::pair<int,int>> cluster_counts;
+-        for (int ii=0; ii<=highest_cluster_number; ii++){
+-            cluster_counts.push_back(std::pair<int,int>(ii,0));
+-        }
+-
+-
+-
+-        //DEV_INFOS("Populate cluster vector");
+-
+-        //poulate the vector so it contains <clusterID, number_of_clusters>
+-        for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+-            cluster_counts[it->getClusterID()].second++;
+-        }
+-
+-        //Force NA cluster to be sorted last.
+-        cluster_counts[0].second=0;
+-
+-
+-        //DEV_INFOS("Sorting Cluster Abundancies");
+-        //sort by second pair element
+-        std::sort(cluster_counts.begin(),cluster_counts.end(), sort_by_second);
+-        for (auto it=cluster_counts.begin(); it != cluster_counts.end(); it++){
+-            //DEV_INFOS("a: "<< it->first << " b: " <<it->second);
+-        }
+-
+-        //make a map that gives map['oldID']=newID
+-        std::map<int,int> cluster_map;
+-        for (int ii=0; ii<=highest_cluster_number; ii++){
+-            cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii+1));
+-            //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii);
+-        }
+-
+-        //remember to reset cluster 0 to position 0, as this is NA,
+-        //Just above we added one to all the other cluster numbers
+-        //to leave room for this
+-        cluster_map[0]=0;
+-
+-        DEV_INFOS("Preparing Results Vector");
+-
+-        //Populate based on the map
+-        //Don't forget cluster 0 = NA
++    }
++
++    //if we have clusters
++    if (!cluster_ids.empty()){
++        DEV_INFOS("Re-ordering them to make cluster 1 most abudant");
++        int highest_cluster_number = *std::max_element(cluster_ids.begin(), cluster_ids.end());
++        //create a vector with the length equal to number of clusters, we will stick
++        //the amount of each cluster we have in here
++        //remember we start at cluster 0, we use pairs to preserve the index (original cluster num)
++        DEV_INFOS("Make cluster counts vector with " << highest_cluster_number+1 << " elements");
++        std::vector<std::pair<int,int>> cluster_counts;
++        for (int ii=0; ii<=highest_cluster_number; ii++){
++            cluster_counts.push_back(std::pair<int,int>(ii,0));
++        }
++
++
++
++        //DEV_INFOS("Populate cluster vector");
++
++        //poulate the vector so it contains <clusterID, number_of_clusters>
++        for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++            cluster_counts[it->getClusterID()].second++;
++        }
++
++        //Force NA cluster to be sorted last.
++        cluster_counts[0].second=0;
++
++
++        //DEV_INFOS("Sorting Cluster Abundancies");
++        //sort by second pair element
++        std::sort(cluster_counts.begin(),cluster_counts.end(), sort_by_second);
++        for (auto it=cluster_counts.begin(); it != cluster_counts.end(); it++){
++            //DEV_INFOS("a: "<< it->first << " b: " <<it->second);
++        }
++
++        //make a map that gives map['oldID']=newID
++        std::map<int,int> cluster_map;
++        for (int ii=0; ii<=highest_cluster_number; ii++){
++            cluster_map.insert( std::pair<int,int>(cluster_counts[ii].first, ii+1));
++            //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<<ii);
++        }
++
++        //remember to reset cluster 0 to position 0, as this is NA,
++        //Just above we added one to all the other cluster numbers
++        //to leave room for this
++        cluster_map[0]=0;
++
++        DEV_INFOS("Preparing Results Vector");
++
++        //Populate based on the map
++        //Don't forget cluster 0 = NA
+         for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+             result.push_back(std::pair<int,int>( it->getID(), cluster_map[it->getClusterID()] ));
+-        }
+-    }
+-    //We have no clusters, but we need to prepare the results vector anyway
+-    else {
++        }
++    }
++    //We have no clusters, but we need to prepare the results vector anyway
++    else {
+         for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+             result.push_back(std::make_pair<int,int>( it->getID(), it->getClusterID() ));
+-        }
+-    }
++        }
++    }
+ 
+ 
+-    return result;
++    return result;
+ 
+ }
+ 
+ /**
+  *
+  */
+-void Step_ColourCluster::dbscan(){
++void Step_ColourCluster::dbscan(){
+     DEV_INFOS("Launching density scanner on "<<m_cluster_vector.size()<<" entries");
+-    m_current_cluster = 0;
+-
+-    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++    m_current_cluster = 0;
++
++    for (std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+ 
+     //for(unsigned ii = 0; ii < m_cluster_vector.size(); ++ii){
+         //only execute the scan if the element has not been visited
+         if (!it->getVisited()){
+ 
+-            it->setVisited(true);
++            it->setVisited(true);
+             //DEV_INFOS("Point " + std::to_string(ii) + " visited");
+ 
+             std::vector<std::vector<ClusterPoint>::iterator> local_neighbours = Step_ColourCluster::findNeighbours( *it );
+@@ -169,7 +169,7 @@ void Step_ColourCluster::dbscan(){
+             }
+         }
+     }
+-}
++}
+ 
+ /**
+  *
+@@ -179,14 +179,15 @@ std::vector<std::vector<ClusterPoint>::iterator> Step_ColourCluster::findNeighbo
+     double colorA1 = searchPoint.getColor()[1];
+     double colorB1 = searchPoint.getColor()[2];
+     std::vector<std::vector<ClusterPoint>::iterator> local_neighbours;
+-    for(std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
+-
++    for(std::vector<ClusterPoint>::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){
++        // CIE76 Colour difference
++        // Note:0.153787=(100/255)^2 because open CV stores and 8 bit int when the value is in [0,100]
+         double colorL2 = it->getColor()[0];
+         double colorA2 = it->getColor()[1];
+         double colorB2 = it->getColor()[2];
+-        double sum = (colorL1-colorL2)*(colorL1-colorL2)*0.392157; //0.392157=100/255 because open CV stores and 8 bit int when the value is in [0,100]
++        double sum = (colorL1-colorL2)*(colorL1-colorL2)*0.153787;
+         sum += (colorA1-colorA2)*(colorA1-colorA2);
+-        sum += (colorB1-colorB2)*(colorB1-colorB2);
++        sum += (colorB1-colorB2)*(colorB1-colorB2);
+ 
+         if (sum<m_clustering_distance_2){
+             local_neighbours.push_back( it );
+@@ -202,7 +203,7 @@ void Step_ColourCluster::expandCluster(ClusterPoint expandPoint){
+     expandPoint.setClusterID(m_current_cluster);
+     std::vector<std::vector<ClusterPoint>::iterator>  local_neighbours = findNeighbours(expandPoint);
+     while (local_neighbours.size() >= 1){
+-        std::vector<ClusterPoint>::iterator neighbour = local_neighbours.front();
++        std::vector<ClusterPoint>::iterator neighbour = local_neighbours.front();
+ 
+         if (neighbour->getVisited() == false){
+             neighbour->setVisited(true);
+@@ -211,9 +212,9 @@ void Step_ColourCluster::expandCluster(ClusterPoint expandPoint){
+                 for (unsigned kk = 0; kk < new_neighbours.size(); ++kk){
+                     if (!new_neighbours[kk]->getVisited()){
+                         local_neighbours.push_back(new_neighbours[kk]);
+-                    }
+-                    else if (new_neighbours[kk]->getClusterID() <= 0){        // The else if block catches visited, unlabelled points
+-                        new_neighbours[kk]->setClusterID(m_current_cluster);  // It means we don't have to add all the points into
++                    }
++                    else if (new_neighbours[kk]->getClusterID() <= 0){        // The else if block catches visited, unlabelled points
++                        new_neighbours[kk]->setClusterID(m_current_cluster);  // It means we don't have to add all the points into
+                     }                                                         // the neighbours list
+                 }
+             }
+@@ -222,5 +223,5 @@ void Step_ColourCluster::expandCluster(ClusterPoint expandPoint){
+             neighbour->setClusterID(m_current_cluster);
+         }
+         local_neighbours.erase(local_neighbours.begin());
+-    }
+-};
++    }
++};
+-- 
+2.9.3
+
diff --git a/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch b/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch
new file mode 100644
index 0000000..6ba8fc0
--- /dev/null
+++ b/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch
@@ -0,0 +1,37 @@
+From 8439d2837fbdf4ed7a261935a781deb22cb6c5dd Mon Sep 17 00:00:00 2001
+From: natl <nathanael at natlampe.com>
+Date: Thu, 19 May 2016 12:19:49 +0200
+Subject: [PATCH 15/16] Checked that patch compiles and updated versioning
+
+---
+ configure.ac                         | 2 +-
+ src/gui/headers/Gui_ControlPanel.hpp | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/configure.ac b/configure.ac
+index cb25c68..bc771ea 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,5 +1,5 @@
+ AC_PREREQ([2.68])
+-AC_INIT([opencfu],[3.9.0],[opencfu at gmail.com],[opencfu],[http://www.opencfu.sourceforge.net/])
++AC_INIT([opencfu],[3.9.1],[opencfu at gmail.com],[opencfu],[http://www.opencfu.sourceforge.net/])
+ AC_CONFIG_AUX_DIR([build-aux])
+ AC_CONFIG_MACRO_DIR([m4])
+ AC_CONFIG_SRCDIR([src])
+diff --git a/src/gui/headers/Gui_ControlPanel.hpp b/src/gui/headers/Gui_ControlPanel.hpp
+index 1b2f3dc..5ae56b2 100644
+--- a/src/gui/headers/Gui_ControlPanel.hpp
++++ b/src/gui/headers/Gui_ControlPanel.hpp
+@@ -14,7 +14,7 @@
+ #include "Gui_LikFiltSelector.hpp"
+ #include "Gui_HelloWindow.hpp"
+ #include "Gui_PixbufOpener.hpp"
+-#include "Gui_MaskSetter.hpp"
++#include "Gui_MaskSetter.hpp"
+ #include "Gui_ColourCluster.hpp" //NJL 10/AUG/2014
+ #include "Gui_ConfigIO.hpp"
+ 
+-- 
+2.9.3
+
diff --git a/debian/patches/0016-Compiler-compatibility-fix.patch b/debian/patches/0016-Compiler-compatibility-fix.patch
new file mode 100644
index 0000000..819f997
--- /dev/null
+++ b/debian/patches/0016-Compiler-compatibility-fix.patch
@@ -0,0 +1,47 @@
+From e70b68344a725b7b2c926a3159dbb5d488c0bdd2 Mon Sep 17 00:00:00 2001
+From: tzdybal <tomek at zdybal.lap.pl>
+Date: Wed, 26 Oct 2016 23:41:18 +0200
+Subject: [PATCH 16/16] Compiler compatibility fix
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Fixed two invalid usages of abs function, giving
+"error: call of overloaded ‘abs(double)’ is ambiguous",
+on current version of compilers.
+
+Solution tested with g++ 6.2.1 and clang++ 3.8.1.
+---
+ src/gui/src/Gui_ColourWheel.cpp   | 2 +-
+ src/processor/src/Step_FiltHS.cpp | 2 +-
+ 2 files changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/src/gui/src/Gui_ColourWheel.cpp b/src/gui/src/Gui_ColourWheel.cpp
+index c6687b0..3b4b5eb 100644
+--- a/src/gui/src/Gui_ColourWheel.cpp
++++ b/src/gui/src/Gui_ColourWheel.cpp
+@@ -53,7 +53,7 @@ void Gui_ColourWheel::redraw(){
+             float aa = (float) mean_hue *  MY_PI /180;
+             float bb = (float) m_centr_hue *  MY_PI /180;
+ 
+-            int diff = abs(atan2(sin(aa-bb), cos(aa-bb)) * 180 / MY_PI);
++            int diff = (int) fabs(atan2(sin(aa-bb), cos(aa-bb)) * 180 / MY_PI);
+             if(val < m_min_sat || val > m_max_sat || diff > m_tol_hue){
+                 chanels[1].at<uchar>(i, j) = 0;
+                 chanels[2].at<uchar>(i, j) = 0;
+diff --git a/src/processor/src/Step_FiltHS.cpp b/src/processor/src/Step_FiltHS.cpp
+index 20a921c..86363dd 100644
+--- a/src/processor/src/Step_FiltHS.cpp
++++ b/src/processor/src/Step_FiltHS.cpp
+@@ -46,7 +46,7 @@ std::vector<bool> Step_FiltHS::filter(const Result& in_numerical_result){
+ 
+         float aa = (float) mean_hue *  3.1416 /180;
+         float bb = (float) m_centr_hue *  3.1416 /180;
+-        int diff = abs(atan2(sin(aa-bb), cos(aa-bb)) * 180 / 3.1416);
++        int diff = (int) fabs(atan2(sin(aa-bb), cos(aa-bb)) * 180 / 3.1416);
+         int mean_sat = (int) mean[2];
+ 
+         if(diff > m_tol_hue || mean_sat > m_max_sat || mean_sat < m_min_sat)
+-- 
+2.9.3
+
diff --git a/debian/patches/series b/debian/patches/series
new file mode 100644
index 0000000..b642495
--- /dev/null
+++ b/debian/patches/series
@@ -0,0 +1,16 @@
+0001-brew-formula.patch
+0002-Can-change-min_colour_clustering_points.patch
+0003-Improved-ordering-of-colour-clusters-by-quantity.patch
+0004-Counting-now-ignores-unmatched-cells.patch
+0005-Changed-maximum-value-of-min_cluster_points.patch
+0006-Bugfix-last-coloured-cluster-sometimes-wasn-t-shown.patch
+0007-Comman-line-parsing-changes-to-highlight-colour.patch
+0008-Push-final-changes-for-clustering-improvements.patch
+0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch
+0010-improve-compat-with-cv3-worked-on-RF.patch
+0011-classifier-now-compatible-with-cv3.patch
+0012-add-explicit-linking-to-std-map-in-colour-clusters.patch
+0013-fixes-17.patch
+0014-Update-Colour-difference-formula.patch
+0015-Checked-that-patch-compiles-and-updated-versioning.patch
+0016-Compiler-compatibility-fix.patch
diff --git a/debian/rules b/debian/rules
index 4f2c774..cca5b3b 100755
--- a/debian/rules
+++ b/debian/rules
@@ -1,4 +1,4 @@
 #!/usr/bin/make -f
 %:
-	dh $@
+	dh $@ --with autoreconf
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/opencfu.git



More information about the debian-med-commit mailing list