void WholeCellSeg::RemoveSmallObjs(){

	typedef itk::LabelGeometryImageFilter< UShortImageType, UShortImageType > GeometryFilterType;
	typedef itk::LabelStatisticsImageFilter< UShortImageType,UShortImageType > StatisticsFilterType;
	typedef itk::CastImageFilter< UShortImageType, UShortImageType > CastUSUSType;
	typedef itk::ImageRegionIteratorWithIndex< UShortImageType > IteratorType;
	typedef GeometryFilterType::LabelIndicesType labelindicestype;

	std::vector< unsigned short > labelsList;

	GeometryFilterType::Pointer geomfilt1 = GeometryFilterType::New();
	geomfilt1->SetInput( seg_im_out );
	geomfilt1->SetCalculatePixelIndices( true );
	geomfilt1->Update();
	labelsList = geomfilt1->GetLabels();

	StatisticsFilterType::Pointer statsfilt = StatisticsFilterType::New();
	statsfilt->UseHistogramsOn();

	statsfilt->SetInput( intermediate_bin_im_out );
	statsfilt->SetLabelInput( seg_im_out );
	statsfilt->Update();

	CastUSUSType::Pointer castUSUSfilter = CastUSUSType::New();

	if( draw_real_bounds && draw_synth_bounds ){
		castUSUSfilter->SetInput( nuclab_inp );
		castUSUSfilter->Update();
		nuclab_inp_cpy = castUSUSfilter->GetOutput();
	}

	for( unsigned short i=0; i<labelsList.size(); ++i ){
		if( !labelsList[i] ) continue;
		labelindicestype indices1;
		indices1 = geomfilt1->GetPixelIndices( labelsList[i] );
		if( !(statsfilt->GetSum( labelsList[i] )) ){
			IteratorType iterator ( seg_im_out, seg_im_out->GetRequestedRegion() );
			for( labelindicestype::const_iterator itPixind = indices1.begin(); itPixind != indices1.end(); ++itPixind ){
				iterator.SetIndex( *itPixind );
				iterator.Set( 0 );
			}
		}
		else if( draw_real_bounds && draw_synth_bounds ){
			IteratorType iterator1 ( nuclab_inp_cpy, nuclab_inp_cpy->GetRequestedRegion() );
			for( labelindicestype::const_iterator itPixind = indices1.begin(); itPixind != indices1.end(); ++itPixind ){
				iterator1.SetIndex( *itPixind );
				if( iterator1.Get()==labelsList[i] )
					iterator1.Set( 0 );
			}
		}
	}
	if( !draw_synth_bounds && draw_real_bounds )
		seg_done = 1;
}
void otb::Wrapper::ObjectsRadiometricStatistics::DoExecute()
{
	VectorImageType::Pointer referenceImage = GetParameterImage("im");

	otb::ogr::DataSource::Pointer ogrDS;
	ogrDS = otb::ogr::DataSource::New(GetParameterString("in"), otb::ogr::DataSource::Modes::Update_LayerUpdate);

	m_OGRDataSourceRendering = OGRDataSourceToMapFilterType::New();
	m_OGRDataSourceRendering->AddOGRDataSource(ogrDS);

	m_OGRDataSourceRendering->SetOutputSize(referenceImage->GetLargestPossibleRegion().GetSize());
	m_OGRDataSourceRendering->SetOutputOrigin(referenceImage->GetOrigin());

	m_OGRDataSourceRendering->SetOutputSpacing(referenceImage->GetSpacing());

	m_OGRDataSourceRendering->SetOutputProjectionRef(referenceImage->GetProjectionRef());

	//	m_OGRDataSourceRendering->SetOutputParametersFromImage(referenceImage); // A tester

	m_OGRDataSourceRendering->SetBackgroundValue(GetParameterInt("background"));
	m_OGRDataSourceRendering->SetBurnAttributeMode(true);
	m_OGRDataSourceRendering->SetBurnAttribute(GetParameterString("field"));

	// Write label image from OGR
	/*
	   WriterType::Pointer writer = WriterType::New(); 
	   writer->SetInput(m_OGRDataSourceRendering->GetOutput());	
	   writer->SetFileName("label_image.tif");
	   writer->Update();
	 */

	// Label image from OGR to statistics label map
	ConverterStatisticsType::Pointer converterStats = ConverterStatisticsType::New(); 
	converterStats->SetInput(m_OGRDataSourceRendering->GetOutput()); 
	converterStats->SetBackgroundValue(GetParameterInt("background")); 
	converterStats->Update();

	// Prepare channel extraction

	ExtractROIFilterType::Pointer m_ExtractROIFilter = ExtractROIFilterType::New();
	m_ExtractROIFilter->SetInput(referenceImage);

	// Update dataset with new fields

	otb::ogr::Layer layer = ogrDS->GetLayerChecked(0);

	OGRFieldDefn fieldNbPixels("NbPixels", OFTInteger);
	layer.CreateField(fieldNbPixels, true);

	OGRFieldDefn fieldFlatness("Flat", OFTReal);
	layer.CreateField(fieldFlatness, true);

	OGRFieldDefn fieldRoundness("Round", OFTReal);
	layer.CreateField(fieldRoundness, true);

	OGRFieldDefn fieldElongation("Elong", OFTReal);
	layer.CreateField(fieldElongation, true);

	OGRFieldDefn fieldPerimeter("Perim", OFTReal);
	layer.CreateField(fieldPerimeter, true);

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"meanB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"stdB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"MedB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"VarB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"KurtB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		std::ostringstream fieldoss;
		fieldoss<<"SkewB"<<i+1;
		OGRFieldDefn field(fieldoss.str().c_str(), OFTReal);
		layer.CreateField(field, true);
	}

	for(unsigned int i = 0; i < referenceImage->GetNumberOfComponentsPerPixel(); i++)
	{
		// Channel selection

		m_ExtractROIFilter->SetChannel(i + 1);

		// Statistics computation
		StatisticsFilterType::Pointer statistics = StatisticsFilterType::New(); 
		statistics->SetInput(converterStats->GetOutput());
		statistics->SetFeatureImage(m_ExtractROIFilter->GetOutput());
		statistics->SetComputePerimeter(true);
		statistics->Update();

		// Write shape attributes only one time
		if(i==0)
		{
			for(otb::ogr::Layer::iterator featIt = layer.begin(); featIt!=layer.end(); ++featIt)
			{
				otb::ogr::Feature m_Feature = *featIt;

				unsigned int label = m_Feature.ogr().GetFieldAsInteger(layer.GetLayerDefn().GetFieldIndex(GetParameterString("field").c_str()));

				if(statistics->GetOutput()->HasLabel(label))
				{
					const StatisticsLabelObjectType *labelObjectStats = statistics->GetOutput()->GetLabelObject(label);

					m_Feature.ogr().SetField("NbPixels", (int)labelObjectStats->GetNumberOfPixels());
					m_Feature.ogr().SetField("Flat", labelObjectStats->GetFlatness());
					m_Feature.ogr().SetField("Round", labelObjectStats->GetRoundness());
					m_Feature.ogr().SetField("Elong", labelObjectStats->GetElongation());
					m_Feature.ogr().SetField("Perim", labelObjectStats->GetPerimeter());

					layer.SetFeature(m_Feature);
				}
			}	
		}

		// Features iteration
		for(otb::ogr::Layer::iterator featIt = layer.begin(); featIt!=layer.end(); ++featIt)
		{
			otb::ogr::Feature m_Feature = *featIt;

			unsigned int label = m_Feature.ogr().GetFieldAsInteger(layer.GetLayerDefn().GetFieldIndex(GetParameterString("field").c_str()));

			if(statistics->GetOutput()->HasLabel(label))
			{
				const StatisticsLabelObjectType *labelObjectStats = statistics->GetOutput()->GetLabelObject(label);
				std::ostringstream fieldoss;

				fieldoss<<"meanB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetMean());
				fieldoss.str("");	

				fieldoss<<"stdB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetStandardDeviation());
				fieldoss.str("");

				fieldoss<<"medB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetMedian());
				fieldoss.str("");	

				fieldoss<<"varB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetVariance());
				fieldoss.str("");	

				fieldoss<<"kurtB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetKurtosis());
				fieldoss.str("");	

				fieldoss<<"skewB"<<i+1;
				m_Feature.ogr().SetField(fieldoss.str().c_str(),labelObjectStats->GetSkewness());
				fieldoss.str("");	
			}
			else
			{
				otbAppLogINFO( << "Object number " << label << " is skipped. This could happen during the rasterisation process when an object is smaller than 1 pixel.");
			}
		}
	}
}
void otb::Wrapper::Aggregate::DoExecute()
{
    // Récupération de la labelmap
    LabelImageType::Pointer labelIn = GetParameterUInt32Image("inseg");
    labelIn->SetRequestedRegionToLargestPossibleRegion();
    labelIn->Update();

    // Filtre statistique pour récupérer le nombre de label dans la labelmap
    StatisticsImageFilterType::Pointer stats = StatisticsImageFilterType::New();
    stats->SetInput(labelIn);
    stats->Update();
    unsigned int regionCount=stats->GetMaximum();

    otbAppLogINFO(<<"Number of objects: "<<regionCount);

    //Récupération de la classification et statistique pour connaître le nombre de classes
    ImageType::Pointer imageIn = GetParameterUInt32Image("in");
    stats->SetInput(imageIn);
    stats->Update();
    unsigned int nbclass=stats->GetMaximum()-stats->GetMinimum()+1;
    otbAppLogINFO(<<"Number of classes: "<<nbclass);
    unsigned int minimum =stats->GetMinimum();
    otbAppLogINFO(<<"Minimum: "<<minimum);

    // Filtre LabelImage vers LabelMap(StatisticsLabelObject)
    ConverterStatisticsType::Pointer converterStats = ConverterStatisticsType::New();
    converterStats->SetInput(labelIn);
    converterStats->SetBackgroundValue(0);
    converterStats->Update();

    // Calcul des statistiques par objet de la LabelMap
    StatisticsFilterType::Pointer statistics = StatisticsFilterType::New();
    statistics->SetInput(converterStats->GetOutput());
    statistics->SetFeatureImage(imageIn);
    statistics->SetNumberOfBins(nbclass);
    statistics->Update();

    // Définition du filtre ChangeLabel
    m_ChangeLabelFilter = ChangeLabelImageFilterType::New();
    m_ChangeLabelFilter->SetInput(labelIn);

    // Iteration sur les objets, récupération de l'histogramme, extraction de la valeur mojoritaire
    // Changement de la valeur du label par la valeur majoritaire dans la label map => obtention d'une classification corrigée

    for(unsigned int i=0; i<regionCount+1; i++)
    {
        if(statistics->GetOutput()->HasLabel(i))
        {
            const StatisticsLabelObjectType *labelObjectStats = statistics->GetOutput()->GetLabelObject(i);
            const HistogramType *histogram = labelObjectStats->GetHistogram();

            unsigned int var = 0;
            unsigned int classe = minimum;
            for(unsigned int j=0; j< nbclass; j++)
            {
                if(histogram->GetFrequency(j)>var)
                {
                    var = histogram->GetFrequency(j);
                    classe = j+minimum;
                }
            }
            m_ChangeLabelFilter->SetChange(i,classe);
        }
    }

    SetParameterOutputImage("outim", m_ChangeLabelFilter->GetOutput());

    //Vectorisation
    otbAppLogINFO(<<"Vectorization...");

    //Définition du shapefile
    const std::string shapefile = GetParameterString("out");

    otb::ogr::DataSource::Pointer ogrDS;
    otb::ogr::Layer layer(NULL, false);

    std::string projRef = imageIn->GetProjectionRef();

    OGRSpatialReference oSRS(projRef.c_str());

    otbAppLogINFO(<< projRef);

    std::vector<std::string> options;

    ogrDS = otb::ogr::DataSource::New(shapefile, otb::ogr::DataSource::Modes::Overwrite);
    std::string layername = itksys::SystemTools::GetFilenameName(shapefile.c_str());
    std::string const extension = itksys::SystemTools::GetFilenameLastExtension(shapefile.c_str());
    layername = layername.substr(0,layername.size()-(extension.size()));
    layer = ogrDS->CreateLayer(layername, &oSRS, wkbMultiPolygon, options);

    OGRFieldDefn labelField("label", OFTInteger);
    layer.CreateField(labelField, true);
    OGRFieldDefn MajorityField("Majority", OFTInteger);
    layer.CreateField(MajorityField, true);

    // Write label image
    /*
    WriterType::Pointer writer = WriterType::New();
    writer->SetInput(m_ChangeLabelFilter->GetOutput());
    writer->SetFileName("label_image.tif");
    writer->Update();
    */

    // Filtre LabelImage vers OGRDataSource
    LabelImageToOGRDataSourceFilterType::Pointer labelToOGR = LabelImageToOGRDataSourceFilterType::New();
    labelToOGR->SetInput(m_ChangeLabelFilter->GetOutput());
    labelToOGR->SetInputMask(m_ChangeLabelFilter->GetOutput());		// La classe 0  est considérée comme du background et n'est pas vectorisée
    labelToOGR->SetFieldName("Majority");
    labelToOGR->Update();

    otb::ogr::DataSource::ConstPointer ogrDSTmp = labelToOGR->GetOutput();
    otb::ogr::Layer layerTmp = ogrDSTmp->GetLayerChecked(0);

    otb::ogr::Layer::const_iterator featIt = layerTmp.begin();

    int nveau_label = 1;
    for(; featIt!=layerTmp.end(); ++featIt)
    {
        otb::ogr::Feature dstFeature(layer.GetLayerDefn());
        dstFeature.SetFrom( *featIt, TRUE );
        layer.CreateFeature( dstFeature );
        dstFeature.ogr().SetField("label",nveau_label);
        layer.SetFeature(dstFeature);
        nveau_label +=1;
    }

    otbAppLogINFO(<<"Processing complete.");
}