diff --git a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx index c9bda376d9e2454fc714710c1d6ceff58cf747d8..dbcc3f38d6d254e4819e8b7528007f7fed4c7e82 100644 --- a/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx +++ b/Modules/Applications/AppFiltering/app/otbContrastEnhancement.cxx @@ -530,7 +530,6 @@ private: } m_GainFilter[channel]->SetMin( min[channel] ); m_GainFilter[channel]->SetMax( max[channel] ); - m_GainFilter[channel]->SetThumbSize(m_ThumbSize); m_GainFilter[channel]->SetInputLut( m_StreamingFilter[channel]->GetOutput() ); m_BufferFilter[channel] -> SetInput ( @@ -599,7 +598,6 @@ private: } m_GainFilter[channel]->SetMin( min ); m_GainFilter[channel]->SetMax( max ); - m_GainFilter[channel]->SetThumbSize( m_ThumbSize ); m_GainFilter[channel]->SetInputLut( m_StreamingFilter[0]->GetOutput() ); m_BufferFilter[channel]->SetInput( diff --git a/Modules/Filtering/Contrast/include/otbApplyGainFilter.h b/Modules/Filtering/Contrast/include/otbApplyGainFilter.h index 35aaa42ba998ac7cc23f155767bb5f01a0845b68..c735725382971d33b31273edcffcda0316184db0 100644 --- a/Modules/Filtering/Contrast/include/otbApplyGainFilter.h +++ b/Modules/Filtering/Contrast/include/otbApplyGainFilter.h @@ -72,6 +72,15 @@ public : itkGetMacro(NoDataFlag, bool) itkSetMacro(NoDataFlag, bool) + /** Get/Set macro to get/set the ThumbSizeFromSpacing flag value */ + itkBooleanMacro(ThumbSizeFromSpacing) + itkGetMacro(ThumbSizeFromSpacing, bool) + itkSetMacro(ThumbSizeFromSpacing, bool) + + /** Get/Set macro to get/set the thumbnail's size */ + itkSetMacro(ThumbSize, typename InputImageType::SizeType) + itkGetMacro(ThumbSize, typename InputImageType::SizeType) + /** Get/Set macro to get/set the minimum value */ itkSetMacro(Min, InputPixelType) itkGetMacro(Min, InputPixelType) @@ -80,10 +89,6 @@ public : itkSetMacro(Max, InputPixelType) itkGetMacro(Max, InputPixelType) - /** Get/Set macro to get/set the thumbnail's size */ - itkSetMacro(ThumbSize, typename InputImageType::SizeType) - itkGetMacro(ThumbSize, typename InputImageType::SizeType) - /** Set the input look up table*/ void SetInputLut( const LutType * lut) ; @@ -107,7 +112,7 @@ protected : void ThreadedGenerateData(const OutputImageRegionType & outputRegionForThread, itk::ThreadIdType threadId) override; - + void VerifyInputInformation() override {} ; private : ApplyGainFilter(const Self &) = delete ; @@ -122,6 +127,7 @@ private : InputPixelType m_Min; InputPixelType m_Max; bool m_NoDataFlag; + bool m_ThumbSizeFromSpacing; double m_Step; typename LutType::SizeType m_LutSize; typename InputImageType::SizeType m_ThumbSize; diff --git a/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx b/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx index 2c70ed13afcbb5923ee5bad6e2a5d3d7ac3a58e0..3d9372892eb34c514b5bef3f1347eb05ff86fe93 100644 --- a/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx +++ b/Modules/Filtering/Contrast/include/otbApplyGainFilter.txx @@ -24,7 +24,7 @@ #include "otbApplyGainFilter.h" #include "itkImageRegionIterator.h" #include "itkImageRegionConstIteratorWithIndex.h" - +#include "itkContinuousIndex.h" #include <limits> @@ -38,7 +38,8 @@ ApplyGainFilter < TInputImage , TLut , TOutputImage > m_Min = std::numeric_limits< InputPixelType >::quiet_NaN(); m_Max = std::numeric_limits< InputPixelType >::quiet_NaN(); m_NoData = std::numeric_limits< InputPixelType >::quiet_NaN(); - + m_NoDataFlag = false; + m_ThumbSizeFromSpacing = true; m_Step = -1; } @@ -93,7 +94,14 @@ void ApplyGainFilter < TInputImage , TLut , TOutputImage > ::BeforeThreadedGenerateData() { typename LutType::ConstPointer lut ( GetInputLut() ); - + typename InputImageType::ConstPointer input ( GetInputImage() ); + if ( m_ThumbSizeFromSpacing ) + { + m_ThumbSize[0] = std::round( lut->GetSpacing()[0] + / input->GetSpacing()[0] ); + m_ThumbSize[1] = std::round( lut->GetSpacing()[1] + / input->GetSpacing()[1] ); + } m_Step = static_cast<double>( m_Max - m_Min ) \ / static_cast<double>( lut->GetVectorLength() - 1 ); } @@ -149,112 +157,146 @@ double ApplyGainFilter < TInputImage , TLut , TOutputImage > unsigned int pixelLutValue , typename InputImageType::IndexType index) { - typename LutType::IndexType lutIndex; - lutIndex[0] = index[0]/m_ThumbSize[0]; - lutIndex[1] = index[1]/m_ThumbSize[1]; - float x ( static_cast< float >(index[0]%m_ThumbSize[0]) - / static_cast< float >(m_ThumbSize[0]) ); - float y ( static_cast< float >(index[1]%m_ThumbSize[1]) - / static_cast< float >(m_ThumbSize[1]) ); - float disty ( std::abs( y - 0.5f ) ) , distx ( std::abs( x - 0.5f ) ); - float w(0.f) , gain(0.f); - if ( gridLut->GetPixel(lutIndex)[pixelLutValue] != -1 ) - { - w = ( 1 - distx )*( 1 - disty ); - gain = gridLut->GetPixel(lutIndex)[pixelLutValue] * - ( 1 - distx ) * ( 1 - disty ) ; - } - typename LutType::OffsetType rightOffSet , upOffSet , leftOffSet , downOffSet; + // typename LutType::IndexType lutIndex; + // lutIndex[0] = index[0]/m_ThumbSize[0]; + // lutIndex[1] = index[1]/m_ThumbSize[1]; + // float x ( static_cast< float >(index[0]%m_ThumbSize[0]) + // / static_cast< float >(m_ThumbSize[0]) ); + // float y ( static_cast< float >(index[1]%m_ThumbSize[1]) + // / static_cast< float >(m_ThumbSize[1]) ); + // float disty ( std::abs( y - 0.5f ) ) , distx ( std::abs( x - 0.5f ) ); + // float w(0.f) , gain(0.f); + // if ( gridLut->GetPixel(lutIndex)[pixelLutValue] != -1 ) + // { + // w = ( 1 - distx )*( 1 - disty ); + // gain = gridLut->GetPixel(lutIndex)[pixelLutValue] * + // ( 1 - distx ) * ( 1 - disty ) ; + // } + // typename LutType::OffsetType rightOffSet , upOffSet , leftOffSet , downOffSet; - rightOffSet.Fill(0); - rightOffSet[0] = 1 ; - bool right = ( x >= 0.5f ) && - ( ( rightOffSet[0] + lutIndex[0] ) < static_cast<int>( m_LutSize[0] ) ); + // rightOffSet.Fill(0); + // rightOffSet[0] = 1 ; + // bool right = ( x >= 0.5f ) && + // ( ( rightOffSet[0] + lutIndex[0] ) < static_cast<int>( m_LutSize[0] ) ); - leftOffSet.Fill(0); - leftOffSet[0] = -1 ; - bool left = ( x <= 0.5f ) && - ( ( leftOffSet[0] + lutIndex[0] ) >= 0 ); + // leftOffSet.Fill(0); + // leftOffSet[0] = -1 ; + // bool left = ( x <= 0.5f ) && + // ( ( leftOffSet[0] + lutIndex[0] ) >= 0 ); - upOffSet.Fill(0); - upOffSet[1] = -1 ; - bool up = ( y <= 0.5f ) && - ( ( upOffSet[1] + lutIndex[1] ) >= 0 ) ; + // upOffSet.Fill(0); + // upOffSet[1] = -1 ; + // bool up = ( y <= 0.5f ) && + // ( ( upOffSet[1] + lutIndex[1] ) >= 0 ) ; - downOffSet.Fill(0); - downOffSet[1] = 1 ; - bool down = ( y >= 0.5f ) && - ( downOffSet[1] + lutIndex[1] ) < static_cast<int>( m_LutSize[1] ) ; - if ( right - && gridLut->GetPixel(lutIndex + rightOffSet)[pixelLutValue] != -1 ) - { - gain += gridLut->GetPixel(lutIndex + rightOffSet)[pixelLutValue] - * (1 - disty ) * distx; - w += (1 - disty ) * distx; - } - if ( left - && gridLut->GetPixel(lutIndex + leftOffSet)[pixelLutValue] != -1 ) - { - gain += gridLut->GetPixel(lutIndex + leftOffSet)[pixelLutValue] - * (1 - disty ) * distx; - w += (1 - disty ) * distx; - } - if ( up - && gridLut->GetPixel(lutIndex + upOffSet)[pixelLutValue] != -1 ) - { - gain += gridLut->GetPixel(lutIndex + upOffSet)[pixelLutValue] - * disty * (1 - distx ); - w += disty * (1 - distx ); - } - if ( down - && gridLut->GetPixel(lutIndex + downOffSet)[pixelLutValue] != -1 ) - { - gain += gridLut->GetPixel(lutIndex + downOffSet)[pixelLutValue] - * disty * (1 - distx ); - w += disty * (1 - distx ); - } - if ( up && left - && gridLut->GetPixel(lutIndex + upOffSet + leftOffSet) - [pixelLutValue] != -1 ) - { - gain += gridLut-> - GetPixel(lutIndex + upOffSet + leftOffSet)[pixelLutValue] - * disty * distx; - w += disty * distx; - } - if ( down && left - && gridLut->GetPixel(lutIndex + downOffSet + leftOffSet) - [pixelLutValue] != -1 ) - { - gain += gridLut-> - GetPixel(lutIndex + downOffSet + leftOffSet)[pixelLutValue] - * disty * distx; - w += disty * distx; - } - if ( up && right - && gridLut->GetPixel(lutIndex + upOffSet + rightOffSet) - [pixelLutValue] != -1 ) - { - gain += gridLut-> - GetPixel(lutIndex + upOffSet + rightOffSet)[pixelLutValue] - * disty * distx; - w += disty * distx ; - } - if ( down && right - && gridLut->GetPixel(lutIndex + downOffSet + rightOffSet) - [pixelLutValue] != -1 ) + // downOffSet.Fill(0); + // downOffSet[1] = 1 ; + // bool down = ( y >= 0.5f ) && + // ( downOffSet[1] + lutIndex[1] ) < static_cast<int>( m_LutSize[1] ) ; + // if ( right + // && gridLut->GetPixel(lutIndex + rightOffSet)[pixelLutValue] != -1 ) + // { + // gain += gridLut->GetPixel(lutIndex + rightOffSet)[pixelLutValue] + // * (1 - disty ) * distx; + // w += (1 - disty ) * distx; + // } + // if ( left + // && gridLut->GetPixel(lutIndex + leftOffSet)[pixelLutValue] != -1 ) + // { + // gain += gridLut->GetPixel(lutIndex + leftOffSet)[pixelLutValue] + // * (1 - disty ) * distx; + // w += (1 - disty ) * distx; + // } + // if ( up + // && gridLut->GetPixel(lutIndex + upOffSet)[pixelLutValue] != -1 ) + // { + // gain += gridLut->GetPixel(lutIndex + upOffSet)[pixelLutValue] + // * disty * (1 - distx ); + // w += disty * (1 - distx ); + // } + // if ( down + // && gridLut->GetPixel(lutIndex + downOffSet)[pixelLutValue] != -1 ) + // { + // gain += gridLut->GetPixel(lutIndex + downOffSet)[pixelLutValue] + // * disty * (1 - distx ); + // w += disty * (1 - distx ); + // } + // if ( up && left + // && gridLut->GetPixel(lutIndex + upOffSet + leftOffSet) + // [pixelLutValue] != -1 ) + // { + // gain += gridLut-> + // GetPixel(lutIndex + upOffSet + leftOffSet)[pixelLutValue] + // * disty * distx; + // w += disty * distx; + // } + // if ( down && left + // && gridLut->GetPixel(lutIndex + downOffSet + leftOffSet) + // [pixelLutValue] != -1 ) + // { + // gain += gridLut-> + // GetPixel(lutIndex + downOffSet + leftOffSet)[pixelLutValue] + // * disty * distx; + // w += disty * distx; + // } + // if ( up && right + // && gridLut->GetPixel(lutIndex + upOffSet + rightOffSet) + // [pixelLutValue] != -1 ) + // { + // gain += gridLut-> + // GetPixel(lutIndex + upOffSet + rightOffSet)[pixelLutValue] + // * disty * distx; + // w += disty * distx ; + // } + // if ( down && right + // && gridLut->GetPixel(lutIndex + downOffSet + rightOffSet) + // [pixelLutValue] != -1 ) + // { + // gain += gridLut-> + // GetPixel(lutIndex + downOffSet + rightOffSet)[pixelLutValue] + // * disty * distx; + // w += disty * distx; + // } + + + typename InputImageType::PointType pixelPoint; + typename itk::ContinuousIndex< double , 2 > pixelIndex; + typename InputImageType::ConstPointer input ( GetInputImage() ); + typename LutType::ConstPointer lut ( GetInputLut() ); + input->TransformIndexToPhysicalPoint( index , pixelPoint ); + lut->TransformPhysicalPointToContinuousIndex( pixelPoint , pixelIndex ); + std::vector< typename LutType::IndexType > neighbors(4); + neighbors[0][0] =std::floor(pixelIndex[0]) ; + neighbors[0][1] =std::floor(pixelIndex[1]) ; + neighbors[1][0] = neighbors[0][0] + 1 ; + neighbors[1][1] = neighbors[0][1] ; + neighbors[2][0] = neighbors[0][0] ; + neighbors[2][1] = neighbors[0][1] + 1 ; + neighbors[3][0] = neighbors[0][0] + 1 ; + neighbors[3][1] = neighbors[0][1] + 1 ; + float gainp(0.f) , wp(0.f) , wtmp(0.f); + int sup0 ( gridLut->GetLargestPossibleRegion().GetSize()[0] ) , + sup1 ( gridLut->GetLargestPossibleRegion().GetSize()[1] ); + for ( auto i : neighbors ) { - gain += gridLut-> - GetPixel(lutIndex + downOffSet + rightOffSet)[pixelLutValue] - * disty * distx; - w += disty * distx; + if ( i[0] < 0 || i[1] < 0 || i[0] >= sup0 || i[1] >= sup1 ) + continue; + if ( gridLut->GetPixel(i)[pixelLutValue] == -1 ) + continue; + wtmp = ( 1 - std::abs( pixelIndex[0] - i[0] ) ) + * ( 1 - std::abs( pixelIndex[1] - i[1] ) ); + if (wtmp>1 || wtmp <0) + std::cout<<"Prb : wtmp = "<<wtmp<<std::endl; + gainp += gridLut->GetPixel(i)[pixelLutValue] * wtmp; + wp += wtmp; } - if (w == 0 ) + if ( wp == 0 ) { - gain = 1; - w = 1; + wp = 1; + gainp = 1; } - return gain/w; + + return gainp/wp; } /** @@ -265,13 +307,15 @@ void ApplyGainFilter < TInputImage , TLut , TOutputImage > ::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); - os << indent << "Is no data activated: " << m_NoDataFlag << std::endl; - os << indent << "No Data: " << m_NoData << std::endl; - os << indent << "Minimum: " << m_Min << std::endl; - os << indent << "Maximum: " << m_Max << std::endl; - os << indent << "Step: " << m_Step << std::endl; - os << indent << "Look up table size: " << m_LutSize << std::endl; - os << indent << "Thumbnail size: " << m_ThumbSize << std::endl; + os << indent << "Is no data activated : " << m_NoDataFlag << std::endl; + os << indent << "No Data : " << m_NoData << std::endl; + os << indent << "Minimum : " << m_Min << std::endl; + os << indent << "Maximum : " << m_Max << std::endl; + os << indent << "Step : " << m_Step << std::endl; + os << indent << "Look up table size : " << m_LutSize << std::endl; + os << indent << "Is ThumbSize from sapcing is activated : " + << m_NoDataFlag << std::endl; + os << indent << "Thumbnail size : " << m_ThumbSize << std::endl; } diff --git a/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx index b78d4354255fbbdb36e4ef09c0828163c964d192..7fb61c1598d4581fda051be85949b39eaf6b8f5f 100644 --- a/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx +++ b/Modules/Filtering/Contrast/include/otbComputeHistoFilter.txx @@ -151,6 +151,19 @@ void ComputeHistoFilter < TInputImage , TOutputImage > region.SetIndex(start); output->SetNumberOfComponentsPerPixel(m_NbBin); output->SetLargestPossibleRegion(region); + typename InputImageType::SpacingType inputSpacing ( input->GetSpacing() ); + typename InputImageType::PointType inputOrigin ( input->GetOrigin() ); + + typename OutputImageType::SpacingType histoSpacing ; + histoSpacing[0] = inputSpacing[0] * m_ThumbSize[0] ; + histoSpacing[1] = inputSpacing[1] * m_ThumbSize[1] ; + output->SetSpacing( histoSpacing ) ; + + typename OutputImageType::PointType histoOrigin ; + histoOrigin[0] = histoSpacing[0] / 2 + inputOrigin[0] - inputSpacing[0] / 2 ; + histoOrigin[1] = histoSpacing[1] / 2 + inputOrigin[1] - inputSpacing[1] / 2 ; + output->SetOrigin( histoOrigin ); + } template <class TInputImage, class TOutputImage >