19 #ifndef __otbMeanShiftImageFilter_txx
20 #define __otbMeanShiftImageFilter_txx
29 #include "msImageProcessor.h"
33 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
39 m_MinimumRegionSize = 10;
42 this->SetNumberOfOutputs(4);
43 this->SetNthOutput(1, OutputImageType::New());
44 this->SetNthOutput(2, LabeledOutputType::New());
45 this->SetNthOutput(3, LabeledOutputType::New());
48 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
53 if (this->GetNumberOfOutputs() < 2)
60 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
65 if (this->GetNumberOfOutputs() < 2)
72 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
77 if (this->GetNumberOfOutputs() < 3)
84 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
89 if (this->GetNumberOfOutputs() < 3)
96 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
101 if (this->GetNumberOfOutputs() < 4)
108 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
113 if (this->GetNumberOfOutputs() < 4)
120 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
125 typename OutputImageType::Pointer outputPtr = this->GetOutput();
126 typename OutputImageType::Pointer clusteredOutputPtr = this->GetClusteredOutput();
127 typename LabeledOutputType::Pointer labeledClusteredOutputPtr = this->GetLabeledClusteredOutput();
128 typename LabeledOutputType::Pointer clusterBoundariesOutputPtr = this->GetClusterBoundariesOutput();
130 outputPtr->SetBufferedRegion(outputPtr->GetRequestedRegion());
131 outputPtr->Allocate();
133 clusteredOutputPtr->SetBufferedRegion(clusteredOutputPtr->GetRequestedRegion());
134 clusteredOutputPtr->Allocate();
136 labeledClusteredOutputPtr->SetBufferedRegion(labeledClusteredOutputPtr->GetRequestedRegion());
137 labeledClusteredOutputPtr->Allocate();
139 clusterBoundariesOutputPtr->SetBufferedRegion(clusterBoundariesOutputPtr->GetRequestedRegion());
140 clusterBoundariesOutputPtr->Allocate();
144 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
150 for (
unsigned int j = 0; j < this->GetNumberOfOutputs(); j++ )
159 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
165 this->AllocateOutputs();
168 typename InputImageType::ConstPointer inputPtr = this->GetInput();
169 typename OutputImageType::Pointer outputPtr = this->GetOutput();
172 double invScale = 1 / m_Scale;
174 RegionType inputRequestedRegion =inputPtr->GetRequestedRegion();
175 RegionType outputRequestedRegion = inputPtr->GetRequestedRegion();
177 inputRequestedRegion.PadByRadius(m_SpatialRadius);
178 if (!inputRequestedRegion.Crop(inputPtr->GetRequestedRegion()))
180 itkExceptionMacro(<<
"error in requested region cropping");
188 msImageProcessor edisonProcessor;
190 float * data =
new float[inputRequestedRegion.GetNumberOfPixels() * inputPtr->GetNumberOfComponentsPerPixel()];
192 unsigned int index = 0;
196 TBufferConverter::PixelToFloatArray(data, index, inputIt.
Get(), m_Scale);
197 index += inputPtr->GetNumberOfComponentsPerPixel();
200 edisonProcessor.DefineLInput(data,
201 inputRequestedRegion.GetSize()[1],
202 inputRequestedRegion.GetSize()[0],
203 inputPtr->GetNumberOfComponentsPerPixel());
206 kernelType k[2] = {Uniform, Uniform};
207 int P[2] = {2,
static_cast<int>(inputPtr->GetNumberOfComponentsPerPixel())};
208 float tempH[2] = {1.0, 1.0};
210 edisonProcessor.DefineKernel(k, tempH, P, 2);
212 edisonProcessor.Filter(m_SpatialRadius, m_RangeRadius * m_Scale, MED_SPEEDUP);
214 if (edisonProcessor.ErrorStatus)
216 itkExceptionMacro(<<
"Error while running edison!");
219 typename OutputImageType::Pointer tmpOutput = OutputImageType::New();
220 tmpOutput->SetRegions(inputRequestedRegion);
221 tmpOutput->SetNumberOfComponentsPerPixel(outputPtr->GetNumberOfComponentsPerPixel());
222 tmpOutput->Allocate();
226 edisonProcessor.GetRawData(data);
228 if (edisonProcessor.ErrorStatus)
230 itkExceptionMacro(<<
"Error while running edison!");
238 TBufferConverter::FloatArrayToPixel(data, index, pixel, outputPtr->GetNumberOfComponentsPerPixel(), invScale);
240 index += outputPtr->GetNumberOfComponentsPerPixel();
248 outputIt.
Set(tmp2It.
Get());
255 typename OutputImageType::Pointer clusteredOutputPtr = this->GetClusteredOutput();
256 typename LabeledOutputType::Pointer labeledClusteredOutputPtr = this->GetLabeledClusteredOutput();
257 typename LabeledOutputType::Pointer clusterBoudariesOutputPtr = this->GetClusterBoundariesOutput();
264 TBufferConverter::PixelToFloatArray(data, index, outputIt.
Get(), m_Scale);
265 index += outputPtr->GetNumberOfComponentsPerPixel();
268 edisonProcessor.DefineLInput(data,
269 outputRequestedRegion.GetSize()[1],
270 outputRequestedRegion.GetSize()[0],
271 outputPtr->GetNumberOfComponentsPerPixel());
278 edisonProcessor.DefineKernel(k, tempH, P, 2);
280 edisonProcessor.FuseRegions(m_RangeRadius * m_Scale, m_MinimumRegionSize);
282 if (edisonProcessor.ErrorStatus)
284 itkExceptionMacro(<<
"Error while running edison!");
287 edisonProcessor.GetRawData(data);
289 if (edisonProcessor.ErrorStatus)
291 itkExceptionMacro(<<
"Error while running edison!");
295 for (clusteredOutputIt.
GoToBegin(); !clusteredOutputIt.
IsAtEnd(); ++clusteredOutputIt)
298 TBufferConverter::FloatArrayToPixel(data, index, pixel,
299 clusteredOutputPtr->GetNumberOfComponentsPerPixel(), invScale);
300 clusteredOutputIt.
Set(pixel);
301 index += clusteredOutputPtr->GetNumberOfComponentsPerPixel();
305 float * modes =
NULL;
306 int * modesPointsCount =
NULL;
308 edisonProcessor.GetRegions(&labels, &modes, &modesPointsCount);
310 if (edisonProcessor.ErrorStatus)
312 itkExceptionMacro(<<
"Error while running edison!");
316 labeledClusteredOutputPtr->GetRequestedRegion());
320 labeledClusteredOutputPtr->FillBuffer(0);
322 for (lcIt.GoToBegin(); !lcIt.IsAtEnd(); ++lcIt)
324 lcIt.
Set(static_cast<LabelType>(labels[index]));
328 clusterBoudariesOutputPtr->FillBuffer(0);
331 RegionList * regionList = edisonProcessor.GetBoundaries();
333 unsigned int numRegions = regionList->GetNumRegions();
335 typename LabeledOutputType::IndexType boundIndex;
337 for (
LabelType label = 0; label < static_cast<LabelType>(numRegions); ++label)
340 TBufferConverter::FloatArrayToPixel(modes,
341 static_cast<unsigned int>(label *
342 clusteredOutputPtr->GetNumberOfComponentsPerPixel()),
343 pixel, clusteredOutputPtr->GetNumberOfComponentsPerPixel(), invScale);
345 m_Modes[label] = pixel;
346 regionIndeces = regionList->GetRegionIndeces(static_cast<int>(label));
347 for (
int i = 0; i < regionList->GetRegionCount(static_cast<int>(label)); ++i)
351 clusterBoudariesOutputPtr->GetRequestedRegion().GetSize()[0]) +
352 clusterBoudariesOutputPtr->GetRequestedRegion().GetIndex()[0];
355 clusterBoudariesOutputPtr->GetRequestedRegion().GetSize()[0]) +
356 clusterBoudariesOutputPtr->GetRequestedRegion().GetIndex()[1];
357 if (clusterBoudariesOutputPtr->GetBufferedRegion().IsInside(boundIndex))
359 clusterBoudariesOutputPtr->SetPixel(boundIndex, 1);
367 delete[] modesPointsCount;
372 template <
class TInputImage,
class TOutputImage,
class TLabeledOutput,
class TBufferConverter>
377 Superclass::PrintSelf(os, indent);
378 os << indent <<
"Spatial radius: " << m_SpatialRadius << std::endl;
379 os << indent <<
"Range radius: " << m_RangeRadius << std::endl;
380 os << indent <<
"Minimum region size: " << m_MinimumRegionSize << std::endl;
381 os << indent <<
"Scale: " << m_Scale << std::endl;