Commit 3f558e48 authored by Pierre Lassalle's avatar Pierre Lassalle

More efficient GRM

parent d9c40966
......@@ -27,6 +27,15 @@ ELSE(OTB_FOUND)
"Cannot build OTB project without OTB. Please set OTB_DIR.")
ENDIF(OTB_FOUND)
#Activate c++11
include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
if(COMPILER_SUPPORTS_CXX11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -fpermissive -Wall -Wmaybe-uninitialized")
else()
message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR}/Code)
add_subdirectory(Code)
......
......@@ -16,7 +16,6 @@
#=========================================================================
add_library(OTBGRM
lsrmContourOperations.cpp
lsrmNeighborhood.cpp)
target_link_libraries(OTBGRM OTBCommon OTBIO)
......@@ -51,7 +51,6 @@ namespace lsrm
float
BaatzSegmenter<TImage>::ComputeMergingCost(NodePointerType n1, NodePointerType n2)
{
const std::size_t bands = n1->m_Means.size();
const unsigned int a1 = n1->m_Area, a2 = n2->m_Area, a_sum = a1 + a2;
float spect_cost = 0.0f;
......@@ -77,7 +76,7 @@ namespace lsrm
const unsigned int boundary = (GraphOperatorType::FindEdge(n1, n2))->m_Boundary;
const float p3 = p1 + p2 - 2 * static_cast<float>(boundary);
const BoundingBox merged_bbox = ContourOperations::MergeBoundingBoxes(n1->m_Bbox, n2->m_Bbox);
const BoundingBox merged_bbox = MergeBoundingBoxes(n1->m_Bbox, n2->m_Bbox);
const float bb1_perimeter = static_cast<float>(2*n1->m_Bbox.m_W + 2*n1->m_Bbox.m_H);
const float bb2_perimeter = static_cast<float>(2*n2->m_Bbox.m_W + 2*n2->m_Bbox.m_H);
const float mbb_perimeter = static_cast<float>(2 * merged_bbox.m_W + 2 * merged_bbox.m_H);
......@@ -141,11 +140,6 @@ namespace lsrm
this->m_ImageWidth,
this->m_ImageHeight,
this->m_LabelImageFileName);
if(!this->m_ContourImageFileName.empty())
IOType::WriteContourImage(this->m_Graph,
this->m_InputFileName,
this->m_LabelImageFileName);
}
} // end of namespace lsrm
......
This diff is collapsed.
This diff is collapsed.
#ifndef __LSRM_DATA_STRUCTURES_H
#define __LSRM_DATA_STRUCTURES_H
#include <stdexcept>
#include <bitset>
#include <vector>
namespace lsrm
{
typedef std::bitset<2> ContourElem;
typedef std::vector<ContourElem> Contour;
typedef typename Contour::iterator ContourIterator;
typedef typename Contour::const_iterator ContourConstIterator;
struct BoundingBox
{
......@@ -25,6 +22,25 @@ namespace lsrm
unsigned int m_H;
};
BoundingBox MergeBoundingBoxes(const BoundingBox& bb1,
const BoundingBox& bb2)
{
long unsigned int min_ux, min_uy, max_xw, max_yh;
BoundingBox bb;
min_ux = std::min(bb1.m_UX, bb2.m_UX);
min_uy = std::min(bb1.m_UY, bb2.m_UY);
max_xw = std::max(bb1.m_UX + bb1.m_W, bb2.m_UX + bb2.m_W);
max_yh = std::max(bb1.m_UY + bb1.m_H, bb2.m_UY + bb2.m_H);
bb.m_UX = min_ux;
bb.m_UY = min_uy;
bb.m_W = max_xw - min_ux;
bb.m_H = max_yh - min_uy;
return bb;
}
} // end of namespace lsrm
#endif
#ifndef __LSRM_GRAPH_H
#define __LSRM_GRAPH_H
#include <boost/shared_ptr.hpp>
#include "lsrmDataStructures.h"
namespace lsrm
{
struct BaseNode
{
BaseNode(){}
virtual ~BaseNode() {}
/* Node already merged. */
bool m_Valid;
/* Node has to be removed from the graph. */
bool m_Expired;
/* Does the node merge at the previous iteration */
bool m_IsMerged;
/* Perimeter of the region */
unsigned int m_Perimeter;
......@@ -35,39 +33,47 @@ namespace lsrm
*/
BoundingBox m_Bbox;
/*
Contour of the region
*/
Contour m_Contour;
/* List of pixels contained in the regions */
std::vector<unsigned long int> m_Pixels;
};
template<class DerivedNode>
struct Node : BaseNode
{
struct Edge
struct NeighborType
{
/* Boundary length between two adjacent regions.*/
typedef std::weak_ptr<DerivedNode> WeakDerived;
typedef std::shared_ptr<DerivedNode> SharedDerived;
WeakDerived m_Target;
float m_Cost;
unsigned int m_Boundary;
bool m_CostUpdated;
NeighborType(WeakDerived ptr, double w, unsigned int c) :
m_Target(ptr), m_Cost(w), m_Boundary(c), m_CostUpdated(false) {}
/* Fusion cost (similarity measure) with the target node. */
float m_Cost;
/* Pointer to a neighboring node. */
boost::shared_ptr<DerivedNode> m_Target;
inline SharedDerived GetRegion()
{
SharedDerived ptr(m_Target.lock());
if(!ptr)
throw std::runtime_error("lss_GenericLMBFRegionMergingHandler.h - NeighborType::GetRegion - Region pointer is not valid");
return ptr;
}
};
Node(){};
virtual ~Node() {}
std::vector<Edge> m_Edges;
template<class DerivedNode>
struct Node : BaseNode
{
typedef NeighborType<DerivedNode> CRPTNeighborType;
std::vector<CRPTNeighborType> m_Edges;
};
template<class TNode>
struct Graph
{
typedef TNode NodeType;
typedef typename NodeType::Edge EdgeType;
typedef boost::shared_ptr<NodeType> NodePointerType;
typedef std::shared_ptr<NodeType> NodePointerType;
typedef typename NodeType::CRPTNeighborType EdgeType;
typedef std::vector<NodePointerType> NodeListType;
typedef typename NodeListType::iterator NodeIteratorType;
typedef typename NodeListType::const_iterator NodeConstIteratorType;
......@@ -75,7 +81,7 @@ namespace lsrm
typedef typename EdgeListType::iterator EdgeIteratorType;
typedef typename EdgeListType::const_iterator EdgeConstIteratorType;
std::vector< boost::shared_ptr<TNode> > m_Nodes;
std::vector< NodePointerType > m_Nodes;
};
} // end of namespace lsrm
......
......@@ -2,7 +2,6 @@
#define __LSRM_GRAPH_OPERATIONS_H
#include "lsrmGraph.h"
#include "lsrmNeighborhood.h"
#include "lsrmContourOperations.h"
#include <iostream>
#include <cassert>
#include <limits>
......@@ -30,59 +29,6 @@ namespace lsrm
typedef typename GraphType::EdgeIteratorType EdgeIterator;
typedef typename GraphType::EdgeConstIteratorType EdgeConstIterator;
/* Some static constants */
static const long long unsigned int NodeSize = sizeof(NodeType) + sizeof(NodePointerType);
static const long long unsigned int EdgeSize = sizeof(EdgeType);
/* Functors (former than lambda expression...
but it can accept all compiler' versions) */
struct EdgeEqualTo
{
explicit EdgeEqualTo(NodePointerType t_) : m_T(t_)
{assert(m_T != NULL);}
bool operator()(const EdgeType& e)
{
return e.m_Target == m_T;
}
NodePointerType m_T;
};
struct IsExpired
{
IsExpired () {}
bool operator()(NodePointerType n) const
{
return n->m_Expired;
}
};
struct IsInSet
{
explicit IsInSet(std::set<long unsigned int>& ur) : m_UsedRegions(ur)
{
}
bool operator()(const EdgeType& e)
{
if(m_UsedRegions.find(e.m_Target->m_Id) == m_UsedRegions.end())
return true;
else
return false;
}
std::set<long unsigned int>& m_UsedRegions;
};
struct NodePtrComparator : public std::unary_function<NodePointerType, bool>
{
NodePointerType nn;
explicit NodePtrComparator(NodePointerType n) : nn(n){}
bool operator()(NodePointerType v) { return v == nn;}
};
/*
* Given the size of the input image and the mask of the
......@@ -282,110 +228,6 @@ namespace lsrm
const unsigned int numberOfIterations,
const unsigned int width,
const unsigned int height);
/*
*
*/
static void LargeScaleInitNodes(GraphType& graph,
SegmenterType& seg,
const unsigned int tileWidth,
const unsigned int tileHeight,
const unsigned int nbTilesX,
const unsigned int nbTilesY,
const unsigned int tileId,
const unsigned int margin,
const unsigned int imageWidth,
const unsigned int imageHeight,
CONNECTIVITY mask);
/*
*
*/
static bool IsOnTileBorder(const unsigned int pixelRow,
const unsigned int pixelCol,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol,
const unsigned int imageWidth,
const unsigned int imageHeight);
static bool IsOnTileBorderAndAdjacentTileBorder(const unsigned int pixelRow,
const unsigned int pixelCol,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol,
const unsigned int imageWidth,
const unsigned int imageHeight);
/*
*
*/
static bool IsBboxStrictlyInsideTile(NodePointerType n,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol);
/*
*
*/
static bool IsBboxInsideTile(NodePointerType n,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol);
/*
*
*/
static void RemoveEdgesToUnstableRegion(NodePointerType r);
/*
*
*/
static void RemoveUnstableRegions(GraphType& graph,
unsigned int lowerRow,
unsigned int upperRow,
unsigned int lowerCol,
unsigned int upperCol,
unsigned int imageWidth);
/*
*
*/
static void AddNeighboringLayer(NodePointerType n,
GraphType& g,
std::set<long unsigned int>& bset);
/*
*
*/
static void BuildStabilityMargins(const GraphType& graph,
GraphType& subgraph,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol,
const unsigned int imageWidth,
const unsigned int imageHeight);
/*
*
*/
static void MergeGraphs(GraphType& graph,
const unsigned int lowerRow,
const unsigned int upperRow,
const unsigned int lowerCol,
const unsigned int upperCol,
const unsigned int imageWidth,
const unsigned int imageHeight,
bool useless);
/*
*
*/
static long long unsigned int GetMemorySpace(const GraphType& graph);
};
} // end of namespace lsrm
......
This diff is collapsed.
......@@ -6,7 +6,6 @@
#include <otbImageFileReader.h>
#include <otbImageFileWriter.h>
#include "lsrmGraph.h"
#include "lsrmContourOperations.h"
#include <string>
#include <stdlib.h>
#include <time.h>
......@@ -54,13 +53,7 @@ namespace lsrm
static void WriteOutputRGBImage(const GraphType& graph,
const unsigned int width,
const unsigned int height,
const std::string& outputFileName);
static void WriteContourImage(const GraphType& graph,
const std::string& inputFileName,
const std::string& outputFileName);
const std::string& outputFileName);
};
} // end of namespace lsrm
......
......@@ -29,19 +29,13 @@ namespace lsrm
// Start at 1 (value 0 can be used for invalid pixels)
long unsigned int label = 1;
for(NodeConstIterator nit = graph.m_Nodes.begin();
nit != graph.m_Nodes.end(); ++nit)
for(auto& region : graph.m_Nodes)
{
ContourOperations::PixelList pixels = ContourOperations::GeneratePixels((*nit)->m_Id,
(*nit)->m_Contour,
(*nit)->m_Bbox,
width);
for (ContourOperations::PixelConstIterator pit = pixels.begin();
pit != pixels.end(); ++pit)
for (auto& pix: region->m_Pixels)
{
index[0] = (*pit) % width;
index[1] = (*pit) / width;
index[0] = pix % width;
index[1] = pix / width;
label_img->SetPixel(index, label);
}
++label;
......@@ -95,21 +89,15 @@ namespace lsrm
srand(time(NULL));
unsigned char c1, c2, c3;
for(NodeConstIterator nit = graph.m_Nodes.begin();
nit != graph.m_Nodes.end(); ++nit)
for(auto& region : graph.m_Nodes)
{
ContourOperations::PixelList pixels = ContourOperations::GeneratePixels((*nit)->m_Id,
(*nit)->m_Contour,
(*nit)->m_Bbox,
width);
c1 = rand() % 256;
c2 = rand() % 256;
c3 = rand() % 256;
for (ContourOperations::PixelConstIterator pit = pixels.begin();
pit != pixels.end(); ++pit)
for (auto& pix : region->m_Pixels)
{
index[0] = (*pit) % width;
index[1] = (*pit) / width;
index[0] = pix % width;
index[1] = pix / width;
pixelValue[0] = c1;
pixelValue[1] = c2;
pixelValue[2] = c3;
......@@ -123,50 +111,6 @@ namespace lsrm
rgb_writer->SetFileName(outputFileName);
rgb_writer->Update();
}
template<class TGraph>
void GraphToOtbImage<TGraph>::WriteContourImage(const GraphType& graph,
const std::string& inputFileName,
const std::string& outputFileName)
{
typedef unsigned char RGBPixelType;
typedef otb::VectorImage<RGBPixelType, 2> RGBImageType;
typedef typename RGBImageType::IndexType RGBIndexType;
typedef otb::ImageFileReader<RGBImageType> RGBImageReaderType;
typedef otb::ImageFileWriter<RGBImageType> RGBImageWriterType;
RGBImageReaderType::Pointer rgb_reader = RGBImageReaderType::New();
rgb_reader->SetFileName(inputFileName);
rgb_reader->Update();
RGBImageType::Pointer rgb_img = rgb_reader->GetOutput();
RGBIndexType index;
const unsigned int width = rgb_img->GetLargestPossibleRegion().GetSize()[0];
for(NodeConstIterator nit = graph.m_Nodes.begin();
nit != graph.m_Nodes.end(); ++nit)
{
ContourOperations::PixelList pixels = ContourOperations::GenerateBorderPixels((*nit)->m_Id,
(*nit)->m_Contour,
width);
for (ContourOperations::PixelConstIterator pit = pixels.begin();
pit != pixels.end(); ++pit)
{
index[0] = (*pit) % width;
index[1] = (*pit) / width;
typename RGBImageType::PixelType rgb_pix = rgb_img->GetPixel(index);
for(unsigned int b=0; b<rgb_img->GetNumberOfComponentsPerPixel(); b++)
rgb_pix[b] = 0;
rgb_img->SetPixel(index, rgb_pix);
}
}
RGBImageWriterType::Pointer rgb_writer = RGBImageWriterType::New();
rgb_writer->SetFileName(outputFileName);
rgb_writer->SetInput(rgb_img);
rgb_writer->Update();
}
} // end of namespace lsrm
#endif
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment