diff -Nru opencfu-3.9.0/debian/control opencfu-3.9.0/debian/control --- opencfu-3.9.0/debian/control 2014-10-30 20:04:49.000000000 +0900 +++ opencfu-3.9.0/debian/control 2016-10-27 00:47:30.000000000 +0900 @@ -5,6 +5,7 @@ Section: misc Priority: optional Build-Depends: debhelper (>= 9), + dh-autoreconf, libgtkmm-2.4-dev, libopencv-dev Standards-Version: 3.9.6 diff -Nru opencfu-3.9.0/debian/patches/0001-brew-formula.patch opencfu-3.9.0/debian/patches/0001-brew-formula.patch --- opencfu-3.9.0/debian/patches/0001-brew-formula.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0001-brew-formula.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,35 @@ +From b4a099a803409de12fe09c70a3df4d65ab6001bb Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 -Nru opencfu-3.9.0/debian/patches/0002-Can-change-min_colour_clustering_points.patch opencfu-3.9.0/debian/patches/0002-Can-change-min_colour_clustering_points.patch --- opencfu-3.9.0/debian/patches/0002-Can-change-min_colour_clustering_points.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0002-Can-change-min_colour_clustering_points.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,403 @@ +From a6f528029a21c04c5fb15aa2b9e11450f97c28fd Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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." + + //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 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 > 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 + #include + #include +-#include ++#include ++#include ++ ++ + + class ClusterPoint + { +@@ -59,12 +62,15 @@ class Step_ColourCluster : public Step_BaseClass + std::vector 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::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 > 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 > clusterColors; +@@ -263,7 +268,8 @@ void Result::ClusterOrder(){ + m_roi_data.clear(); + for (std::vector::iterator it = v.begin(); it != v.end(); ++it){ + std::unordered_map >::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 l, const std::pair 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 "< > Step_ColourCluster::cluster(const Result& in_n + } + + dbscan(); +- +- for (std::vector::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ +- result.push_back(std::make_pair( 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 cluster_ids; ++ for (std::vector::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> cluster_counts; ++ for (int ii=0; ii<=highest_cluster_number; ii++){ ++ cluster_counts.push_back(std::pair(ii,0)); ++ } ++ ++ //DEV_INFOS("Populate cluster vector"); ++ ++ //poulate the vector so it contains ++ for (std::vector::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: " <second); ++ } ++ ++ //make a map that gives map['oldID']=newID ++ std::map cluster_map; ++ for (int ii=0; ii<=highest_cluster_number; ii++){ ++ cluster_map.insert( std::pair(cluster_counts[ii].first, ii)); ++ //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ ++ result.push_back(std::pair( it->getID(), cluster_map[it->getClusterID()]+1 )); ++ } + } ++ //We have no clusters, but we need to prepare the results vector anyway ++ else {*/ ++ for (std::vector::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ ++ result.push_back(std::make_pair( it->getID(), it->getClusterID() )); ++ } ++ //} + + + return result; +-- +2.9.3 + diff -Nru opencfu-3.9.0/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch opencfu-3.9.0/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch --- opencfu-3.9.0/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0003-Improved-ordering-of-colour-clusters-by-quantity.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,60 @@ +From f3b12b33f92e023c073d7054dba3097b1ecc0b54 Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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 > 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 > 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 > 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::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ + result.push_back(std::make_pair( it->getID(), it->getClusterID() )); + } +- //} ++ } + + + return result; +-- +2.9.3 + diff -Nru opencfu-3.9.0/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch opencfu-3.9.0/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch --- opencfu-3.9.0/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0004-Counting-now-ignores-unmatched-cells.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,48 @@ +From 854a03c69fe3f80e0d8449bbd56f4d9df42885d5 Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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 > 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 > Step_ColourCluster::cluster(const Result& in_n + //make a map that gives map['oldID']=newID + std::map cluster_map; + for (int ii=0; ii<=highest_cluster_number; ii++){ +- cluster_map.insert( std::pair(cluster_counts[ii].first, ii)); ++ cluster_map.insert( std::pair(cluster_counts[ii].first, ii+1)); + //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ +- result.push_back(std::pair( it->getID(), cluster_map[it->getClusterID()]+1 )); ++ result.push_back(std::pair( it->getID(), cluster_map[it->getClusterID()] )); + } + } + //We have no clusters, but we need to prepare the results vector anyway +-- +2.9.3 + diff -Nru opencfu-3.9.0/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch opencfu-3.9.0/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch --- opencfu-3.9.0/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0005-Changed-maximum-value-of-min_cluster_points.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,76 @@ +From 3bda769fa953a318b171697891570d049cd6662a Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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 > Step_ColourCluster::cluster(const Result& in_n + cluster_counts.push_back(std::pair(ii,0)); + } + ++ ++ + //DEV_INFOS("Populate cluster vector"); + + //poulate the vector so it contains +@@ -94,6 +96,9 @@ std::vector< std::pair > 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 > Step_ColourCluster::cluster(const Result& in_n + //DEV_INFOS("key "<< cluster_counts[ii].first << " val "< +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 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::iterator it = v.begin(); it != v.end(); ++it){ + std::unordered_map >::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 -Nru opencfu-3.9.0/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch opencfu-3.9.0/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch --- opencfu-3.9.0/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0007-Comman-line-parsing-changes-to-highlight-colour.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,122 @@ +From 03b1754ae67bfcb641307c950030af47c47499a2 Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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 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]"< +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 -Nru opencfu-3.9.0/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch opencfu-3.9.0/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch --- opencfu-3.9.0/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0009-first-attemps-at-addressing-17.-Compiles-but-segfaul.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,192 @@ +From 87bbe96fdbc0416351acbf6994493a2fd46aa933 Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 "< PRED(left) \n"< PRED(left) \n"< PRED(left) \n"< 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 m_trees = cv::ml::StatModel::load(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& categs){ + cv::Mat categ_mat(categs.size(),1,CV_32S); + for(int i = 0; i < categ_mat.rows;i++) + categ_mat.at(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"< 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"<train(features, cv::ml::ROW_SAMPLE, categ_mat); ++ ++ //DEV_INFOS("Variable Importance:\n"<getVarImportance()<& 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 -Nru opencfu-3.9.0/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch opencfu-3.9.0/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch --- opencfu-3.9.0/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0010-improve-compat-with-cv3-worked-on-RF.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,70 @@ +From cb8af1a9c9fbf2dfc087c9aad263cbf146dbd5fa Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 m_trees = cv::ml::StatModel::load(str.c_str()); ++ m_trees = cv::ml::StatModel::load ("/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& c + //m_trees->train(features, cv::ml::ROW_SAMPLE, categ_mat); + + //std::cout<<"\nConfusion Matrix = \n REAL(top) -> PRED(left) \n"<train(features, cv::ml::ROW_SAMPLE, categ_mat); + ++ + //DEV_INFOS("Variable Importance:\n"<& c + } + + void Predictor::predict(const cv::Mat& in, std::vector& 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 -Nru opencfu-3.9.0/debian/patches/0011-classifier-now-compatible-with-cv3.patch opencfu-3.9.0/debian/patches/0011-classifier-now-compatible-with-cv3.patch --- opencfu-3.9.0/debian/patches/0011-classifier-now-compatible-with-cv3.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0011-classifier-now-compatible-with-cv3.patch 2016-10-27 00:46:39.000000000 +0900 @@ -0,0 +1,309 @@ +From edecbbd6fa13304b6f6a39efd49426c22c164786 Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 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 "< 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 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 lut; +@@ -70,21 +83,26 @@ int main(int argc, char **argv){ + std::vector counts(3,0); + + for(unsigned int i = 0; i(pred,real) = m_mat.at(pred,real) + 1; ++ m_mat.at(pred_int,real_int) = m_mat.at(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 "< PRED(left) \n"< PRED(left) \n"< PRED(left) \n"< 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 + + #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 ("/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 (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& c + cv::Mat categ_mat(categs.size(),1,CV_32S); + for(int i = 0; i < categ_mat.rows;i++) + categ_mat.at(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 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"<train(features, cv::ml::ROW_SAMPLE, categ_mat); +- +- +- //DEV_INFOS("Variable Importance:\n"<getVarImportance()<& 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 > Step_ColourCluster::cluster(const Result& in_n + + + std::vector< std::pair > 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 > 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 > Step_ColourCluster::cluster(const Result& in_n + } + } + ++ */ ++ return result; + +- return result; + } + + /** +-- +2.9.3 + diff -Nru opencfu-3.9.0/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch opencfu-3.9.0/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch --- opencfu-3.9.0/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0012-add-explicit-linking-to-std-map-in-colour-clusters.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,40 @@ +From b56df8b63c1b63248432b0caab588fa50ac3539e Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 + + bool sort_by_second( const std::pair l, const std::pair r) { return l.second > r.second; } + +@@ -67,7 +68,7 @@ std::vector< std::pair > 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 > Step_ColourCluster::cluster(const Result& in_n + } + } + +- */ ++ + return result; + + } +-- +2.9.3 + diff -Nru opencfu-3.9.0/debian/patches/0013-fixes-17.patch opencfu-3.9.0/debian/patches/0013-fixes-17.patch --- opencfu-3.9.0/debian/patches/0013-fixes-17.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0013-fixes-17.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,56 @@ +From 82e4f786969a46412350da9d9a299362192a8cae Mon Sep 17 00:00:00 2001 +From: Quentin Geissmann +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 "< 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 (str); + #endif // CV_MAJOR_VERSION +@@ -85,7 +85,7 @@ void Predictor::predict(const cv::Mat& in, std::vector& 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 -Nru opencfu-3.9.0/debian/patches/0014-Update-Colour-difference-formula.patch opencfu-3.9.0/debian/patches/0014-Update-Colour-difference-formula.patch --- opencfu-3.9.0/debian/patches/0014-Update-Colour-difference-formula.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0014-Update-Colour-difference-formula.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,359 @@ +From 8f6499e575cf87648bbaccb51da9bbda742587ff Mon Sep 17 00:00:00 2001 +From: Nathanael Lampe +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 +- +-bool sort_by_second( const std::pair l, const std::pair r) { return l.second > r.second; } ++#include "Step_ColourCluster.hpp" ++#include ++ ++bool sort_by_second( const std::pair l, const std::pair 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 "< > Step_ColourCluster::cluster(const Result& in_numerical_result){ +- +- +- std::vector< std::pair > 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 "< > Step_ColourCluster::cluster(const Result& in_numerical_result){ ++ ++ ++ std::vector< std::pair > 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 > Step_ColourCluster::cluster(const Result& in_n + result.push_back( std::make_pair( 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 cluster_ids; +- for (std::vector::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 cluster_ids; ++ for (std::vector::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> cluster_counts; +- for (int ii=0; ii<=highest_cluster_number; ii++){ +- cluster_counts.push_back(std::pair(ii,0)); +- } +- +- +- +- //DEV_INFOS("Populate cluster vector"); +- +- //poulate the vector so it contains +- for (std::vector::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: " <second); +- } +- +- //make a map that gives map['oldID']=newID +- std::map cluster_map; +- for (int ii=0; ii<=highest_cluster_number; ii++){ +- cluster_map.insert( std::pair(cluster_counts[ii].first, ii+1)); +- //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<> cluster_counts; ++ for (int ii=0; ii<=highest_cluster_number; ii++){ ++ cluster_counts.push_back(std::pair(ii,0)); ++ } ++ ++ ++ ++ //DEV_INFOS("Populate cluster vector"); ++ ++ //poulate the vector so it contains ++ for (std::vector::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: " <second); ++ } ++ ++ //make a map that gives map['oldID']=newID ++ std::map cluster_map; ++ for (int ii=0; ii<=highest_cluster_number; ii++){ ++ cluster_map.insert( std::pair(cluster_counts[ii].first, ii+1)); ++ //DEV_INFOS("key "<< cluster_counts[ii].first << " val "<::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ + result.push_back(std::pair( 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::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ + result.push_back(std::make_pair( it->getID(), it->getClusterID() )); +- } +- } ++ } ++ } + + +- return result; ++ return result; + + } + + /** + * + */ +-void Step_ColourCluster::dbscan(){ ++void Step_ColourCluster::dbscan(){ + DEV_INFOS("Launching density scanner on "<::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ ++ m_current_cluster = 0; ++ ++ for (std::vector::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::iterator> local_neighbours = Step_ColourCluster::findNeighbours( *it ); +@@ -169,7 +169,7 @@ void Step_ColourCluster::dbscan(){ + } + } + } +-} ++} + + /** + * +@@ -179,14 +179,15 @@ std::vector::iterator> Step_ColourCluster::findNeighbo + double colorA1 = searchPoint.getColor()[1]; + double colorB1 = searchPoint.getColor()[2]; + std::vector::iterator> local_neighbours; +- for(std::vector::iterator it = m_cluster_vector.begin(); it != m_cluster_vector.end(); ++it){ +- ++ for(std::vector::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::iterator> local_neighbours = findNeighbours(expandPoint); + while (local_neighbours.size() >= 1){ +- std::vector::iterator neighbour = local_neighbours.front(); ++ std::vector::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 -Nru opencfu-3.9.0/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch opencfu-3.9.0/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch --- opencfu-3.9.0/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0015-Checked-that-patch-compiles-and-updated-versioning.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,37 @@ +From 8439d2837fbdf4ed7a261935a781deb22cb6c5dd Mon Sep 17 00:00:00 2001 +From: natl +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@gmail.com],[opencfu],[http://www.opencfu.sourceforge.net/]) ++AC_INIT([opencfu],[3.9.1],[opencfu@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 -Nru opencfu-3.9.0/debian/patches/0016-Compiler-compatibility-fix.patch opencfu-3.9.0/debian/patches/0016-Compiler-compatibility-fix.patch --- opencfu-3.9.0/debian/patches/0016-Compiler-compatibility-fix.patch 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/0016-Compiler-compatibility-fix.patch 2016-10-27 00:47:30.000000000 +0900 @@ -0,0 +1,47 @@ +From e70b68344a725b7b2c926a3159dbb5d488c0bdd2 Mon Sep 17 00:00:00 2001 +From: tzdybal +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(i, j) = 0; + chanels[2].at(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 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 -Nru opencfu-3.9.0/debian/patches/series opencfu-3.9.0/debian/patches/series --- opencfu-3.9.0/debian/patches/series 1970-01-01 09:00:00.000000000 +0900 +++ opencfu-3.9.0/debian/patches/series 2016-10-27 00:47:30.000000000 +0900 @@ -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 -Nru opencfu-3.9.0/debian/rules opencfu-3.9.0/debian/rules --- opencfu-3.9.0/debian/rules 2014-10-30 20:04:49.000000000 +0900 +++ opencfu-3.9.0/debian/rules 2016-10-27 00:47:30.000000000 +0900 @@ -1,4 +1,4 @@ #!/usr/bin/make -f %: - dh $@ + dh $@ --with autoreconf