Commit d76b85598a4655d1cff33260551e7ec302b7ee8a

Authored by Jordi Inglada
1 parent 9532b414

ENH: add option not to copy input bands

app/iota2FeatureExtraction.cxx
... ... @@ -79,6 +79,9 @@ private:
79 79 "No data value (default = -10000).");
80 80 MandatoryOff("nodata");
81 81  
  82 + AddParameter(ParameterType_Empty, "copyinput", "Copy input bands to output image. Default value is true");
  83 + MandatoryOff("copyinput");
  84 +
82 85 AddRAMParameter();
83 86 }
84 87  
... ... @@ -88,8 +91,6 @@ private:
88 91  
89 92 void DoExecute()
90 93 {
91   - IsParameterEnabled("comp") ;
92   -
93 94 auto cpd = 1;
94 95 if(IsParameterEnabled("comp"))
95 96 cpd = GetParameterInt("comp");
... ... @@ -108,6 +109,11 @@ private:
108 109 auto noDataValue = float{-10000};
109 110 if(IsParameterEnabled("nodata"))
110 111 noDataValue = GetParameterInt("nodata");
  112 + auto copyInputBands = true;
  113 + if (IsParameterEnabled("copyinput"))
  114 + {
  115 + copyInputBands = GetParameterEmpty("copyinput");
  116 + }
111 117  
112 118 FloatVectorImageType::Pointer inputImage = this->GetParameterImage("in");
113 119 inputImage->UpdateOutputInformation();
... ... @@ -118,7 +124,8 @@ private:
118 124 swirIndex,
119 125 normIndexFactor,
120 126 noDataValue,
121   - nbOfInputBands);
  127 + nbOfInputBands,
  128 + copyInputBands);
122 129 m_FeatureExtractionFilter = FeatureExtractionFilterType::New();
123 130 m_FeatureExtractionFilter->SetFunctor(fef);
124 131 m_FeatureExtractionFilter->SetInput(inputImage);
... ...
include/iota2FeatureExtraction.h
... ... @@ -69,10 +69,10 @@ public:
69 69  
70 70 FeatureExtractionFunctor() = default;
71 71 FeatureExtractionFunctor(size_t cpd, size_t ri, size_t ni, size_t si,
72   - ValueType nif, ValueType ndv, size_t nic)
  72 + ValueType nif, ValueType ndv, size_t nic, bool cpi)
73 73 : m_ComponentsPerDate{cpd}, m_RedIndex{ri},
74 74 m_NIRIndex{ni}, m_SWIRIndex{si}, m_NormalizedIndexFactor{nif},
75   - m_NoDataValue{ndv}, m_NumberOfInputComponents{nic}
  75 + m_NoDataValue{ndv}, m_NumberOfInputComponents{nic}, m_CopyInputBands{cpi}
76 76 {
77 77 m_NumberOfDates = m_NumberOfInputComponents/m_ComponentsPerDate;
78 78 m_NumberOfOutputComponents = (m_NumberOfFeatures +
... ... @@ -92,8 +92,12 @@ public:
92 92 p.GetDataPointer()+p.GetSize());
93 93 //copy the spectral bands
94 94 auto outVec = std::vector<ValueType>(m_NumberOfOutputComponents);
  95 + size_t copyOffset = (m_CopyInputBands?m_NumberOfInputComponents:0);
95 96 //copy the input reflectances
96   - std::copy(inVec.cbegin(), inVec.cend(), outVec.begin());
  97 + if(m_CopyInputBands)
  98 + {
  99 + std::copy(inVec.cbegin(), inVec.cend(), outVec.begin());
  100 + }
97 101  
98 102 size_t date_counter{0};
99 103 auto inIt = inVec.cbegin();
... ... @@ -106,9 +110,9 @@ public:
106 110 return std::fabs(x - m_NoDataValue)<0.1;
107 111 }))
108 112 {
109   - outVec[m_NumberOfInputComponents+date_counter] = m_NoDataValue;
110   - outVec[m_NumberOfInputComponents+m_NumberOfDates+date_counter] = m_NoDataValue;
111   - outVec[m_NumberOfInputComponents+m_NumberOfDates*2+date_counter] = m_NoDataValue;
  113 + outVec[copyOffset+date_counter] = m_NoDataValue;
  114 + outVec[copyOffset+m_NumberOfDates+date_counter] = m_NoDataValue;
  115 + outVec[copyOffset+m_NumberOfDates*2+date_counter] = m_NoDataValue;
112 116 }
113 117 else
114 118 {
... ... @@ -126,9 +130,9 @@ public:
126 130 auto brightness = std::sqrt(std::accumulate(tmpVec.begin(), tmpVec.end(),
127 131 ValueType{0}));
128 132 //append the features
129   - outVec[m_NumberOfInputComponents+date_counter] = ndvi * m_NormalizedIndexFactor;
130   - outVec[m_NumberOfInputComponents+m_NumberOfDates+date_counter] = ndwi * m_NormalizedIndexFactor;
131   - outVec[m_NumberOfInputComponents+m_NumberOfDates*2+date_counter] = brightness;
  133 + outVec[copyOffset+date_counter] = ndvi * m_NormalizedIndexFactor;
  134 + outVec[copyOffset+m_NumberOfDates+date_counter] = ndwi * m_NormalizedIndexFactor;
  135 + outVec[copyOffset+m_NumberOfDates*2+date_counter] = brightness;
132 136 }
133 137 //move to the next date
134 138 std::advance(inIt, m_ComponentsPerDate);
... ... @@ -158,6 +162,7 @@ protected:
158 162 ValueType m_NormalizedIndexFactor;
159 163 ValueType m_NoDataValue;
160 164 size_t m_NumberOfInputComponents;
  165 + bool m_CopyInputBands;
161 166 size_t m_NumberOfOutputComponents;
162 167 size_t m_NumberOfDates;
163 168 static constexpr size_t m_NumberOfFeatures = 3;
... ...
test/CMakeLists.txt
... ... @@ -23,7 +23,10 @@ target_link_libraries(iota2FeatureExtractionTests ${${otb-module}-Test_LIBRARIES
23 23 otb_module_target_label(iota2FeatureExtractionTests)
24 24  
25 25 otb_add_test(NAME iota2FexFunctor
26   - COMMAND iota2FeatureExtractionTests fexFunctor)
  26 + COMMAND iota2FeatureExtractionTests fexFunctor 1)
  27 +
  28 +otb_add_test(NAME iota2FexFunctorNoCopy
  29 + COMMAND iota2FeatureExtractionTests fexFunctor 0)
27 30  
28 31 otb_test_application(NAME iota2FexApp
29 32 APP iota2FeatureExtraction
... ...
test/iota2FeatureExtractionFunctor.cxx
... ... @@ -15,7 +15,7 @@
15 15 #include "itkMacro.h"
16 16 #include "iota2FeatureExtraction.h"
17 17 #include "itkVariableLengthVector.h"
18   -int fexFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
  18 +int fexFunctor(int argc, char * argv[])
19 19 {
20 20 using ValueType = float;
21 21 using PixelType = itk::VariableLengthVector<ValueType>;
... ... @@ -28,54 +28,70 @@ int fexFunctor(int itkNotUsed(argc), char * itkNotUsed(argv)[])
28 28 constexpr auto ndv = ValueType{-10000};
29 29 constexpr auto nic = size_t{cpd*nbd};
30 30  
  31 + bool copyInputBands = true;
  32 + if(argc!=2)
  33 + {
  34 + std::cout << "Need one arg" << "\n";
  35 + return EXIT_FAILURE;
  36 + }
  37 + if(std::stoi(argv[1]) == 0)
  38 + {
  39 + copyInputBands = false;
  40 + }
  41 +
  42 + size_t outOffset = (copyInputBands?cpd:0);
  43 +
31 44 std::vector<ValueType> inVec{2,3,4,5,
32 45 5,4,3,2};
33 46 const auto ndvi1 = (inVec[ni-1]-inVec[ri-1])/(inVec[ni-1]+inVec[ri-1]);
34   - const auto ndvi2 = (inVec[ni+cpd-1]-inVec[ri+cpd-1])/(inVec[ni+cpd-1]+inVec[ri+cpd-1]);
  47 + const auto ndvi2 = (inVec[ni+cpd-1]-inVec[ri+cpd-1])/
  48 + (inVec[ni+cpd-1]+inVec[ri+cpd-1]);
35 49 constexpr ValueType b2 = std::sqrt(ValueType{5*5+4*4+3*3+2*2});
36 50  
37 51 PixelType p(nic);
38 52 for(size_t i=0; i<nic; i++)
39 53 p[i] = inVec[i];
40   - auto func = iota2::FeatureExtractionFunctor<PixelType>(cpd,ri,ni,si,nif,ndv,nic);
  54 + auto func = iota2::FeatureExtractionFunctor<PixelType>(cpd,ri,ni,si,nif,ndv,
  55 + nic,copyInputBands);
41 56 auto res = func(p);
42   - auto ndvi1_res = res[cpd*nbd];
43   - auto ndvi2_res = res[cpd*nbd+1];
44   - auto b2_res = res[cpd*nbd+2*nbd+1];
  57 + auto ndvi1_res = res[outOffset*nbd];
  58 + auto ndvi2_res = res[outOffset*nbd+1];
  59 + auto b2_res = res[outOffset*nbd+2*nbd+1];
45 60  
46 61  
47 62 if(std::abs(ndvi1-ndvi1_res)>10e-5)
48 63 {
49   - std::cout << ndvi1 << "\t" << ndvi1_res << "\n";
  64 + std::cout << "NDVI1 " << ndvi1 << "\t" << ndvi1_res << "\n";
50 65 return EXIT_FAILURE;
51 66 }
52 67  
53 68 if(std::abs(ndvi2-ndvi2_res)>10e-5)
54 69 {
55   - std::cout << ndvi2 << "\t" << ndvi2_res << "\n";
  70 + std::cout << "NDVI2 " << ndvi2 << "\t" << ndvi2_res << "\n";
56 71 return EXIT_FAILURE;
57 72 }
58 73  
59 74 if(std::abs(b2-b2_res)>10e-5)
60 75 {
61   - std::cout << b2 << "\t" << b2_res << "\n";
  76 + std::cout << "BRI2 " << b2 << "\t" << b2_res << "\n";
62 77 return EXIT_FAILURE;
63 78 }
64 79  
65   - if(p[1]!=res[1])
  80 + if(p[1]!=res[1] && copyInputBands)
66 81 {
67 82 std::cout << p[1] << "\t" << res[1] << "\n";
68 83 return EXIT_FAILURE;
69 84 }
70 85  
  86 +
71 87 p[0] = ndv;
72 88 res = func(p);
73   - ndvi1_res = res[cpd*nbd];
  89 + ndvi1_res = res[outOffset*nbd];
74 90 if(ndvi1_res != ndv)
75 91 {
76 92 std::cout << p[0] << "\t" << res[1] << " --> should be no data\n";
77 93 return EXIT_FAILURE;
78 94 }
79 95  
80   - return EXIT_SUCCESS;
  96 + return EXIT_SUCCESS;
81 97 }
... ...