/*========================================================================= * * Copyright NumFOCUS * * 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 * * https://www.apache.org/licenses/LICENSE-2.0.txt * * 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 itkLevelSetVelocityNeighborhoodExtractor_hxx #define itkLevelSetVelocityNeighborhoodExtractor_hxx #include "itkMath.h" namespace itk { /** * */ template LevelSetVelocityNeighborhoodExtractor::LevelSetVelocityNeighborhoodExtractor() { m_AuxInsideValues = nullptr; m_AuxOutsideValues = nullptr; for (unsigned int i = 0; i < VAuxDimension; ++i) { m_AuxImage[i] = nullptr; } } /* * */ template void LevelSetVelocityNeighborhoodExtractor::PrintSelf(std::ostream & os, Indent indent) const { Superclass::PrintSelf(os, indent); os << indent << "Input aux image: ["; unsigned int j; for (j = 0; j + 1 < VAuxDimension; ++j) { os << m_AuxImage[j].GetPointer() << ", "; } os << m_AuxImage[j].GetPointer() << ']' << std::endl; os << indent << "AuxInsideValues: " << m_AuxInsideValues.GetPointer() << std::endl; os << indent << "AuxOutsideValues: " << m_AuxOutsideValues.GetPointer() << std::endl; } /* * */ template void LevelSetVelocityNeighborhoodExtractor::Initialize() { this->Superclass::Initialize(); // create new empty auxiliary variable containers m_AuxInsideValues = AuxValueContainer::New(); m_AuxOutsideValues = AuxValueContainer::New(); } /* * */ template double LevelSetVelocityNeighborhoodExtractor::CalculateDistance(Index & index) { double distance = this->Superclass::CalculateDistance(index); if (distance >= this->GetLargeValue()) { return distance; } double centerValue[VAuxDimension]; AuxValueType auxPixel; AuxValueVectorType auxVector; for (unsigned int k = 0; k < VAuxDimension; ++k) { auxPixel = m_AuxImage[k]->GetPixel(index); centerValue[k] = static_cast(auxPixel); } // if distance is zero, insert point in inside container if (this->GetLastPointIsInside()) { for (unsigned int k = 0; k < VAuxDimension; ++k) { auxVector[k] = centerValue[k]; } m_AuxInsideValues->InsertElement(m_AuxInsideValues->Size(), auxVector); return distance; } double denom = 0.0; double numer[VAuxDimension]; typename Superclass::NodeType neighNode; for (unsigned int k = 0; k < VAuxDimension; ++k) { numer[k] = 0.0; } // The extend velocity value is a weighted value of // the speed values at point used in the computation // of the distance by the superclass. // // The weights is proportional to one over the square // of distance along the grid line to the zero set // crossing. for (unsigned int j = 0; j < SetDimension; ++j) { neighNode = this->GetNodeUsedInCalculation(j); if (neighNode.GetValue() >= this->GetLargeValue()) { break; } denom += 1.0 / itk::Math::sqr(static_cast(neighNode.GetValue())); for (unsigned int k = 0; k < VAuxDimension; ++k) { auxPixel = m_AuxImage[k]->GetPixel(neighNode.GetIndex()); numer[k] += static_cast(auxPixel) / itk::Math::sqr(static_cast(neighNode.GetValue())); } } for (unsigned int k = 0; k < VAuxDimension; ++k) { numer[k] /= denom; auxVector[k] = numer[k]; } if (this->GetLastPointIsInside()) { m_AuxInsideValues->InsertElement(m_AuxInsideValues->Size(), auxVector); } else { m_AuxOutsideValues->InsertElement(m_AuxOutsideValues->Size(), auxVector); } return distance; } } // namespace itk #endif