Commit a376e3ff authored by Guillaume Pasero's avatar Guillaume Pasero

Remove EdisonMeanShift module

parent 2de54084
project(OTBEdisonMeanShift)
otb_module_impl()
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
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 __otbMeanShiftImageFilter_h
#define __otbMeanShiftImageFilter_h
#include "vcl_deprecated_header.h"
#include "itkImageToImageFilter.h"
#include "itkVariableLengthVector.h"
#include "otbImage.h"
#include "otbObjectList.h"
#include "otbPolygon.h"
#include "otbLabeledOutputAccessor.h"
namespace otb
{
namespace MeanShift
{
/** \class ScalarBufferConverter
* \brief Small utilities class used for buffer conversion with EDISON standard.
* This class handles buffer conversion when pixel type is scalar.
* \deprecated
*
*
* \ingroup OTBEdisonMeanShift
**/
class ScalarBufferConverter
{
public:
/**
* Fill the pixel with the float array values at index, using nbComp values scaled by scale.
*/
template <class TPixel>
static inline void
FloatArrayToPixel(const float * data, unsigned int index, TPixel& pixel,
const unsigned int /*nbComp*/, double scale)
{
pixel = static_cast<TPixel>(scale * data[index]);
}
/**
* Fill the float array data with the pixel values at index, using nbComp values scaled by scale.
*/
template <class TPixel>
static inline void
PixelToFloatArray(float * data, unsigned int index, const TPixel& pixel, double scale)
{
data[index] = static_cast<float>(scale * pixel);
}
};
}
/** \class MeanShiftImageFilter
*
*
* Mean shift is a data clustering algorithm often used in image processing and segmentation.
* For a given pixel, the mean shift will build a set of neighboring pixels within a given spatial
* radius (can be set using SetSpatialRadius()) and a color range (can be set using SetRangeRadius()).
* The spatial and color center of this set is then computed and the algorithm iterates with this new spatial
* and color center.
*
* Mean shift can be used for edge-preserving smoothing, or for clustering. The GetOutput() method will allow
* you to get the smoothed image, whereas the
* GetClusteredOutput() methods returns the clustered output. The GetLabeledClusteredOutput() returns
* a labeled clustered image, and the GetClusterBoundariesOutput()
* an image of the cluster boundaries.
*
* The MinimumRegionSize parameter allows you to prune small clustered regions.
*
* This filter uses the Edison mean shift algorithm implementation. Please note that data whose precision
* is more than float are casted to float before processing.
*
* The Scale parameter allows you to stretch the data dynamic
*
* For more information on mean shift techniques, one might consider reading the following article:
*
* D. Comaniciu, P. Meer, "Mean Shift: A Robust Approach Toward Feature Space Analysis," IEEE Transactions on
* Pattern Analysis and Machine Intelligence, vol. 24, no. 5, pp. 603-619, May, 2002
* D. Comaniciu, P. Meer, "Robust analysis of feature spaces: color image segmentation," cvpr, p. 750, 1997
* IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR'97), 1997
* D. Comaniciu, P. Meer, "Mean Shift Analysis and Applications," iccv, p. 1197, Seventh International Conference
* on Computer Vision (ICCV'99) - Volume 2, 1999
*
* \deprecated use MeanShiftSegmentationFilter instead
*
* \sa MeanShiftSmootingImageFilter, MeanShiftSegmentationFilter
*
* \ingroup ImageEnhancement
*
* \ingroup OTBEdisonMeanShift
*/
template <class TInputImage, class TOutputImage,
class TLabeledOutput = otb::Image<unsigned short, 2>,
class TBufferConverter = MeanShift::ScalarBufferConverter>
class ITK_EXPORT MeanShiftImageFilter
: public itk::ImageToImageFilter<TInputImage, TOutputImage>
{
public:
/** Standard class typedef */
typedef MeanShiftImageFilter Self;
typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkTypeMacro(MeanShiftImageFilter, ImageToImageFilter);
itkNewMacro(Self);
/** Template parameters typedefs */
typedef TInputImage InputImageType;
typedef typename InputImageType::Pointer InputImagePointerType;
typedef typename InputImageType::PixelType InputPixelType;
typedef typename InputImageType::PointType PointType;
typedef TOutputImage OutputImageType;
typedef typename OutputImageType::Pointer OutputImagePointerType;
typedef typename OutputImageType::PixelType OutputPixelType;
typedef typename OutputImageType::RegionType RegionType;
typedef TLabeledOutput LabeledOutputType;
typedef typename LabeledOutputType::Pointer LabeledOutputPointerType;
typedef typename LabeledOutputType::PixelType LabelType;
/** Typedefs for vectorized output */
typedef otb::Polygon<InputPixelType> PolygonType;
typedef typename PolygonType::Pointer PolygonPointerType;
typedef otb::ObjectList<PolygonType> PolygonListType;
typedef typename PolygonListType::Pointer PolygonListPointerType;
/** Typedef for mean-shift modes map */
typedef std::map<LabelType, InputPixelType> ModeMapType;
/** Setters / Getters */
itkSetMacro(SpatialRadius, unsigned int);
itkGetMacro(SpatialRadius, unsigned int);
itkSetMacro(RangeRadius, double);
itkGetMacro(RangeRadius, double);
itkSetMacro(MinimumRegionSize, unsigned int);
itkGetMacro(MinimumRegionSize, unsigned int);
itkSetMacro(Scale, double);
itkGetMacro(Scale, double);
/** Return the const clustered image output */
const OutputImageType * GetClusteredOutput() const;
/** Return the clustered image output */
OutputImageType * GetClusteredOutput();
/** Return the const labeled clustered image output */
const LabeledOutputType * GetLabeledClusteredOutput() const;
/** Return the labeled clustered image output */
LabeledOutputType * GetLabeledClusteredOutput();
/** Return the const cluster boundaries image output */
const LabeledOutputType * GetClusterBoundariesOutput() const;
/** Return the cluster boundaries image output */
LabeledOutputType * GetClusterBoundariesOutput();
/** Return the mean-shift mode by label */
const ModeMapType& GetModes()
{
return m_Modes;
}
protected:
virtual void EnlargeOutputRequestedRegion( itk::DataObject *output );
virtual void GenerateData();
/** Allocate the outputs (need to be reimplemented since outputs have differents type) */
virtual void AllocateOutputs();
/** If modified, we have to reset the list of modes */
virtual void Modified() const
{
Superclass::Modified();
m_Modes.clear();
}
/** Constructor */
MeanShiftImageFilter();
/** destructor */
virtual ~MeanShiftImageFilter() {}
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
private:
MeanShiftImageFilter(const Self &); //purposely not implemented
void operator =(const Self&); //purposely not implemented
/** Spatial radius for mean shift convergence */
unsigned int m_SpatialRadius;
/** Range radius for mean shift convergence */
double m_RangeRadius;
/** Minimum region size in pixels for clustering */
unsigned int m_MinimumRegionSize;
/** Data scale (used to stretch data range) */
double m_Scale;
/** A map of the different modes by segmented regions */
mutable ModeMapType m_Modes;
};
/**
* \class LabeledOutputAccessor
* \brief Specialized class to get the index of the labeled output image in mean shift filter.
*
* \ingroup OTBEdisonMeanShift
*/
template <class TInputImage, class TOutputImage, class TLabeledImage, class TBufferConverter>
class LabeledOutputAccessor<MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage, TBufferConverter> >
{
public:
typedef typename MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledImage, TBufferConverter>::LabeledOutputType LabelImageType;
itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2);
};
} // end namespace otb
#ifndef OTB_MANUAL_INSTANTIATION
#include "otbMeanShiftImageFilter.txx"
#endif
#endif
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
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 __otbMeanShiftVectorImageFilter_h
#define __otbMeanShiftVectorImageFilter_h
#include "vcl_deprecated_header.h"
#include "otbMeanShiftImageFilter.h"
namespace otb
{
namespace MeanShift
{
/** \class ScalarBufferConverter
* \brief Small utilities class used for buffer conversion with EDISON standard.
* This class handles buffer conversion when pixel type is scalar.
* \deprecated
*
* \ingroup OTBEdisonMeanShift
**/
class VectorBufferConverter
{
public:
/**
* Fill the pixel with the float array values at index, using nbComp values scaled by scale.
*/
template <class TPixel> static inline void FloatArrayToPixel(const float * data,
unsigned int index,
TPixel& pixel,
const unsigned int nbComp,
double scale)
{
pixel.SetSize(nbComp);
for (unsigned int i = 0; i < pixel.Size(); ++i)
{
pixel[i] = static_cast<typename TPixel::ValueType> (scale * data[index + i]);
}
}
/**
* Fill the float array data with the pixel values at index, using nbComp values scaled by scale.
*/
template <class TPixel> static inline void PixelToFloatArray(float * data,
unsigned int index,
const TPixel& pixel,
double scale)
{
for (unsigned int i = 0; i < pixel.Size(); ++i)
{
data[index + i] = static_cast<float>(scale * pixel[i]);
}
}
};
}
/** \class MeanShiftVectorImageFilter
*
* This is the implementation of the mean shift clustering and edge-preserving smoothing filter adapted to
* otb::VectorImage or itk::VectorImage. For the full documentation, please refer to the
* base class otb::MeanShiftImageFilter.
*
* \deprecated use MeanShiftSegmentationFilter instead
*
* \sa MeanShiftSmootingImageFilter, MeanShiftSegmentationFilter
*
* \ingroup ImageEnhancement
*
* \ingroup OTBEdisonMeanShift
*/
template <class TInputImage, class TOutputImage, class TLabeledOutput = otb::Image<unsigned short, 2> >
class MeanShiftVectorImageFilter
: public MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput, MeanShift::VectorBufferConverter>
{
public:
/** Standard class typedef */
typedef MeanShiftVectorImageFilter Self;
typedef MeanShiftImageFilter<TInputImage, TOutputImage, TLabeledOutput,
MeanShift::VectorBufferConverter> Superclass;
typedef itk::SmartPointer<Self> Pointer;
typedef itk::SmartPointer<const Self> ConstPointer;
/** Type macro */
itkTypeMacro(MeanShiftVectorImageFilter, MeanShiftImageFilter);
itkNewMacro(Self);
protected:
/** Constructor */
MeanShiftVectorImageFilter() {}
/** destructor */
virtual ~MeanShiftVectorImageFilter() {}
/**PrintSelf method */
virtual void PrintSelf(std::ostream& os, itk::Indent indent) const
{
Superclass::PrintSelf(os, indent);
}
private:
MeanShiftVectorImageFilter(const Self&); //purposely not implemented
void operator =(const Self&); //purposely not implemented
};
/**
* \class LabeledOutputAccessor
* \brief Specialized class to get the index of the labeled output image in mean shift vector image filter.
*
* \ingroup OTBEdisonMeanShift
*/
template <class TInputImage, class TOutputImage, class TLabeledImage>
class LabeledOutputAccessor<MeanShiftVectorImageFilter<TInputImage, TOutputImage, TLabeledImage> >
{
public:
typedef typename MeanShiftVectorImageFilter<TInputImage, TOutputImage, TLabeledImage>::LabeledOutputType LabelImageType;
itkStaticConstMacro(LabeledOutputIndex, unsigned int, 2);
};
} // end namespace otb
#endif
set(DOCUMENTATION "This module implements the mean shift segmentation algorithm
(EDISON library).")
otb_module(OTBEdisonMeanShift
DEPENDS
OTBVectorDataBase
OTBEdison
OTBITK
OTBImageBase
OTBCommon
OTBLabelling
OTBObjectList
TEST_DEPENDS
OTBTestKernel
OTBImageIO
OTBImageManipulation
DESCRIPTION
"${DOCUMENTATION}"
)
#include "otbImage.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMeanShiftVectorImageFilter.h"
//Code adapted from submission from Christophe Simler
// http://bugs.orfeo-toolbox.org/view.php?id=41
int main(int argc, char *argv[])
{
if (argc < 9)
{
std::cout <<
"Usage : inputImage rangeRadius spatialRadius minRegionSize outfilenamefiltered outfilenamesegmented outfilenamelabeled outfilenameboundary"
<< std::endl;
return EXIT_FAILURE;
}
char * filename = argv[1];
int rangeRadius = atoi(argv[2]);
int spatialRadius = atoi(argv[3]);
int minRegionSize = atoi(argv[4]);
char * outfilenamefiltered = argv[5];
char * outfilenamesegmented = argv[6];
char * outfilenamelabeled = argv[7];
char * outfilenameboundary = argv[8];
typedef otb::VectorImage<unsigned char, 2> ImageType; // image d'entree, image filtree et image segmente
typedef otb::Image<int, 2> TLabeledOutput; // image labelisee, image des contours (de l'image labellisee)
// lecture de l'image d'entree a partir d'un fichier
typedef otb::ImageFileReader<ImageType> ReaderType;
ReaderType::Pointer reader = ReaderType::New();
reader->SetFileName(filename);
// traitement avec le filtre
typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType, TLabeledOutput> FilterType;
FilterType::Pointer filter = FilterType::New();
filter->SetRangeRadius(rangeRadius);
filter->SetSpatialRadius(spatialRadius);
filter->SetMinimumRegionSize(minRegionSize);
// sauvegarde de l'image filtree,
typedef otb::ImageFileWriter<ImageType> WriterType1;
WriterType1::Pointer writer1 = WriterType1::New();
writer1->SetFileName(outfilenamefiltered);
// sauvegarde de l'image segmente,
typedef otb::ImageFileWriter<ImageType> WriterType2;
WriterType2::Pointer writer2 = WriterType2::New();
writer2->SetFileName(outfilenamesegmented);
// sauvegarde de l'image labelisee
typedef otb::ImageFileWriter<TLabeledOutput> WriterType3;
WriterType3::Pointer writer3 = WriterType3::New();
writer3->SetFileName(outfilenamelabeled);
// sauvegarde de l'image de contours
typedef otb::ImageFileWriter<TLabeledOutput> WriterType4;
WriterType4::Pointer writer4 = WriterType4::New();
writer4->SetFileName(outfilenameboundary);
// construction du pipeline
filter->SetInput(reader->GetOutput());
writer1->SetInput(filter->GetOutput()); // image filtree (*)
writer2->SetInput(filter->GetClusteredOutput()); // image segmente (clusterisee avec coherence spaciale ?) (*)
writer3->SetInput(filter->GetLabeledClusteredOutput()); // image des labels des clusters
writer4->SetInput(filter->GetClusterBoundariesOutput()); // image des contours des clusters (contours de l'image labelisee)
writer1->Update();
writer2->Update();
writer3->Update();
writer4->Update();
return 0;
}
/*=========================================================================
Program: ORFEO Toolbox
Language: C++
Date: $Date$
Version: $Revision$
Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
See OTBCopyright.txt for details.
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.
=========================================================================*/
#include "itkMacro.h"
#include "otbVectorImage.h"
#include "otbImageFileReader.h"
#include "otbImageFileWriter.h"
#include "otbMeanShiftVectorImageFilter.h"
#include "otbStreamingShrinkImageFilter.h"
int main(int itkNotUsed(argc), char * argv[])
{
const char * infname = argv[1];
const unsigned int spatialRadius = atoi(argv[2]);
const double rangeRadius = atof(argv[3]);
const unsigned int minRegionSize = atoi(argv[4]);
unsigned int factor = atoi(argv[5]);
const unsigned int Dimension = 2;
typedef float PixelType;
typedef otb::VectorImage<PixelType, Dimension> ImageType;
typedef otb::ImageFileReader<ImageType> ReaderType;
typedef otb::MeanShiftVectorImageFilter<ImageType, ImageType> FilterType;
typedef otb::StreamingShrinkImageFilter<ImageType, ImageType> ShrinkType;
// Instantiating object
FilterType::Pointer filter = FilterType::New();
ReaderType::Pointer reader = ReaderType::New();
ShrinkType::Pointer shrinker = ShrinkType::New();
reader->SetFileName(infname);
filter->SetSpatialRadius(spatialRadius);
filter->SetRangeRadius(rangeRadius);
filter->SetMinimumRegionSize(minRegionSize);
filter->SetInput(reader->GetOutput());
filter->UpdateOutputInformation();
shrinker->SetInput(filter->GetOutput());
shrinker->SetShrinkFactor(factor);
shrinker->Update();
return EXIT_SUCCESS;
}
otb_module_test()
set(OTBEdisonMeanShiftTests
otbEdisonMeanShiftTestDriver.cxx
otbMeanShiftImageFilterNew.cxx
otbMeanShiftImageFilter.cxx
otbMeanShiftVectorImageFilterNew.cxx
otbMeanShiftVectorImageFilter.cxx
)
add_executable(otbEdisonMeanShiftTestDriver ${OTBEdisonMeanShiftTests})
target_link_libraries(otbEdisonMeanShiftTestDriver ${OTBEdisonMeanShift-Test_LIBRARIES})
otb_module_target_label(otbEdisonMeanShiftTestDriver)
# Tests Declaration
otb_add_test(NAME bfTvMeanShiftImageFilter COMMAND otbEdisonMeanShiftTestDriver
--compare-n-images ${EPSILON_7} 4
${BASELINE}/bfMeanShiftImageFilterOutput.tif
${TEMP}/bfMeanShiftImageFilterOutput.tif
${BASELINE}/bfMeanShiftImageFilterClusteredOutput.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutput.tif
${BASELINE}/bfMeanShiftImageFilterLabeledClusteredOutput.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutput.tif
${BASELINE}/bfMeanShiftImageFilterClusterBoundariesOutput.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutput.tif
otbMeanShiftImageFilter
${INPUTDATA}/QB_Suburb.png
${TEMP}/bfMeanShiftImageFilterOutput.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutput.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutput.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutput.tif
16 16 10 1.0
)
otb_add_test(NAME bfTvMeanShiftImageFilterEDISON COMMAND otbEdisonMeanShiftTestDriver
--compare-image ${EPSILON_7}
${BASELINE}/bfTvMeanShiftFilterSpectralOutputOptim.tif
${TEMP}/bfTvMeanShiftImageFilterOutputOptim.tif
otbMeanShiftImageFilter
${INPUTDATA}/MeanShiftTest.tif
${TEMP}/bfTvMeanShiftImageFilterOutputOptim.tif
${TEMP}/bfTvMeanShiftImageFilterClusteredOutputOptim.tif
${TEMP}/bfTvMeanShiftImageFilterLabeledClusteredOutputOptim.tif
${TEMP}/bfTvMeanShiftImageFilterClusterBoundariesOutpuOptim.tif
2 10 10 0.1
)
otb_add_test(NAME bfTvMeanShiftImageFilterQBSuburb COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftImageFilter
${INPUTDATA}/QB_Suburb.png
${TEMP}/bfMeanShiftImageFilterOutput_QBSuburb.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutput_QBSuburb.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutput_QBSuburb.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutput_QBSuburb.tif
4 50 10 1.0
)
otb_add_test(NAME bfTuMeanShiftImageFilterNew COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftImageFilterNew )
otb_add_test(NAME bfTuMeanShiftSmoothingImageFilterNew COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftImageFilterNew )
otb_add_test(NAME bfTuMeanShiftVectorImageFilterNew COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftVectorImageFilterNew )
otb_add_test(NAME bfTvMeanShiftVectorImageFilterQBPAN COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftVectorImageFilter
${INPUTDATA}/QB_Toulouse_Ortho_PAN.tif
${TEMP}/bfMeanShiftImageFilterOutput_PAN.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutputValid_PAN.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutputValid_PAN.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutputValid_PAN.tif
5 15 100 1.0
)
otb_add_test(NAME bfTvMeanShiftVectorImageFilter COMMAND otbEdisonMeanShiftTestDriver
--compare-n-images ${EPSILON_7} 4
${BASELINE}/bfMeanShiftVectorImageFilterOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterOutput.tif
${BASELINE}/bfMeanShiftVectorImageFilterClusteredOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterClusteredOutput.tif
${BASELINE}/bfMeanShiftVectorImageFilterLabeledClusteredOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterLabeledClusteredOutput.tif
${BASELINE}/bfMeanShiftVectorImageFilterClusterBoundariesOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterClusterBoundariesOutput.tif
otbMeanShiftVectorImageFilter
${INPUTDATA}/qb_RoadExtract2sub200x200.tif
${TEMP}/bfMeanShiftVectorImageFilterOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterClusteredOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterLabeledClusteredOutput.tif
${TEMP}/bfMeanShiftVectorImageFilterClusterBoundariesOutput.tif
16 16 10 1.0
)
otb_add_test(NAME bfTuMeanShiftVectorImageFilterSPOT5 COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftVectorImageFilter
${INPUTDATA}/SPOT5_EXTRACTS/Arcachon/Arcachon_extrait_3852_3319_546_542.tif
${TEMP}/bfMeanShiftImageFilterOutput_SPOT5.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutput_SPOT5.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutput_SPOT5.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutput_SPOT5.tif
4 10 100 1.0
)
otb_add_test(NAME bfTuMeanShiftVectorImageFilterQBRoad COMMAND otbEdisonMeanShiftTestDriver
otbMeanShiftVectorImageFilter
${INPUTDATA}/qb_RoadExtract.img
${TEMP}/bfMeanShiftImageFilterOutput_QBRoad.tif
${TEMP}/bfMeanShiftImageFilterClusteredOutput_QBRoad.tif
${TEMP}/bfMeanShiftImageFilterLabeledClusteredOutput_QBRoad.tif
${TEMP}/bfMeanShiftImageFilterClusterBoundariesOutput_QBRoad.tif
4 30 100 1.0
)