1 #include <ossim/base/ossim2dBilinearTransform.h>
2 #include <ossim/base/ossimLeastSquaresBilin.h>
3 #include <ossim/base/ossimKeywordlist.h>
4 #include <iostream>
5 RTTI_DEF1(ossim2dBilinearTransform, "ossim2dBilinearTransform", ossim2dTo2dTransform);
ossim2dBilinearTransform()6 ossim2dBilinearTransform::ossim2dBilinearTransform()
7 {
8    std::fill(m_coefficientsXTerm, m_coefficientsXTerm+4, 0.0);
9    std::fill(m_coefficientsYTerm, m_coefficientsYTerm+4, 0.0);
10    std::fill(m_inverseCoefficientsXTerm, m_inverseCoefficientsXTerm+4, 0.0);
11    std::fill(m_inverseCoefficientsYTerm, m_inverseCoefficientsYTerm+4, 0.0);
12 
13    // setup identity
14    //
15    m_coefficientsXTerm[1] = 1.0;
16    m_coefficientsYTerm[2] = 1.0;
17    m_inverseCoefficientsXTerm[1] = 1.0;
18    m_inverseCoefficientsYTerm[2] = 1.0;
19 }
20 
ossim2dBilinearTransform(const ossim2dBilinearTransform & src)21 ossim2dBilinearTransform::ossim2dBilinearTransform(const ossim2dBilinearTransform& src)
22 :ossim2dTo2dTransform(src)
23 {
24    std::copy(src.m_coefficientsXTerm, src.m_coefficientsXTerm+4, m_coefficientsXTerm);
25    std::copy(src.m_coefficientsYTerm, src.m_coefficientsYTerm+4, m_coefficientsYTerm);
26    std::copy(src.m_inverseCoefficientsXTerm, src.m_inverseCoefficientsXTerm+4, m_inverseCoefficientsXTerm);
27    std::copy(src.m_inverseCoefficientsYTerm, src.m_inverseCoefficientsYTerm+4, m_inverseCoefficientsYTerm);
28 }
29 
setFromPoints(const ossimDpt & in1,const ossimDpt & in2,const ossimDpt & in3,const ossimDpt & in4,const ossimDpt & out1,const ossimDpt & out2,const ossimDpt & out3,const ossimDpt & out4)30 void ossim2dBilinearTransform::setFromPoints(const ossimDpt& in1, const ossimDpt& in2, const ossimDpt& in3, const ossimDpt& in4,
31                                              const ossimDpt& out1, const ossimDpt& out2, const ossimDpt& out3, const ossimDpt& out4)
32 {
33    ossimDpt input[4];
34    ossimDpt output[4];
35 
36    input[0] = in1;
37    input[1] = in2;
38    input[2] = in3;
39    input[3] = in4;
40 
41    output[0] = out1;
42    output[1] = out2;
43    output[2] = out3;
44    output[3] = out4;
45 
46    setFromPoints(&input[0], &output[0], 4);
47 }
48 
setFromPoints(const ossimDpt * input,const ossimDpt * output,ossim_uint32 arraySize)49 void ossim2dBilinearTransform::setFromPoints(const ossimDpt* input,
50                                              const ossimDpt* output,
51                                              ossim_uint32 arraySize)
52 {
53    ossimLeastSquaresBilin inx;
54    ossimLeastSquaresBilin inversex;
55    ossimLeastSquaresBilin iny;
56    ossimLeastSquaresBilin inversey;
57    ossim_uint32 idx = 0;
58    for(idx=0; idx < arraySize; ++idx)
59    {
60       inx.addSample(input[idx].x, input[idx].y, output[idx].x);
61       inversex.addSample(output[idx].x, output[idx].y, input[idx].x);
62       iny.addSample(input[idx].x, input[idx].y, output[idx].y);
63       inversey.addSample(output[idx].x, output[idx].y, input[idx].y);
64    }
65    inx.solveLS();
66    inversex.solveLS();
67    iny.solveLS();
68    inversey.solveLS();
69    inx.getLSParms(m_coefficientsXTerm[0], m_coefficientsXTerm[1], m_coefficientsXTerm[2], m_coefficientsXTerm[3]);
70    iny.getLSParms(m_coefficientsYTerm[0], m_coefficientsYTerm[1], m_coefficientsYTerm[2], m_coefficientsYTerm[3]);
71    inversex.getLSParms(m_inverseCoefficientsXTerm[0], m_inverseCoefficientsXTerm[1], m_inverseCoefficientsXTerm[2], m_inverseCoefficientsXTerm[3]);
72    inversey.getLSParms(m_inverseCoefficientsYTerm[0], m_inverseCoefficientsYTerm[1], m_inverseCoefficientsYTerm[2], m_inverseCoefficientsYTerm[3]);
73 }
74 
saveState(ossimKeywordlist & kwl,const char * prefix) const75 bool ossim2dBilinearTransform::saveState(ossimKeywordlist& kwl,
76                                        const char* prefix)const
77 {
78    ossimString xterm = (ossimString::toString(m_coefficientsXTerm[0])
79                         +" "+ossimString::toString(m_coefficientsXTerm[1])
80                         +" "+ossimString::toString(m_coefficientsXTerm[2])
81                         +" "+ossimString::toString(m_coefficientsXTerm[3]));
82    ossimString yterm = (ossimString::toString(m_coefficientsYTerm[0])
83                         +" "+ossimString::toString(m_coefficientsYTerm[1])
84                         +" "+ossimString::toString(m_coefficientsYTerm[2])
85                         +" "+ossimString::toString(m_coefficientsYTerm[3]));
86    ossimString inverse_xterm = (ossimString::toString(m_inverseCoefficientsXTerm[0])
87                         +" "+ossimString::toString(m_inverseCoefficientsXTerm[1])
88                         +" "+ossimString::toString(m_inverseCoefficientsXTerm[2])
89                         +" "+ossimString::toString(m_inverseCoefficientsXTerm[3]));
90    ossimString inverse_yterm = (ossimString::toString(m_inverseCoefficientsYTerm[0])
91                         +" "+ossimString::toString(m_inverseCoefficientsYTerm[1])
92                         +" "+ossimString::toString(m_inverseCoefficientsYTerm[2])
93                         +" "+ossimString::toString(m_inverseCoefficientsYTerm[3]));
94 
95    kwl.add(prefix, "xterm", xterm, true);
96    kwl.add(prefix, "yterm", yterm, true);
97    kwl.add(prefix, "inverse_xterm", inverse_xterm, true);
98    kwl.add(prefix, "inverse_yterm", inverse_yterm, true);
99    return ossim2dTo2dTransform::saveState(kwl, prefix);
100 }
101 
loadState(const ossimKeywordlist & kwl,const char * prefix)102 bool ossim2dBilinearTransform::loadState(const ossimKeywordlist& kwl,
103                                        const char* prefix)
104 {
105    bool result = true;
106    ossimString xterm = kwl.find(prefix, "xterm");
107    ossimString yterm = kwl.find(prefix, "yterm");
108    ossimString inverse_xterm = kwl.find(prefix, "inverse_xterm");
109    ossimString inverse_yterm = kwl.find(prefix, "inverse_yterm");
110 
111    std::vector<ossimString> values;
112    xterm.split(values, " ");
113    if(values.size() == 4)
114    {
115       m_coefficientsXTerm[0] = values[0].toDouble();
116       m_coefficientsXTerm[1] = values[1].toDouble();
117       m_coefficientsXTerm[2] = values[2].toDouble();
118       m_coefficientsXTerm[3] = values[3].toDouble();
119    }
120    else
121    {
122       result = false;
123    }
124    values.clear();
125    yterm.split(values, " ");
126    if(values.size() == 4)
127    {
128       m_coefficientsYTerm[0] = values[0].toDouble();
129       m_coefficientsYTerm[1] = values[1].toDouble();
130       m_coefficientsYTerm[2] = values[2].toDouble();
131       m_coefficientsYTerm[3] = values[3].toDouble();
132    }
133    else
134    {
135       result = false;
136    }
137    values.clear();
138    inverse_xterm.split(values, " ");
139    if(values.size() == 4)
140    {
141       m_inverseCoefficientsXTerm[0] = values[0].toDouble();
142       m_inverseCoefficientsXTerm[1] = values[1].toDouble();
143       m_inverseCoefficientsXTerm[2] = values[2].toDouble();
144       m_inverseCoefficientsXTerm[3] = values[3].toDouble();
145    }
146    else
147    {
148       result = false;
149    }
150    values.clear();
151    inverse_yterm.split(values, " ");
152    if(values.size() == 4)
153    {
154       m_inverseCoefficientsYTerm[0] = values[0].toDouble();
155       m_inverseCoefficientsYTerm[1] = values[1].toDouble();
156       m_inverseCoefficientsYTerm[2] = values[2].toDouble();
157       m_inverseCoefficientsYTerm[3] = values[3].toDouble();
158    }
159    else
160    {
161       result = false;
162    }
163 
164    if(result)
165    {
166       result = ossim2dTo2dTransform::loadState(kwl, prefix);
167    }
168 
169    return result;
170 }
171