1 #ifndef ossim2dBilinearTransform_HEADER 2 #define ossim2dBilinearTransform_HEADER 3 #include <ossim/base/ossim2dTo2dTransform.h> 4 #include <algorithm> 5 /** 6 * ossim2dBilinearTransform allows one to specify a set of input points and output points 7 * and will fit a bilinear transform to those points. Function of the form is solved for each 8 * output dimension. 9 * 10 * z(x,y) = a + b*x + c*y + d*x*y 11 * 12 * We use the ossimLeastSquareBilin solver to solve for the coefficients. 13 * 14 */ 15 class OSSIM_DLL ossim2dBilinearTransform : public ossim2dTo2dTransform 16 { 17 public: 18 /** 19 * Initialize to the identity 20 */ 21 ossim2dBilinearTransform(); 22 23 /** 24 * Initialize the transform that best fits the input and output arrays. 25 * If the input and output are well dispersed and are 4 points it should fit 26 * exactly. Both arrays should be of equal number of points 27 * 28 * @param input the list of input points 29 * @param output the list of output points to transform the input to 30 * @param arraySize the number of points for the arrays. 31 */ 32 ossim2dBilinearTransform(const ossimDpt* input, 33 const ossimDpt* output, 34 ossim_uint32 arraySize) 35 { 36 setFromPoints(input, output, arraySize); 37 } 38 39 /** 40 * Mapping 4 corners to an output 4 corners. 41 * 42 */ 43 ossim2dBilinearTransform(const ossimDpt& in1, const ossimDpt& in2, const ossimDpt& in3, const ossimDpt& in4, 44 const ossimDpt& out1, const ossimDpt& out2, const ossimDpt& out3, const ossimDpt& out4) 45 { 46 setFromPoints(in1, in2, in3, in4, out1, out2, out3, out4); 47 } 48 49 /** 50 * Copy constructor 51 */ 52 ossim2dBilinearTransform(const ossim2dBilinearTransform& src); 53 54 /** 55 * Duplication method that duplicates this object 56 */ 57 virtual ossimObject* dup()const{return new ossim2dBilinearTransform(*this);} 58 59 /** 60 * Overloaded operator equal that allows for assignment. 61 * 62 * @param src the src data to copy into this object. It will call the base classes 63 * equal operator. 64 */ 65 const ossim2dBilinearTransform& operator =(const ossim2dBilinearTransform& src) 66 { 67 if(this == &src) return *this; 68 69 ossim2dTo2dTransform::operator =(*this); // call base classes equal operator 70 std::copy(src.m_coefficientsXTerm, src.m_coefficientsXTerm+4, m_coefficientsXTerm); 71 std::copy(src.m_coefficientsYTerm, src.m_coefficientsYTerm+4, m_coefficientsYTerm); 72 std::copy(src.m_inverseCoefficientsXTerm, src.m_inverseCoefficientsXTerm+4, m_inverseCoefficientsXTerm); 73 std::copy(src.m_inverseCoefficientsYTerm, src.m_inverseCoefficientsYTerm+4, m_inverseCoefficientsYTerm); 74 75 return *this; 76 } 77 78 /** 79 * Mapping 4 corners to an output 4 corners. Will use the ossimLeastSquareBilin class to solve 80 * the bilinear coefficients that maps the given input points to the output points. 81 */ 82 void setFromPoints(const ossimDpt& in1, const ossimDpt& in2, const ossimDpt& in3, const ossimDpt& in4, 83 const ossimDpt& out1, const ossimDpt& out2, const ossimDpt& out3, const ossimDpt& out4); 84 85 /** 86 * Initialize the transform that best fits the input and output arrays. 87 * If the input and output are well dispersed and are 4 points it should fit 88 * exactly. Both arrays should be of equal number of points 89 * 90 * @param input the list of input points 91 * @param output the list of output points to transform the input to 92 * @param arraySize the number of points for the arrays. 93 */ 94 void setFromPoints(const ossimDpt* input, 95 const ossimDpt* output, 96 ossim_uint32 arraySize); 97 98 /** 99 * forward transform will transform an input point to the output. 100 */ 101 virtual void forward(const ossimDpt& input, 102 ossimDpt& output) const 103 { 104 output.x = (m_coefficientsXTerm[0] + 105 m_coefficientsXTerm[1]*input.x + 106 m_coefficientsXTerm[2]*input.y + 107 m_coefficientsXTerm[3]*input.x*input.y); 108 output.y = (m_coefficientsYTerm[0] + 109 m_coefficientsYTerm[1]*input.x + 110 m_coefficientsYTerm[2]*input.y + 111 m_coefficientsYTerm[3]*input.x*input.y); 112 } 113 114 /** 115 * forward transform will transform an input point to the output and modify the passed in point 116 * to the new value 117 */ 118 virtual void forward(ossimDpt& modify_this) const 119 { 120 double saveX = modify_this.x; 121 modify_this.x = (m_coefficientsXTerm[0] + 122 m_coefficientsXTerm[1]*modify_this.x + 123 m_coefficientsXTerm[2]*modify_this.y + 124 m_coefficientsXTerm[3]*modify_this.x*modify_this.y); 125 modify_this.y = (m_coefficientsYTerm[0] + 126 m_coefficientsYTerm[1]*saveX + 127 m_coefficientsYTerm[2]*modify_this.y + 128 m_coefficientsYTerm[3]*saveX*modify_this.y); 129 } 130 131 /** 132 * Inverts the point back to the original input value. 133 */ 134 virtual void inverse(const ossimDpt& input, 135 ossimDpt& output) const 136 { 137 output.x = (m_inverseCoefficientsXTerm[0] + 138 m_inverseCoefficientsXTerm[1]*input.x + 139 m_inverseCoefficientsXTerm[2]*input.y + 140 m_inverseCoefficientsXTerm[3]*input.x*input.y); 141 output.y = (m_inverseCoefficientsYTerm[0] + 142 m_inverseCoefficientsYTerm[1]*input.x + 143 m_inverseCoefficientsYTerm[2]*input.y + 144 m_inverseCoefficientsYTerm[3]*input.x*input.y); 145 } 146 147 /** 148 * Inverts the point back to the original input value and modifies the passed in point 149 * to the new value. 150 */ 151 virtual void inverse(ossimDpt& modify_this) const 152 { 153 double saveX = modify_this.x; 154 modify_this.x = (m_inverseCoefficientsXTerm[0] + 155 m_inverseCoefficientsXTerm[1]*modify_this.x + 156 m_inverseCoefficientsXTerm[2]*modify_this.y + 157 m_inverseCoefficientsXTerm[3]*modify_this.x*modify_this.y); 158 modify_this.y = (m_inverseCoefficientsYTerm[0] + 159 m_inverseCoefficientsYTerm[1]*saveX + 160 m_inverseCoefficientsYTerm[2]*modify_this.y + 161 m_inverseCoefficientsYTerm[3]*saveX*modify_this.y); 162 } 163 164 /** 165 * Saves the state of this object. 166 */ 167 virtual bool saveState(ossimKeywordlist& kwl, 168 const char* prefix = 0)const; 169 170 /** 171 * loads the state of this object from a keywordlist. 172 */ 173 virtual bool loadState(const ossimKeywordlist& kwl, 174 const char* prefix = 0); 175 176 /** 177 * prints the contents of this object. Will also cal the base classes 178 * print method. 179 */ 180 virtual std::ostream& print(std::ostream& out) const 181 { 182 ossim2dTo2dTransform::print(out); 183 out << "xTerm: " << m_coefficientsXTerm[0] << ", " << m_coefficientsXTerm[1] << ", " 184 << m_coefficientsXTerm[2] << ", " << m_coefficientsXTerm[3] << "\n"; 185 out << "yTerm: " << m_coefficientsYTerm[0] << ", " << m_coefficientsYTerm[1] << ", " 186 << m_coefficientsYTerm[2] << ", " << m_coefficientsYTerm[3] << "\n"; 187 188 out << "xInverseTerm: " << m_inverseCoefficientsXTerm[0] << ", " << m_inverseCoefficientsXTerm[1] << ", " 189 << m_inverseCoefficientsXTerm[2] << ", " << m_inverseCoefficientsXTerm[3] << "\n"; 190 out << "yInverseTerm: " << m_inverseCoefficientsYTerm[0] << ", " << m_inverseCoefficientsYTerm[1] << ", " 191 << m_inverseCoefficientsYTerm[2] << ", " << m_inverseCoefficientsYTerm[3] << "\n"; 192 193 return out; 194 } 195 196 protected: 197 ossim_float64 m_coefficientsXTerm[4]; // constant, linear x, linear y, cross xy 198 ossim_float64 m_coefficientsYTerm[4]; // constant, linear x, linear y, cross xy 199 200 ossim_float64 m_inverseCoefficientsXTerm[4]; // constant, linear x, linear y, cross xy 201 ossim_float64 m_inverseCoefficientsYTerm[4]; // constant, linear x, linear y, cross xy 202 TYPE_DATA; 203 }; 204 205 #endif 206