21 #ifndef otbMeanShiftSmoothingImageFilter_h
22 #define otbMeanShiftSmoothingImageFilter_h
26 #include "itkImageToImageFilter.h"
27 #include "itkImageRegionConstIterator.h"
28 #include "itkImageRegionConstIteratorWithIndex.h"
41 for (
unsigned int i = 0; i != p; ++i)
57 template <
class TInputImage,
class TOutputJo
intImage>
67 typename TOutputJointImage::PixelType
operator()(
const typename TInputImage::PixelType& inputPixel,
const typename TInputImage::IndexType& index)
const
82 void Initialize(
unsigned int _ImageDimension,
unsigned int numberOfComponentsPerPixel_,
typename TInputImage::IndexType globalShift_)
112 return (x <= 1) ? 1.0 : 0.0;
131 return std::exp(-0.5 * x);
136 return 3.0 * bandwidth;
147 template <
typename TImage>
181 #if 0 // disable bucket mode
194 template<
class TImage>
198 typedef TImage ImageType;
199 typedef typename ImageType::ConstPointer ImageConstPointerType;
200 typedef typename ImageType::PixelType PixelType;
201 typedef typename ImageType::InternalPixelType InternalPixelType;
202 typedef typename ImageType::RegionType RegionType;
203 typedef typename ImageType::IndexType IndexType;
205 typedef double RealType;
207 static const unsigned int ImageDimension = ImageType::ImageDimension;
210 typedef std::vector<typename ImageType::SizeType::SizeValueType> BucketImageSizeType;
211 typedef std::vector<typename ImageType::IndexType::IndexValueType> BucketImageIndexType;
216 typedef const typename ImageType::InternalPixelType * ImageDataPointerType;
217 typedef std::vector<ImageDataPointerType> BucketType;
218 typedef std::vector<BucketType> BucketListType;
231 BucketImage(ImageConstPointerType image,
const RegionType & region, RealType spatialRadius, RealType rangeRadius,
232 unsigned int spectralCoordinate) :
233 m_Image(image), m_Region(region), m_SpatialRadius(spatialRadius), m_RangeRadius(rangeRadius),
234 m_SpectralCoordinate(spectralCoordinate)
238 itk::ImageRegionConstIterator<ImageType> inputIt(m_Image, m_Region);
240 InternalPixelType minValue = inputIt.Get()[spectralCoordinate];
241 InternalPixelType maxValue = minValue;
243 while (!inputIt.IsAtEnd())
245 const PixelType &p = inputIt.Get();
246 minValue = std::min(minValue, p[m_SpectralCoordinate]);
247 maxValue = std::max(maxValue, p[m_SpectralCoordinate]);
251 m_MinValue = minValue;
252 m_MaxValue = maxValue;
256 m_DimensionVector.resize(ImageDimension + 1);
257 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
259 m_DimensionVector[dim] = m_Region.GetSize()[dim] / m_SpatialRadius + 3;
261 m_DimensionVector[ImageDimension] = (
unsigned int) ((maxValue - minValue) / m_RangeRadius) + 3;
263 unsigned int numBuckets = m_DimensionVector[0];
264 for (
unsigned int dim = 1; dim <= ImageDimension; ++dim)
265 numBuckets *= m_DimensionVector[dim];
267 m_BucketList.resize(numBuckets);
269 itk::ImageRegionConstIteratorWithIndex<ImageType> it(m_Image, m_Region);
272 FastImageRegionConstIterator<ImageType> fastIt(m_Image, m_Region);
275 while (!it.IsAtEnd())
277 const IndexType & index = it.GetIndex();
278 const PixelType & pixel = it.Get();
281 const BucketImageIndexType bucketIndex = GetBucketIndex(pixel, index);
283 unsigned int bucketListIndex = BucketIndexToBucketListIndex(bucketIndex);
284 assert(bucketListIndex < numBuckets);
285 m_BucketList[bucketListIndex].push_back(fastIt.GetPixelPointer());
292 std::vector<BucketImageIndexType> neighborsIndexList;
293 neighborsIndexList.reserve(
simple_pow(3, ImageDimension + 1));
294 neighborsIndexList.resize(1, BucketImageIndexType(ImageDimension + 1));
296 for (
unsigned dim = 0; dim <= ImageDimension; ++dim)
300 const unsigned int curSize = neighborsIndexList.size();
301 for (
unsigned int i = 0; i < curSize; ++i)
303 BucketImageIndexType index = neighborsIndexList[i];
305 neighborsIndexList.push_back(index);
307 neighborsIndexList.push_back(index);
311 const unsigned int neighborhoodOffsetVectorSize = neighborsIndexList.size();
312 m_NeighborhoodOffsetVector.reserve(neighborhoodOffsetVectorSize);
313 for (
unsigned int i = 0; i < neighborhoodOffsetVectorSize; ++i)
315 const int listIndex = BucketIndexToBucketListIndex(neighborsIndexList[i]);
316 m_NeighborhoodOffsetVector.push_back(listIndex);
325 BucketImageIndexType GetBucketIndex(
const PixelType & pixel,
const IndexType & index)
327 BucketImageIndexType bucketIndex(ImageDimension + 1);
328 for (
unsigned int dim = 0; dim < ImageDimension; ++dim)
330 bucketIndex[dim] = (index[dim] - m_Region.GetIndex()[dim]) / m_SpatialRadius + 1;
332 bucketIndex[ImageDimension] = (pixel[m_SpectralCoordinate] - m_MinValue) / m_RangeRadius + 1;
339 int BucketIndexToBucketListIndex(
const BucketImageIndexType & bucketIndex)
const
341 int bucketListIndex = bucketIndex[0];
342 for (
unsigned int dim = 1; dim <= ImageDimension; ++dim)
344 bucketListIndex = bucketListIndex * m_DimensionVector[dim] + bucketIndex[dim];
346 return bucketListIndex;
351 std::vector<unsigned int> GetNeighborhoodBucketListIndices(
int bucketIndex)
const
353 const unsigned int neighborhoodOffsetVectorSize = m_NeighborhoodOffsetVector.size();
354 std::vector<unsigned int> indices(neighborhoodOffsetVectorSize);
357 for (
unsigned int i = 0; i < neighborhoodOffsetVectorSize; ++i)
359 indices[i] = bucketIndex + m_NeighborhoodOffsetVector[i];
365 const BucketType & GetBucket(
unsigned int index)
const
367 return m_BucketList[index];
370 unsigned int GetNumberOfNeighborBuckets()
const
372 return m_NeighborhoodOffsetVector.size();
377 ImageConstPointerType m_Image;
383 RealType m_SpatialRadius;
386 RealType m_RangeRadius;
390 unsigned int m_SpectralCoordinate;
393 InternalPixelType m_MinValue;
394 InternalPixelType m_MaxValue;
397 BucketListType m_BucketList;
400 BucketImageSizeType m_DimensionVector;
405 std::vector<int> m_NeighborhoodOffsetVector;
465 template <
class TInputImage,
class TOutputImage,
class TKernel = Meanshift::KernelUniform,
472 typedef itk::ImageToImageFilter<TInputImage, TOutputImage>
Superclass;
494 typedef typename InputImageType::SizeType
SizeType;
512 itkStaticConstMacro(ImageDimension,
unsigned int, InputImageType::ImageDimension);
521 itkSetMacro(SpatialBandwidth,
RealType);
522 itkGetConstReferenceMacro(SpatialBandwidth,
RealType);
528 itkSetMacro(RangeBandwidth,
RealType);
529 itkGetConstReferenceMacro(RangeBandwidth,
RealType);
535 itkSetMacro(RangeBandwidthRamp,
RealType);
536 itkGetConstReferenceMacro(RangeBandwidthRamp,
RealType);
540 itkGetConstReferenceMacro(MaxIterationNumber,
unsigned int);
541 itkSetMacro(MaxIterationNumber,
unsigned int);
547 itkGetConstReferenceMacro(Threshold,
double);
548 itkSetMacro(Threshold,
double);
555 itkSetMacro(ModeSearch,
bool);
556 itkGetConstReferenceMacro(ModeSearch,
bool);
562 itkSetMacro(BucketOptimization,
bool);
563 itkGetConstReferenceMacro(BucketOptimization,
bool);
600 void GenerateOutputInformation(
void)
override;
602 void GenerateInputRequestedRegion()
override;
604 void BeforeThreadedGenerateData()
override;
616 void ThreadedGenerateData(
const OutputRegionType& outputRegionForThread, itk::ThreadIdType threadId)
override;
618 void AfterThreadedGenerateData()
override;
621 void AllocateOutputs()
override;
630 void PrintSelf(std::ostream& os, itk::Indent indent)
const override;
635 virtual void CalculateMeanShiftVectorBucket(
const RealVector& jointPixel,
RealVector& meanShiftVector);
640 void operator=(
const Self&) =
delete;
683 bool m_BucketOptimization;
694 typedef Meanshift::BucketImage<RealVectorImageType> BucketImageType;
695 BucketImageType m_BucketImage;
703 #ifndef OTB_MANUAL_INSTANTIATION