Commit a77b7b5f9c829187d65dfa082b78032add1f9403

Authored by Pierre Lassalle
1 parent 3f558e48
Exists in master

OTB friendly version

Applications/RegionMergingSegmentation.cxx
1 1 #include <iostream>
2 2 #include <otbImage.h>
3   -#include <otbImageFileReader.h>
4 3 #include <otbVectorImage.h>
  4 +#include <otbImageFileReader.h>
  5 +#include <otbImageFileWriter.h>
5 6 #include "lsrmBaatzSegmenter.h"
6 7  
7 8 int main(int argc, char *argv[])
... ... @@ -20,26 +21,45 @@ int main(int argc, char *argv[])
20 21 }
21 22  
22 23 lsrm::BaatzParam params;
23   - const char * input_image = argv[1];
24   - const char * clustered_image = argv[2];
25   - const char * label_image = argv[3];
  24 + const char * inFileName = argv[1];
  25 + const char * clusterFileName = argv[2];
  26 + const char * labelFileName = argv[3];
26 27 params.m_SpectralWeight = atof(argv[4]);
27 28 params.m_ShapeWeight = atof(argv[5]);
28 29 float sqrt_scale = atof(argv[6]);
29 30 const float scale = sqrt_scale * sqrt_scale;
30 31  
31 32 typedef float PixelType;
32   - typedef otb::VectorImage<PixelType, 2> ImageType;
33   - typedef lsrm::BaatzSegmenter<ImageType> SegmenterType;
  33 + typedef unsigned long int LabelPixelType;
  34 + typedef unsigned char ClusterPixelType;
  35 + typedef otb::VectorImage<PixelType, 2> InputImageType;
  36 + typedef otb::Image<LabelPixelType, 2> LabelImageType;
  37 + typedef otb::VectorImage<ClusterPixelType, 2> ClusterImageType;
  38 + typedef otb::ImageFileReader<InputImageType> InputImageReaderType;
  39 + typedef otb::ImageFileWriter<LabelImageType> LabelImageWriterType;
  40 + typedef otb::ImageFileWriter<ClusterImageType> ClusterImageWriterType;
  41 + typedef lsrm::BaatzSegmenter<InputImageType> SegmenterType;
  42 +
  43 + auto imgReader = InputImageReaderType::New();
  44 + imgReader->SetFileName(inFileName);
  45 + imgReader->Update();
34 46  
  47 +
35 48 SegmenterType segmenter;
36 49 segmenter.SetParam(params);
37 50 segmenter.SetThreshold(scale);
38   - segmenter.SetInputFileName(input_image);
39   - segmenter.SetClusteredImageFileName(clustered_image);
40   - segmenter.SetLabelImageFileName(label_image);
41   -
42   - segmenter.RunSegmentation();
  51 + segmenter.SetInput(imgReader->GetOutput());
  52 + segmenter.Update();
  53 +
  54 + auto labelWriter = LabelImageWriterType::New();
  55 + labelWriter->SetFileName(labelFileName);
  56 + labelWriter->SetInput(segmenter.GetLabeledClusteredOutput());
  57 + labelWriter->Update();
  58 +
  59 + auto clusterWriter = ClusterImageWriterType::New();
  60 + clusterWriter->SetFileName(clusterFileName);
  61 + clusterWriter->SetInput(segmenter.GetClusteredImageOutput());
  62 + clusterWriter->Update();
43 63  
44 64 return 0;
45 65 }
... ... @@ -50,3 +70,5 @@ int main(int argc, char *argv[])
50 70  
51 71  
52 72  
  73 +
  74 +
... ...
Code/lsrmBaatzSegmenter.h
1 1 #ifndef __LSRM_BAATZ_SEGMENTER_H
2 2 #define __LSRM_BAATZ_SEGMENTER_H
3 3 #include "lsrmSegmenter.h"
4   -#include "lsrmGraphToOtbImage.h"
5 4 /*
6 5 * Tutorial : Implementation of the Baatz & Schape criterion
7 6 *
... ... @@ -88,7 +87,7 @@ namespace lsrm
88 87  
89 88 BaatzSegmenter();
90 89  
91   - void RunSegmentation();
  90 + void Update();
92 91 float ComputeMergingCost(NodePointerType n1, NodePointerType n2);
93 92 void UpdateSpecificAttributes(NodePointerType n1, NodePointerType n2);
94 93 void InitFromImage();
... ...
Code/lsrmBaatzSegmenter.txx
... ... @@ -17,19 +17,14 @@ namespace lsrm
17 17 void
18 18 BaatzSegmenter<TImage>::InitFromImage()
19 19 {
20   - typedef otb::ImageFileReader<TImage> ImageReaderType;
21 20 typedef itk::ImageRegionIterator<TImage> ImageIterator;
22 21  
23   - typename ImageReaderType::Pointer reader = ImageReaderType::New();
24   - reader->SetFileName(this->m_InputFileName);
25   - reader->Update();
26   -
27   - this->m_ImageWidth = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0];
28   - this->m_ImageHeight = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1];
29   - this->m_NumberOfComponentsPerPixel = reader->GetOutput()->GetNumberOfComponentsPerPixel();
  22 + this->m_ImageWidth = this->m_InputImage->GetLargestPossibleRegion().GetSize()[0];
  23 + this->m_ImageHeight =this->m_InputImage->GetLargestPossibleRegion().GetSize()[1];
  24 + this->m_NumberOfComponentsPerPixel = this->m_InputImage->GetNumberOfComponentsPerPixel();
30 25  
31 26 std::size_t idx = 0;
32   - ImageIterator it(reader->GetOutput(), reader->GetOutput()->GetLargestPossibleRegion());
  27 + ImageIterator it(this->m_InputImage, this->m_InputImage->GetLargestPossibleRegion());
33 28 for(it.GoToBegin(); !it.IsAtEnd(); ++it)
34 29 {
35 30 this->m_Graph.m_Nodes[idx]->m_Means.reserve(this->m_NumberOfComponentsPerPixel);
... ... @@ -112,34 +107,34 @@ namespace lsrm
112 107  
113 108 template<class TImage>
114 109 void
115   - BaatzSegmenter<TImage>::RunSegmentation()
  110 + BaatzSegmenter<TImage>::Update()
116 111 {
117   - GraphOperatorType::InitNodes(this->m_Graph, *this, this->m_InputFileName, FOUR);
118   -
119   - bool prev_merged =
120   - GraphOperatorType::PerfomAllIterationsWithLMBFAndConstThreshold(this->m_Graph, *this,
121   - this->m_Threshold, this->m_NumberOfIterations,
122   - this->m_ImageWidth, this->m_ImageHeight);
123   -
124   - if(prev_merged && this->m_DoBFSegmentation)
  112 + GraphOperatorType::InitNodes(this->m_InputImage, this->m_Graph, *this, FOUR);
  113 + bool prev_merged = false;
  114 +
  115 + if(this->m_NumberOfIterations > 0)
125 116 {
126 117 prev_merged =
127   - GraphOperatorType::PerfomAllIterationsWithBFAndConstThreshold(this->m_Graph, *this,
128   - this->m_Threshold, this->m_NumberOfIterations,
129   - this->m_ImageWidth, this->m_ImageHeight);
130   - }
  118 + GraphOperatorType::PerfomAllIterationsWithLMBFAndConstThreshold(this->m_Graph, *this,
  119 + this->m_Threshold, this->m_NumberOfIterations,
  120 + this->m_ImageWidth, this->m_ImageHeight);
131 121  
132   - if(!this->m_ClusteredImageFileName.empty())
133   - IOType::WriteOutputRGBImage(this->m_Graph,
134   - this->m_ImageWidth,
135   - this->m_ImageHeight,
136   - this->m_ClusteredImageFileName);
137   -
138   - if(!this->m_LabelImageFileName.empty())
139   - IOType::WriteLabelImage(this->m_Graph,
140   - this->m_ImageWidth,
141   - this->m_ImageHeight,
142   - this->m_LabelImageFileName);
  122 + if(prev_merged && this->m_DoBFSegmentation)
  123 + {
  124 + prev_merged =
  125 + GraphOperatorType::PerfomAllIterationsWithBFAndConstThreshold(this->m_Graph, *this,
  126 + this->m_Threshold, this->m_NumberOfIterations,
  127 + this->m_ImageWidth, this->m_ImageHeight);
  128 + }
  129 + }
  130 + else
  131 + {
  132 + assert(this->m_DoBFSegmentation == true);
  133 + prev_merged =
  134 + GraphOperatorType::PerfomAllIterationsWithBFAndConstThreshold(this->m_Graph, *this,
  135 + this->m_Threshold, this->m_NumberOfIterations,
  136 + this->m_ImageWidth, this->m_ImageHeight);
  137 + }
143 138 }
144 139 } // end of namespace lsrm
145 140  
... ...
Code/lsrmGraphOperations.h
... ... @@ -18,6 +18,7 @@ namespace lsrm
18 18  
19 19 /* Some convenient typedefs */
20 20 typedef TSegmenter SegmenterType;
  21 + typedef typename SegmenterType::ImageType ImageType;
21 22 typedef typename SegmenterType::GraphType GraphType;
22 23 typedef typename GraphType::NodeType NodeType;
23 24 typedef typename GraphType::EdgeType EdgeType;
... ... @@ -40,9 +41,9 @@ namespace lsrm
40 41 * const unsigned int height: height of the input image
41 42 * CONNECTIVITY mask : mask of the neighborhood (4X4 or 8X8)
42 43 */
43   - static void InitNodes(GraphType& graph,
  44 + static void InitNodes(ImageType * inputImg,
  45 + GraphType& graph,
44 46 SegmenterType& seg,
45   - const std::string& inputFileName,
46 47 CONNECTIVITY mask);
47 48  
48 49 /*
... ...
Code/lsrmGraphOperations.txx
... ... @@ -5,22 +5,16 @@
5 5 namespace lsrm
6 6 {
7 7 template<class TSegmenter>
8   - void GraphOperations<TSegmenter>::InitNodes(GraphType& graph,
  8 + void GraphOperations<TSegmenter>::InitNodes(ImageType * inputImg,
  9 + GraphType& graph,
9 10 SegmenterType& seg,
10   - const std::string& inputFileName,
11 11 CONNECTIVITY mask)
12 12 {
13 13 unsigned int width, height;
14 14  
15 15 {
16   - typedef typename TSegmenter::ImageType ImageType;
17   - typedef otb::ImageFileReader<ImageType> ReaderType;
18   - typename ReaderType::Pointer reader = ReaderType::New();
19   - reader->SetFileName(inputFileName);
20   - reader->UpdateOutputInformation();
21   -
22   - width = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[0];
23   - height = reader->GetOutput()->GetLargestPossibleRegion().GetSize()[1];
  16 + width = inputImg->GetLargestPossibleRegion().GetSize()[0];
  17 + height = inputImg->GetLargestPossibleRegion().GetSize()[1];
24 18 }
25 19  
26 20 const long unsigned int num_nodes = width * height;
... ... @@ -430,17 +424,25 @@ namespace lsrm
430 424 const unsigned int height)
431 425 {
432 426 bool merged = true;
  427 + unsigned int maxNumberOfIterations;
  428 + if(numberOfIterations < 1)
  429 + maxNumberOfIterations = 75;
  430 + else
  431 + maxNumberOfIterations = numberOfIterations;
  432 +
433 433 unsigned int iterations = 0;
434 434  
435 435 while(merged &&
436   - iterations < numberOfIterations &&
  436 + iterations < maxNumberOfIterations &&
437 437 graph.m_Nodes.size() > 1)
438 438 {
  439 + std::cout << "." << std::flush;
439 440 ++iterations;
440 441  
441 442 merged = PerfomOneIterationWithBF(graph, seg, threshold,
442 443 width, height);
443 444 }
  445 + std::cout << std::endl;
444 446  
445 447 if(graph.m_Nodes.size() < 2)
446 448 return false;
... ... @@ -457,3 +459,6 @@ namespace lsrm
457 459  
458 460  
459 461  
  462 +
  463 +
  464 +
... ...
Code/lsrmGraphToOtbImage.h
1 1 #ifndef __LSRM_GRAPH_TO_OTBIMAGE_H
2 2 #define __LSRM_GRAPH_TO_OTBIMAGE_H
3 3 #include <itkRGBPixel.h>
  4 +#include <itkImageRegion.h>
4 5 #include <otbImage.h>
5 6 #include <otbVectorImage.h>
6 7 #include <otbImageFileReader.h>
... ... @@ -22,38 +23,19 @@ namespace lsrm
22 23 typedef typename GraphType::NodeType NodeType;
23 24 typedef std::vector< boost::shared_ptr<NodeType> > NodeList;
24 25 typedef typename NodeList::const_iterator NodeConstIterator;
  26 + typedef unsigned long int LabelPixelType;
  27 + typedef otb::Image<LabelPixelType, 2> LabelImageType;
  28 + typedef unsigned char ClusterPixelType;
  29 + typedef otb::VectorImage<ClusterPixelType, 2> ClusteredImageType;
  30 +
25 31  
26   - /*
27   - * Given a graph of nodes and the size of the image, it returns
28   - * a raster image where to every pixel of a region is assigned
29   - * the same unique label value.
30   - *
31   - * @params
32   - * const GraphType& graph : graph of nodes
33   - * const unsigned int width : width of the output labeled image.
34   - * const unsigned int height : height of the output labeled image.
35   - * const std::string& outputFileName : filename of the output image.
36   - */
37   - static void WriteLabelImage(const GraphType& graph,
38   - const unsigned int width,
39   - const unsigned int height,
40   - const std::string& outputFileName);
  32 + LabelImageType::Pointer GetLabelImage(const GraphType& graph,
  33 + const unsigned int width,
  34 + const unsigned int height);
41 35  
42   - /*
43   - * Given a graph of nodes and the size of the image, it returns
44   - * a raster image where to every pixel of a region is assigned
45   - * the same rgb color.
46   - *
47   - * @params
48   - * const GraphType& graph : graph of nodes
49   - * const unsigned int width : width of the output rgb image.
50   - * const unsigned int height : height of the output rgb image.
51   - * const std::string& outputFileName : filename of the output image.
52   - */
53   - static void WriteOutputRGBImage(const GraphType& graph,
54   - const unsigned int width,
55   - const unsigned int height,
56   - const std::string& outputFileName);
  36 + ClusteredImageType::Pointer GetClusteredOutput(const GraphType& graph,
  37 + const unsigned int width,
  38 + const unsigned int height);
57 39 };
58 40  
59 41 } // end of namespace lsrm
... ...
Code/lsrmGraphToOtbImage.txx
... ... @@ -5,15 +5,11 @@
5 5 namespace lsrm
6 6 {
7 7 template<class TGraph>
8   - void GraphToOtbImage<TGraph>::WriteLabelImage(const GraphType& graph,
9   - const unsigned int width,
10   - const unsigned int height,
11   - const std::string& outputFileName)
  8 + typename GraphToOtbImage<TGraph>::LabelImageType::Pointer
  9 + GraphToOtbImage<TGraph>::GetLabelImage(const GraphType& graph,
  10 + const unsigned int width,
  11 + const unsigned int height)
12 12 {
13   - typedef long unsigned int LabelPixelType;
14   -
15   - typedef otb::Image<LabelPixelType, 2> LabelImageType;
16   -
17 13 LabelImageType::IndexType index;
18 14 LabelImageType::SizeType size;
19 15 LabelImageType::RegionType region;
... ... @@ -41,51 +37,31 @@ namespace lsrm
41 37 ++label;
42 38 }
43 39  
44   - typedef otb::ImageFileWriter<LabelImageType> LabelWriterType;
45   - LabelWriterType::Pointer label_writer = LabelWriterType::New();
46   - label_writer->SetInput(label_img);
47   - label_writer->SetFileName(outputFileName);
48   - label_writer->Update();
  40 + return label_img;
49 41 }
50 42  
51 43 template<class TGraph>
52   - void GraphToOtbImage<TGraph>::WriteOutputRGBImage(const GraphType& graph,
53   - const unsigned int width,
54   - const unsigned int height,
55   - const std::string& outputFileName)
  44 + typename GraphToOtbImage<TGraph>::ClusteredImageType::Pointer
  45 + GraphToOtbImage<TGraph>::GetClusteredOutput(const GraphType& graph,
  46 + const unsigned int width,
  47 + const unsigned int height)
56 48 {
57   - typedef unsigned char RGBPixelType;
58   -
59   - typedef otb::VectorImage<RGBPixelType, 2> RGBImageType;
60   - typename RGBImageType::PixelType pixelValue;
61   -
62   - RGBImageType::IndexType index;
63   - RGBImageType::SizeType size;
64   - RGBImageType::RegionType region;
  49 + ClusteredImageType::IndexType index;
  50 + ClusteredImageType::SizeType size;
  51 + ClusteredImageType::RegionType region;
65 52  
66 53 index[0] = 0; index[1] = 0;
67 54 size[0] = width; size[1] = height;
68 55 region.SetIndex(index);
69 56 region.SetSize(size);
70 57  
71   - RGBImageType::Pointer rgb_img = RGBImageType::New();
72   - rgb_img->SetRegions(region);
73   - rgb_img->SetNumberOfComponentsPerPixel(3);
74   - rgb_img->Allocate();
75   - pixelValue.Reserve(3);
76   - pixelValue[0] = 0;
77   - pixelValue[1] = 0;
78   - pixelValue[2] = 0;
  58 + ClusteredImageType::Pointer clusterImg = ClusteredImageType::New();
  59 + clusterImg->SetRegions(region);
  60 + clusterImg->SetNumberOfComponentsPerPixel(3);
  61 + clusterImg->Allocate();
79 62  
80   - for(unsigned int y = 0; y < height; ++y)
81   - {
82   - for(unsigned int x = 0; x < width; ++x)
83   - {
84   - index[0] = x;
85   - index[1] = y;
86   - rgb_img->SetPixel(index, pixelValue);
87   - }
88   - }
  63 + ClusteredImageType::PixelType pixelValue;
  64 + pixelValue.Reserve(3);
89 65  
90 66 srand(time(NULL));
91 67 unsigned char c1, c2, c3;
... ... @@ -101,16 +77,11 @@ namespace lsrm
101 77 pixelValue[0] = c1;
102 78 pixelValue[1] = c2;
103 79 pixelValue[2] = c3;
104   - rgb_img->SetPixel(index, pixelValue);
  80 + clusterImg->SetPixel(index, pixelValue);
105 81 }
106 82 }
107   -
108   - typedef otb::ImageFileWriter<RGBImageType> RGBWriterType;
109   - RGBWriterType::Pointer rgb_writer = RGBWriterType::New();
110   - rgb_writer->SetInput(rgb_img);
111   - rgb_writer->SetFileName(outputFileName);
112   - rgb_writer->Update();
  83 + return clusterImg;
113 84 }
114   -
  85 +
115 86 } // end of namespace lsrm
116 87 #endif
... ...
Code/lsrmSegmenter.h
... ... @@ -3,6 +3,7 @@
3 3 #include "macro-generator.h"
4 4 #include "lsrmGraph.h"
5 5 #include "lsrmGraphOperations.h"
  6 +#include "lsrmGraphToOtbImage.h"
6 7  
7 8 namespace lsrm
8 9 {
... ... @@ -21,6 +22,9 @@ namespace lsrm
21 22 typedef typename GraphType::EdgeType EdgeType;
22 23 typedef GraphOperations<Self> GraphOperatorType;
23 24 typedef typename GraphOperatorType::NodePointerType NodePointerType;
  25 + typedef GraphToOtbImage<GraphType> IOType;
  26 + typedef typename IOType::LabelImageType LabelImageType;
  27 + typedef typename IOType::ClusteredImageType ClusteredImageType;
24 28  
25 29 /* Default constructor and destructor */
26 30  
... ... @@ -30,7 +34,7 @@ namespace lsrm
30 34 /*
31 35 * This method performs the region merging segmentation.
32 36 */
33   - virtual void RunSegmentation() = 0;
  37 + virtual void Update() = 0;
34 38  
35 39 /* methods to overload */
36 40  
... ... @@ -66,17 +70,30 @@ namespace lsrm
66 70 * const std::string& inputFileName : input image path
67 71 */
68 72 virtual void InitFromImage() = 0;
  73 +
  74 + /* Return the label image */
  75 + inline typename LabelImageType::Pointer GetLabeledClusteredOutput()
  76 + {
  77 + IOType io;
  78 + auto labelImg = io.GetLabelImage(this->m_Graph, this->m_ImageWidth, this->m_ImageHeight);
  79 + return labelImg;
  80 + }
  81 +
  82 + inline typename ClusteredImageType::Pointer GetClusteredImageOutput()
  83 + {
  84 + IOType io;
  85 + auto clusteredImg = io.GetClusteredOutput(this->m_Graph, this->m_ImageWidth, this->m_ImageHeight);
  86 + return clusteredImg;
  87 + }
69 88  
70 89 /* Set methods */
71 90 SetMacro(bool, DoBFSegmentation);
72 91 SetMacro(unsigned int, NumberOfIterations);
73 92 SetMacro(float, Threshold);
74 93 SetMacro(ParamType, Param);
75   - SetMacro(std::string, InputFileName);
76   - SetMacro(std::string, ClusteredImageFileName);
77   - SetMacro(std::string, LabelImageFileName);
78   - SetMacro(std::string, ContourImageFileName);
79   -
  94 + inline void SetInput(TImage * in){ m_InputImage = in;}
  95 +
  96 +
80 97 protected:
81 98  
82 99 /* Activate the Best Fitting heuristic */
... ... @@ -98,10 +115,9 @@ namespace lsrm
98 115 unsigned int m_ImageWidth; // Number of columns
99 116 unsigned int m_ImageHeight; // NUmber of rows
100 117 unsigned int m_NumberOfComponentsPerPixel; // Number of spectral bands
101   - std::string m_InputFileName;
102   - std::string m_ClusteredImageFileName;
103   - std::string m_LabelImageFileName;
104   - std::string m_ContourImageFileName;
  118 +
  119 + /* Pointer to the input image to segment */
  120 + TImage * m_InputImage;
105 121 };
106 122 } // end of namespace lsrm
107 123  
... ...