/* * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES) * * This file is part of Orfeo Toolbox * * https://www.orfeo-toolbox.org/ * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #ifndef otbComplexMomentPathFunction_hxx #define otbComplexMomentPathFunction_hxx #include "otbComplexMomentPathFunction.h" #include "itkImageRegionIterator.h" #include "itkConstNeighborhoodIterator.h" #include "otbMacro.h" #include namespace otb { /** * Constructor */ template ComplexMomentPathFunction::ComplexMomentPathFunction() { m_P = 0; m_Q = 0; } /** * */ template void ComplexMomentPathFunction::PrintSelf(std::ostream& os, itk::Indent indent) const { this->Superclass::PrintSelf(os, indent); os << indent << " p indice value : " << m_P << std::endl; os << indent << " q indice value : " << m_Q << std::endl; } template typename ComplexMomentPathFunction::ComplexPrecisionType ComplexMomentPathFunction::EvaluateComplexMomentAtIndex(VertexType index) const { ComplexPrecisionType ValP; ComplexPrecisionType ValQ; ComplexPrecisionType Result; PrecisionType PixelValue(1.0); ValP = ComplexPrecisionType(1.0, 0.0); ValQ = ComplexPrecisionType(1.0, 0.0); unsigned int p = m_P; while (p > 0) { ValP *= ComplexPrecisionType(index[0], index[1]); --p; } unsigned int q = m_Q; while (q > 0) { ValQ *= ComplexPrecisionType(index[0], -index[1]); --q; } Result = ValP * ValQ * ComplexPrecisionType(static_cast(PixelValue), 0.0); return Result; } template typename ComplexMomentPathFunction::OutputType ComplexMomentPathFunction::Evaluate(const PathType& path) const { // Retrieve the vertex list VertexListPointer vertexList = path.GetVertexList(); // Get the number of vertices in the path unsigned int pathSize = vertexList->Size(); // value will store the result ComplexPrecisionType value = static_cast(0.0); // Check if we there are enough vertices in the path to actually // compute something if (pathSize < 2) { return static_cast(value); } // First, we compute the centroid of the path so as to center the moment typename VertexListType::ConstIterator it = vertexList->Begin(); VertexType centroid = it.Value(); ++it; // Cumulate points while (it != vertexList->End()) { centroid[0] += it.Value()[0]; centroid[1] += it.Value()[1]; ++it; } // Normalize centroid[0] /= static_cast(pathSize); centroid[1] /= static_cast(pathSize); // Second, we integrate along the edge it = vertexList->Begin(); VertexType source = it.Value(); source[0] -= centroid[0]; source[1] -= centroid[1]; ++it; PrecisionType ds; VertexType dest; // This variable will be used to normalize the moment PrecisionType norm = 0.; while (it != vertexList->End()) { dest = it.Value(); // Get source and destination coordinates dest[0] -= centroid[0]; dest[1] -= centroid[1]; // Don't forget the ds part of the integration process ds = std::sqrt(std::pow(dest[0] - source[0], 2.) + std::pow(dest[1] - source[1], 2.)); norm += ds; value += ds * EvaluateComplexMomentAtIndex(source); source = dest; ++it; } // Close the loop dest = vertexList->Begin().Value(); dest[0] -= centroid[0]; dest[1] -= centroid[1]; ds = std::sqrt(std::pow(dest[0] - source[0], 2.) + std::pow(dest[1] - source[1], 2.)); norm += ds; value += EvaluateComplexMomentAtIndex(source) * ds; norm = std::pow(norm, ((PrecisionType)m_P + (PrecisionType)m_Q) / 2.); // Normalize with edge perimeter value /= norm; return static_cast(value); } template typename ComplexMomentPathFunction::OutputType ComplexMomentPathFunction::Evaluate() const { if (!this->GetInputPath()) { otbMsgDevMacro(<< "Pb with GetInputPath"); return static_cast(ComplexPrecisionType(itk::NumericTraits::Zero, itk::NumericTraits::Zero)); } OutputType Result = Evaluate(*(this->GetInputPath())); return Result; } } // namespace otb #endif