00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef CVD_INC_INTERPOLATE_H
00023 #define CVD_INC_INTERPOLATE_H
00024
00025 #include <cvd/image.h>
00026 #include <cvd/config.h>
00027 #include <cvd/vision.h>
00028 #include <cvd/vector_image_ref.h>
00029
00030 namespace CVD
00031 {
00043 double interpolate_extremum(double d1, double d2, double d3)
00044 {
00045 assert(d2 >= d1 && d2 > d3 || d2 > d1 && d2 >= d3);
00046 assert(d2 <= d1 && d2 < d3 || d2 < d1 && d2 <= d3);
00047
00048
00049 return -0.5 * (d3 - d1) / (d3 + d1 - 2 * d2);
00050 }
00051
00052 #if defined CVD_HAVE_TOON || defined DOXYGEN_IGNORE_INTERNAL
00053
00077 TooN::Vector<2> interpolate_extremum(double I__1__1,
00078 double I__1_0,
00079 double I__1_1,
00080 double I_0__1,
00081 double I_0_0,
00082 double I_0_1,
00083 double I_1__1,
00084 double I_1_0,
00085 double I_1_1)
00086 {
00087
00088 double gx = 0.5 * (I_1_0 - I__1_0);
00089 double gy = 0.5 * (I_0_1 - I_0__1);
00090
00091
00092 double gxx = I_1_0 - 2 * I_0_0 + I__1_0;
00093 double gyy = I_0_1 - 2 * I_0_0 + I_0__1;
00094 double gxy = 0.25 * (I_1_1 + I__1__1 - I_1__1 - I__1_1);
00095
00096
00097
00098 double Dinv = 1./(gxx * gyy - gxy * gxy);
00099
00100 TooN::Vector<2> v;
00101 v[0] = -Dinv * (gyy * gx - gxy * gy);
00102 v[1] = -Dinv * (-gxy * gx + gxx * gy);
00103
00104 return v;
00105 }
00106
00107
00113 template<class I> TooN::Vector<2> interpolate_extremum(const SubImage<I>& i, ImageRef p)
00114 {
00115 CVD_IMAGE_ASSERT(p.x > 0 && p.y > 0 && p.x < i.size().x-1 && p.y < i.size().y-1, ImageError::AccessOutsideImage);
00116
00117
00118 double I__1__1 = i[p + ImageRef(-1, -1)];
00119 double I__1_0 = i[p + ImageRef(-1, 0)];
00120 double I__1_1 = i[p + ImageRef(-1, 1)];
00121 double I_0__1 = i[p + ImageRef( 0, -1)];
00122 double I_0_0 = i[p + ImageRef( 0, 0)];
00123 double I_0_1 = i[p + ImageRef( 0, 1)];
00124 double I_1__1 = i[p + ImageRef( 1, -1)];
00125 double I_1_0 = i[p + ImageRef( 1, 0)];
00126 double I_1_1 = i[p + ImageRef( 1, 1)];
00127 return interpolate_extremum(I__1__1, I__1_0, I__1_1, I_0__1, I_0_0, I_0_1, I_1__1, I_1_0, I_1_1) + vec(p);
00128 }
00129
00130 #endif
00131
00156 std::pair<TooN::Vector<2>, double> interpolate_extremum_value(double I__1__1,
00157 double I__1_0,
00158 double I__1_1,
00159 double I_0__1,
00160 double I_0_0,
00161 double I_0_1,
00162 double I_1__1,
00163 double I_1_0,
00164 double I_1_1)
00165 {
00166
00167 double gx = 0.5 * (I_1_0 - I__1_0);
00168 double gy = 0.5 * (I_0_1 - I_0__1);
00169
00170
00171 double gxx = I_1_0 - 2 * I_0_0 + I__1_0;
00172 double gyy = I_0_1 - 2 * I_0_0 + I_0__1;
00173 double gxy = 0.25 * (I_1_1 + I__1__1 - I_1__1 - I__1_1);
00174
00175
00176
00177 double Dinv = 1./(gxx * gyy - gxy * gxy);
00178
00179 TooN::Vector<2> v;
00180 v[0] = -Dinv * (gyy * gx - gxy * gy);
00181 v[1] = -Dinv * (-gxy * gx + gxx * gy);
00182
00183 double value = I_0_0 + (gx + 0.5 * gxx * v[0] + gxy * v[1])* v[0] + (gy + 0.5 * gyy * v[1]) * v[1];
00184
00185 return std::make_pair(v, value);
00186 }
00187
00193 template<class I> std::pair<TooN::Vector<2>, double> interpolate_extremum_value(const SubImage<I>& i, ImageRef p)
00194 {
00195 CVD_IMAGE_ASSERT(p.x > 0 && p.y > 0 && p.x < i.size().x-1 && p.y < i.size().y-1, ImageError::AccessOutsideImage);
00196
00197
00198 double I__1__1 = i[p + ImageRef(-1, -1)];
00199 double I__1_0 = i[p + ImageRef(-1, 0)];
00200 double I__1_1 = i[p + ImageRef(-1, 1)];
00201 double I_0__1 = i[p + ImageRef( 0, -1)];
00202 double I_0_0 = i[p + ImageRef( 0, 0)];
00203 double I_0_1 = i[p + ImageRef( 0, 1)];
00204 double I_1__1 = i[p + ImageRef( 1, -1)];
00205 double I_1_0 = i[p + ImageRef( 1, 0)];
00206 double I_1_1 = i[p + ImageRef( 1, 1)];
00207 std::pair<TooN::Vector<2>, double> result = interpolate_extremum_value(I__1__1, I__1_0, I__1_1, I_0__1, I_0_0, I_0_1, I_1__1, I_1_0, I_1_1);
00208 result.first += vec(p);
00209 return result;
00210 }
00211
00212 }
00213
00214 #endif
00215