grmGraphToOtbImage.txx 3.66 KB
/*=========================================================================

  Program: Generic Region Merging Library
  Language: C++
  author: Lassalle Pierre
  contact: lassallepierre34@gmail.com



  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved


     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef GRM_GRAPH_TO_OTBIMAGE_TXX
#define GRM_GRAPH_TO_OTBIMAGE_TXX
#include "grmGraphToOtbImage.h"
#include "itkImageRegionIterator.h"
#include "itkGrayscaleFillholeImageFilter.h"

namespace grm
{
	template<class TGraph>
	typename GraphToOtbImage<TGraph>::LabelImageType::Pointer
	GraphToOtbImage<TGraph>::GetLabelImage(const GraphType& graph,
										   const unsigned int width,
										   const unsigned int height)
	{
		LabelImageType::IndexType index;
		LabelImageType::SizeType size;
		LabelImageType::RegionType region;

		index[0] = 0; index[1] = 0;
		size[0] = width; size[1] = height;
		region.SetIndex(index);
		region.SetSize(size);

		LabelImageType::Pointer label_img = LabelImageType::New();
		label_img->SetRegions(region);
		label_img->Allocate();
		label_img->FillBuffer(0);
		
		// Start at 1 (value 0 can be used for invalid pixels)
		unsigned int label = 1;
		for(auto& node : graph.m_Nodes)
		{
			lp::CellLists borderPixels;
			ContourOperator::GenerateBorderCells(borderPixels, node->m_Contour, node->m_Id, width);
			
			for (auto& pix: borderPixels)
			{
				index[0] = pix % width;
				index[1] = pix / width;
				label_img->SetPixel(index, label);
			}
			++label;
		}

		// Fill holes
		typedef itk::GrayscaleFillholeImageFilter<LabelImageType,LabelImageType>  FillholeFilterType;
		FillholeFilterType::Pointer fillFilter = FillholeFilterType::New();
		fillFilter->SetInput(label_img);
		fillFilter->Update();
		
		return fillFilter->GetOutput();
	}

	template<class TGraph>
	typename GraphToOtbImage<TGraph>::ClusteredImageType::Pointer
	GraphToOtbImage<TGraph>::GetClusteredOutput(const GraphType& graph,
												const unsigned int width,
												const unsigned int height)
	{
		ClusteredImageType::IndexType index;
		ClusteredImageType::SizeType size;
		ClusteredImageType::RegionType region;

		index[0] = 0; index[1] = 0;
		size[0] = width; size[1] = height;
		region.SetIndex(index);
		region.SetSize(size);

		ClusteredImageType::Pointer clusterImg = ClusteredImageType::New();
		clusterImg->SetRegions(region);
		clusterImg->SetNumberOfComponentsPerPixel(3);
		clusterImg->Allocate();

		ClusteredImageType::PixelType pixelValue;
		pixelValue.SetSize(3);
		pixelValue.Fill(255);

		clusterImg->FillBuffer(pixelValue);
		LabelImageType::Pointer label_img = this->GetLabelImage(graph, width, height);

		typedef typename itk::ImageRegionConstIterator<LabelImageType> LabelImageIteratorType;
		typedef typename itk::ImageRegionIterator<ClusteredImageType> ClusteredImageIteratorType;

		LabelImageIteratorType it1 (label_img, region);
		ClusteredImageIteratorType it2 (clusterImg, region);

		// Generate a random color vector
		srand(time(NULL));
		std::vector<double> colorMap;
		colorMap.reserve(graph.m_Nodes.size());
		std::generate_n(std::back_inserter(colorMap), graph.m_Nodes.size(), rand);

		for (it1.GoToBegin(), it2.GoToBegin() ; !it1.IsAtEnd() ; ++it1, ++it2)
		  {
		  pixelValue[0] = colorMap[it1.Get()];
          pixelValue[1] = (16807 * pixelValue[0]) % 255 ;
          pixelValue[2] = (16807 * pixelValue[1]) % 255 ;
          it2.Set(pixelValue);
		  }
		
		return clusterImg;
	}
		
} // end of namespace grm
#endif