/* * 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 otbChannelSelectorFunctor_h #define otbChannelSelectorFunctor_h #include #include "itkVariableLengthVector.h" #include "itkRGBPixel.h" #include "itkRGBAPixel.h" #include "itkObject.h" #include "itkObjectFactory.h" namespace otb { namespace Function { /** \class ChannelSelectorFunctor * \brief Base class for pixel representation functions. * * \ingroup Visualization * * \sa AmplitudeFunctor PhaseFunctor * * \ingroup OTBCommon */ template class ChannelSelectorFunctor : public itk::Object { public: /** Standard class typedefs */ typedef ChannelSelectorFunctor Self; typedef itk::Object Superclass; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; /** Method for creation through the object factory */ itkNewMacro(Self); /** Runtime information */ itkTypeMacro(ChannelSelectorFunctor, itk::Object); typedef TInputPixel PixelType; typedef typename itk::NumericTraits::ValueType ScalarType; typedef itk::VariableLengthVector VectorPixelType; typedef itk::RGBPixel RGBPixelType; typedef itk::RGBAPixel RGBAPixelType; typedef VectorPixelType OutputPixelType; typedef std::vector ChannelListType; const char* GetDescription() const { return "Channel Selection"; } virtual OutputPixelType operator()(const VectorPixelType& inPixel) const { // otbMsgDevMacro(<<"Channel list "<< m_ChannelList[0]); OutputPixelType outPixel; outPixel.SetSize(m_ChannelList.size()); for (unsigned int i = 0; i < m_ChannelList.size(); ++i) { // assert as the verification should be done outside and only // once for the image, not for every pixel, when we reach this point // the m_ChannelList MUST be valid assert(m_ChannelList[i] < inPixel.Size()); outPixel[i] = inPixel[m_ChannelList[i]]; } return outPixel; } virtual OutputPixelType operator()(ScalarType inPixel) const { OutputPixelType outPixel; outPixel.SetSize(1); for (unsigned int i = 0; i < m_ChannelList.size(); ++i) { assert(m_ChannelList[i] < 1); outPixel[0] = inPixel; } return outPixel; } virtual OutputPixelType operator()(const RGBPixelType& inPixel) const { OutputPixelType outPixel; outPixel.SetSize(m_ChannelList.size()); for (unsigned int i = 0; i < m_ChannelList.size(); ++i) { assert(m_ChannelList[i] < 3); outPixel[i] = inPixel[m_ChannelList[i]]; } return outPixel; } virtual OutputPixelType operator()(const RGBAPixelType& inPixel) const { OutputPixelType outPixel; outPixel.SetSize(m_ChannelList.size()); for (unsigned int i = 0; i < m_ChannelList.size(); ++i) { assert(m_ChannelList[i] < 4); outPixel[i] = inPixel[m_ChannelList[i]]; } return outPixel; } virtual unsigned int GetOutputSize() const { return m_ChannelList.size(); } virtual std::vector GetChannelList() const { return m_ChannelList; } virtual void SetChannelList(std::vector channels) { m_ChannelList = channels; usingDefaultParameters = false; } virtual void SetChannelIndex(unsigned int channelPosition, unsigned int channel) { if (m_ChannelList.size() < channelPosition + 1) { m_ChannelList.resize(channelPosition + 1, 0); } m_ChannelList[channelPosition] = channel; usingDefaultParameters = false; } virtual unsigned int GetChannelIndex(unsigned int channelPosition) const { if (channelPosition >= m_ChannelList.size()) { itkExceptionMacro(<< "Can't get channel " << channelPosition << ", there is only " << m_ChannelList.size() << " element in the list"); } return m_ChannelList[channelPosition]; } /** Only for backward compatibility but should not be used*/ virtual void SetAllChannels(unsigned int channel) { if (m_ChannelList.size() < 3) { m_ChannelList.resize(3, 0); } m_ChannelList[0] = channel; m_ChannelList[1] = channel; m_ChannelList[2] = channel; usingDefaultParameters = false; } virtual void SetRedChannelIndex(unsigned int channel) { if (m_ChannelList.size() < 1) { m_ChannelList.resize(3, 0); } m_ChannelList[0] = channel; usingDefaultParameters = false; } virtual void SetGreenChannelIndex(unsigned int channel) { if (m_ChannelList.size() < 2) { m_ChannelList.resize(3, 0); } m_ChannelList[1] = channel; usingDefaultParameters = false; } virtual void SetBlueChannelIndex(unsigned int channel) { if (m_ChannelList.size() < 3) { m_ChannelList.resize(3, 0); } m_ChannelList[2] = channel; usingDefaultParameters = false; } virtual unsigned int GetRedChannelIndex() const { return m_ChannelList[0]; } virtual unsigned int GetGreenChannelIndex() const { return m_ChannelList[1]; } virtual unsigned int GetBlueChannelIndex() const { return m_ChannelList[2]; } virtual bool IsUsingDefaultParameters() { return usingDefaultParameters; } protected: /** Constructor */ ChannelSelectorFunctor() : usingDefaultParameters(true) { if (std::string(typeid(PixelType).name()).find("RGBAPixel") != std::string::npos) { m_ChannelList.push_back(0); m_ChannelList.push_back(1); m_ChannelList.push_back(2); m_ChannelList.push_back(3); } else if (std::string(typeid(PixelType).name()).find("RGBPixel") != std::string::npos) { m_ChannelList.push_back(0); m_ChannelList.push_back(1); m_ChannelList.push_back(2); } else if (std::string(typeid(PixelType).name()).find("VariableLengthVector") != std::string::npos) { m_ChannelList.push_back(0); } else { m_ChannelList.push_back(0); } } /** Destructor */ ~ChannelSelectorFunctor() override { } private: ChannelListType m_ChannelList; bool usingDefaultParameters; }; } } #endif