22 #ifndef otbStreamingMatrixTransposeMatrixImageFilter_hxx
23 #define otbStreamingMatrixTransposeMatrixImageFilter_hxx
27 #include "itkImageRegionIterator.h"
28 #include "itkNumericTraits.h"
29 #include "itkProgressReporter.h"
34 template <
class TInputImage,
class TInputImage2>
37 this->SetNumberOfRequiredInputs(2);
45 typename ImageType::Pointer output1 =
static_cast<ImageType*
>(this->MakeOutput(0).GetPointer());
46 this->itk::ProcessObject::SetNthOutput(0, output1.GetPointer());
47 typename MatrixObjectType::Pointer output2 =
static_cast<MatrixObjectType*
>(this->MakeOutput(1).GetPointer());
48 this->itk::ProcessObject::SetNthOutput(1, output2.GetPointer());
51 m_UsePadFirstInput =
false;
52 m_UsePadSecondInput =
false;
55 m_NumberOfComponents1 = 0;
56 m_NumberOfComponents2 = 0;
59 template <
class TInputImage,
class TInputImage2>
65 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
68 return static_cast<itk::DataObject*
>(MatrixObjectType::New().GetPointer());
72 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
76 template <
class TInputImage,
class TInputImage2>
80 return static_cast<MatrixObjectType*
>(this->itk::ProcessObject::GetOutput(1));
83 template <
class TInputImage,
class TInputImage2>
87 return static_cast<const MatrixObjectType*
>(this->itk::ProcessObject::GetOutput(1));
90 template <
class TInputImage,
class TInputImage2>
93 Superclass::GenerateInputRequestedRegion();
95 if (this->GetFirstInput() && this->GetSecondInput())
99 image->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
100 image2->SetRequestedRegion(this->GetOutput()->GetRequestedRegion());
103 template <
class TInputImage,
class TInputImage2>
106 Superclass::GenerateOutputInformation();
107 if (this->GetFirstInput())
109 this->GetOutput()->CopyInformation(this->GetFirstInput());
110 this->GetOutput()->SetLargestPossibleRegion(this->GetFirstInput()->GetLargestPossibleRegion());
113 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
115 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
119 template <
class TInputImage,
class TInputImage2>
129 template <
class TInputImage,
class TInputImage2>
133 TInputImage* inputPtr1 =
const_cast<TInputImage*
>(this->GetFirstInput());
134 inputPtr1->UpdateOutputInformation();
135 TInputImage2* inputPtr2 =
const_cast<TInputImage2*
>(this->GetSecondInput());
136 inputPtr2->UpdateOutputInformation();
138 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
140 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
143 if (inputPtr1->GetLargestPossibleRegion().GetSize() != inputPtr2->GetLargestPossibleRegion().GetSize())
145 itkExceptionMacro(<<
" Can't multiply the transposed matrix of a " << inputPtr1->GetLargestPossibleRegion().GetSize() <<
" and a "
146 << inputPtr2->GetLargestPossibleRegion().GetSize() <<
" matrix ");
149 m_NumberOfComponents1 = inputPtr1->GetNumberOfComponentsPerPixel();
150 m_NumberOfComponents2 = inputPtr2->GetNumberOfComponentsPerPixel();
151 unsigned int numberOfThreads = this->GetNumberOfThreads();
153 if (m_UsePadFirstInput ==
true)
155 m_NumberOfComponents1++;
157 if (m_UsePadSecondInput ==
true)
159 m_NumberOfComponents2++;
163 tempMatrix.SetSize(m_NumberOfComponents1, m_NumberOfComponents2);
164 tempMatrix.Fill(itk::NumericTraits<RealType>::Zero);
167 initMatrix.SetSize(m_NumberOfComponents2, m_NumberOfComponents2);
168 initMatrix.Fill(itk::NumericTraits<RealType>::Zero);
169 this->GetResultOutput()->Set(initMatrix);
172 template <
class TInputImage,
class TInputImage2>
175 unsigned int numberOfThreads = this->GetNumberOfThreads();
177 resultMatrix.SetSize(m_NumberOfComponents1, m_NumberOfComponents2);
178 resultMatrix.Fill(itk::NumericTraits<RealType>::Zero);
180 for (
unsigned int thread = 0; thread < numberOfThreads; thread++)
186 for (
unsigned int i = 0; i < resultMatrix.Rows(); ++i)
188 for (
unsigned int j = 0; j < resultMatrix.Cols(); ++j)
190 resultMatrix(i, j) += m_ThreadSum[thread](i, j);
196 this->GetResultOutput()->Set(resultMatrix);
199 template <
class TInputImage,
class TInputImage2>
201 itk::ThreadIdType threadId)
211 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
213 itk::ImageRegionConstIterator<TInputImage> it1(input1Ptr, outputRegionForThread);
214 itk::ImageRegionConstIterator<TInputImage2> it2(input2Ptr, outputRegionForThread);
219 while (!it1.IsAtEnd())
225 if (m_UsePadFirstInput ==
true)
227 PixelType vectortemp1(vectorValue1.Size() + 1);
229 for (
unsigned int n = 0; n < vectorValue1.Size(); ++n)
231 vectortemp1[n + 1] = vectorValue1[n];
233 vectorValue1.SetSize(vectortemp1.Size());
234 vectorValue1 = vectortemp1;
237 if (m_UsePadSecondInput ==
true)
239 PixelType2 vectortemp2(vectorValue2.Size() + 1);
241 for (
unsigned int m = 0; m < vectorValue2.Size(); m++)
243 vectortemp2[m + 1] = vectorValue2[m];
245 vectorValue2.SetSize(vectortemp2.Size());
246 vectorValue2 = vectortemp2;
249 for (
unsigned int i = 0; i < vectorValue1.Size(); ++i)
251 for (
unsigned int j = 0; j < vectorValue2.Size(); ++j)
253 m_ThreadSum[threadId](i, j) +=
static_cast<RealType>(vectorValue1[i]) *
static_cast<RealType>(vectorValue2[j]);
258 progress.CompletedPixel();
262 template <
class TInputImage,
class TInputImage2>
265 Superclass::PrintSelf(os, indent);
267 os << indent <<
"Result: " << this->GetResultOutput()->Get() << std::endl;