Skip to content

Commit

Permalink
Merge pull request #73 from DerThorsten/dev
Browse files Browse the repository at this point in the history
Dev to master
  • Loading branch information
DerThorsten authored May 30, 2017
2 parents ef34d9d + 378b4cf commit 6e14fbe
Show file tree
Hide file tree
Showing 17 changed files with 589 additions and 55 deletions.
4 changes: 2 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules)
project(nifty)

set (NIFTY_VERSION_MAJOR 0)
set (NIFTY_VERSION_MINOR 10)
set (NIFTY_VERSION_PATCH 2)
set (NIFTY_VERSION_MINOR 12)
set (NIFTY_VERSION_PATCH 0)


set (NIFTY_VERSION_SHORT_STR "${NIFTY_VERSION_MAJOR}.${NIFTY_VERSION_MINOR}")
Expand Down
17 changes: 0 additions & 17 deletions docsrc/python/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,3 @@ Contents:
zbibliography



The documentation is split into 3 parts:

* The documentation:
Auto generated API reference can be confusing
for beginners.
This is even more true for python libraries which
use pybind11 or boost::python to export C++ to python.
If the C++ code heavily relies on templates the auto generated
documentation is full of complicated ``template`` names.
Therefore we try to add es many examples and hand written
documentation to improve the user experience.

* Examples:
TODO
* The API Reference documentation:
TODO
78 changes: 78 additions & 0 deletions include/nifty/graph/edge_map_from_node_map.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
#pragma once


namespace nifty{
namespace graph{
namespace graph_maps{



/**
* @brief Implicit edge map
* @details Convert a node map into an edge map by applying
* a binary functor to the node maps values.
*
* @tparam GRAPH the graph type
* @tparam NODE_MAP The node map. This can be a
* (const) reference or a value type (in) case of proxy objects
* @tparam BINARY_FUNCTOR a binary functor.This can be a
* (const) reference or a value type.
*/
template<class GRAPH, class NODE_MAP, class BINARY_FUNCTOR>
class EdgeMapFromNodeMap {
public:
typedef GRAPH GraphType;
typedef BINARY_FUNCTOR BinaryFunctorType;
typedef typename BinaryFunctorType::value_type value_type;
typedef NODE_MAP NodeMapType;

/**
* @brief construct edge map from node map and functor
*
* @param graph the graph
* @param nodeMap the node map
* @param binaryFunctor the binary functor
*/
EdgeMapFromNodeMap(
const GraphType & graph,
NodeMapType nodeMap,
BinaryFunctorType binaryFunctor
)
: graph_(graph),
nodeMap_(nodeMap),
binaryFunctor_(binaryFunctor){
}

/**
* @brief get the value for an edge
* @details get the value for an edge
* by calling the binary functor. The functor
* is called with the node maps values at
* the enpoints of the edge.
*
* @param edgeIndex the edge index
* @return the value of the edge map
*/
value_type operator[](const uint64_t edgeIndex)const{
const auto uv = graph_.uv(edgeIndex);
const auto u = uv.first;
const auto v = uv.second;
return binaryFunctor_(nodeMap_[u], nodeMap_[v]);
}

private:
const GraphType & graph_;
NODE_MAP nodeMap_;
BinaryFunctorType binaryFunctor_;
};







} // namespace nifty::graph::graph_maps
} // namespace nifty::graph
} // namespace nifty

7 changes: 5 additions & 2 deletions include/nifty/graph/edge_weighted_watersheds.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -224,8 +224,11 @@ namespace detail_watersheds_segmentation{
const SEEDS & seeds,
LABELS & labels
){
detail_watersheds_segmentation::RawPriorityFunctor fPriority;
detail_watersheds_segmentation::edgeWeightedWatershedsSegmentationImpl(g,edgeWeights,seeds,fPriority,labels);
detail_watersheds_segmentation::edgeWeightedWatershedsSegmentationKruskalImpl(
g,edgeWeights,seeds,labels);

//detail_watersheds_segmentation::RawPriorityFunctor fPriority;
//detail_watersheds_segmentation::edgeWeightedWatershedsSegmentationImpl(g,edgeWeights,seeds,fPriority,labels);
}


Expand Down
16 changes: 0 additions & 16 deletions include/nifty/graph/graph_maps.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,6 @@ private:











template<class G, class T>
struct EdgeMap : public std::vector<T>{
EdgeMap( const G & g, const T & val)
Expand All @@ -217,14 +209,6 @@ struct EdgeMap : public std::vector<T>{
};










} // namespace nifty::graph::graph_maps
} // namespace nifty::graph
} // namespace nifty
Expand Down
135 changes: 135 additions & 0 deletions include/nifty/graph/node_weighted_watersheds.hxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
#pragma once


#include <algorithm> // sort


#include "vigra/priority_queue.hxx"
#include "nifty/tools/changable_priority_queue.hxx"
#include "nifty/ufd/ufd.hxx"

namespace nifty{
namespace graph{

// \cond SUPPRESS_DOXYGEN
namespace detail_watersheds_segmentation{




template<
class GRAPH,
class NODE_WEIGHTS,
class SEEDS,
class LABELS
>
void nodeWeightedWatershedsSegmentationImpl(
const GRAPH & g,
const NODE_WEIGHTS & nodeWeights,
const SEEDS & seeds,
LABELS & labels
){
typedef GRAPH Graph;
typedef typename NODE_WEIGHTS::value_type WeightType;
typedef typename LABELS::value_type LabelType;
//typedef typename Graph:: template EdgeMap<bool> EdgeBoolMap;
typedef vigra::PriorityQueue<int64_t, WeightType,true> PQ;

PQ pq;
for(auto node : g.nodes())
labels[node] = seeds[node];

// put edges from nodes with seed on pq
for(auto node : g.nodes()){
if(labels[node]!=static_cast<LabelType>(0)){

for(auto adj : g.adjacency(node)){
const auto edge = adj.edge();
const auto neigbour = adj.node();
//std::cout<<"n- node "<<g.id(neigbour)<<"\n";
if(labels[neigbour]==static_cast<LabelType>(0)){
const auto priority = nodeWeights[neigbour];
pq.push(edge,priority);
//inPQ[edge]=true;
}
}
}
}


while(!pq.empty()){

const auto edge = pq.top();
pq.pop();

const auto u = g.u(edge);
const auto v = g.v(edge);
const LabelType lU = labels[u];
const LabelType lV = labels[v];


if(lU==0 && lV==0){
throw std::runtime_error("both have no labels");
}
else if(lU!=0 && lV!=0){
// nothing to do
}
else{

const auto unlabeledNode = lU==0 ? u : v;
const auto label = lU==0 ? lV : lU;

// assign label to unlabeled node
labels[unlabeledNode] = label;

// iterate over the nodes edges
for(auto adj : g.adjacency(unlabeledNode)){
const auto otherEdge = adj.edge();
const auto targetNode = adj.node();
if(labels[targetNode] == 0){
//if(inPQ[otherEdge] == false && labels[targetNode] == 0){
const auto priority = nodeWeights[targetNode];
pq.push(otherEdge,priority);
// inPQ[otherEdge]=true;
}
}
}
}
}






} // end namespace detail_watersheds_segmentation

// \endcond


/// \brief edge weighted watersheds Segmentataion
///
/// \param g: input graph
/// \param nodeWeights : node weights / node height
/// \param seeds : seed must be non empty!
/// \param[out] labels : resulting nodeLabeling (not necessarily dense)
template<class GRAPH,class NODE_WEIGHTS,class SEEDS,class LABELS>
void nodeWeightedWatershedsSegmentation(
const GRAPH & g,
const NODE_WEIGHTS & nodeWeights,
const SEEDS & seeds,
LABELS & labels
){
detail_watersheds_segmentation::nodeWeightedWatershedsSegmentationImpl(
g,nodeWeights,seeds,labels);

}






} // namespace nifty::graph
} // namespace nifty

31 changes: 31 additions & 0 deletions include/nifty/graph/undirected_grid_graph.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -274,6 +274,37 @@ public:
void deserialize(ITER iter);


/**
* @brief convert an image with DIM dimension to an edge map
* @details convert an image with DIM dimension to an edge map
* by applying a binary functor to the values of a node map at
* the endpoints of an edge.
*
* @param image the input image
* @param binaryFunctor a binary functor
* @param[out] the result edge map
*
* @return [description]
*/
template<class IMAGE, class BINARY_FUNCTOR, class EDGE_MAP>
void imageToEdgeMap(
const IMAGE & image,
BINARY_FUNCTOR binaryFunctor,
EDGE_MAP & edgeMap
)const{
for(const auto edge : this->edges()){
const auto uv = this->uv(edge);
CoordinateType cU,cV;
nodeToCoordinate(uv.first, cU);
nodeToCoordinate(uv.second, cV);
const auto uVal = image(cU.asStdArray());
const auto vVal = image(cU.asStdArray());
edgeMap[edge] = binaryFunctor(uVal, vVal);
}
}



// COORDINATE RELATED
CoordinateType nodeToCoordinate(const uint64_t node)const{
CoordinateType ret;
Expand Down
13 changes: 11 additions & 2 deletions include/nifty/python/converter.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

#include <type_traits>
#include <initializer_list>

#include <iostream>


#include <pybind11/pybind11.h>
Expand Down Expand Up @@ -304,11 +304,20 @@ namespace marray
};


}



template <typename VALUE_TYPE, size_t DIM, bool AUTO_CAST_TYPE>
std::ostream& operator<<(
std::ostream& os,
const nifty::marray::PyView<VALUE_TYPE, DIM, AUTO_CAST_TYPE> & obj
)
{
os<<"PyViewArray[..]\n";
return os;
}


namespace tools{

template<class ARRAY>
Expand Down
2 changes: 1 addition & 1 deletion src/python/examples/graph/plot_agglomerative_clustering.py
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@

f.add_subplot(2, 2, 4)
b_img = skimage.segmentation.mark_boundaries(img,
seg.astype('uint32'), mode='inner', color=(1,0,0))
seg.astype('uint32'), mode='inner', color=(0,0,0))
pylab.imshow(b_img)
pylab.title('Segmentation')

Expand Down
Loading

0 comments on commit 6e14fbe

Please sign in to comment.