TensorOps.C
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036 #ifndef IMAGE_TENSOROPS_C_DEFINED
00037 #define IMAGE_TENSOROPS_C_DEFINED
00038
00039 #include "Image/TensorOps.H"
00040
00041
00042
00043
00044 #include "Image/Image.H"
00045 #include "Image/Pixels.H"
00046 #include "Image/Range.H"
00047 #include "Image/MatrixOps.H"
00048 #include "Util/Assert.H"
00049 #include "Util/MathFunctions.H"
00050 #include "Util/safecopy.H"
00051 #include "rutz/trace.h"
00052 #include "GUI/DebugWin.H"
00053
00054 #include <algorithm>
00055 #include <cmath>
00056 #include <climits>
00057 #include <cfloat>
00058 #include <numeric>
00059
00060 #if defined(INVT_USE_MMX) || defined(INVT_USE_SSE) || defined(INVT_USE_SSE2)
00061 #include "Util/mmx-sse.H"
00062 #endif
00063
00064
00065
00066
00067
00068
00069 template <class T>
00070 TensorField getTensor(const Image<T>& img, int kernelSize)
00071 {
00072 GVX_TRACE(__PRETTY_FUNCTION__);
00073 typedef typename promote_trait<T, float>::TP TF;
00074
00075 ASSERT( (kernelSize == 3 ) | (kernelSize == 5));
00076 TensorField tensorField(img.getDims(), NO_INIT);
00077
00078 bool useScharr = true;
00079
00080 typename Image<T>::const_iterator src = img.begin();
00081
00082 const int w = img.getWidth(), h = img.getHeight();
00083 typename Image<TF>::iterator t1 = tensorField.t1.beginw();
00084 typename Image<TF>::iterator t2 = tensorField.t2.beginw();
00085 typename Image<TF>::iterator t3 = tensorField.t3.beginw();
00086 typename Image<TF>::iterator t4 = tensorField.t4.beginw();
00087 TF zero = TF();
00088
00089
00090 switch(kernelSize) {
00091 case 3:
00092 for (int i = 0; i < w; i ++)
00093 {
00094 *t1++ = zero; *t2++ = zero;
00095 *t3++ = zero; *t4++ = zero;
00096 }
00097 src += w;
00098 break;
00099 case 5:
00100 for (int i = 0; i < w*2; i ++)
00101 {
00102 *t1++ = zero; *t2++ = zero;
00103 *t3++ = zero; *t4++ = zero;
00104 }
00105 src += w*2;
00106 break;
00107 }
00108
00109
00110 switch(kernelSize)
00111 {
00112 case 3:
00113 for (int j = 1; j < h-1; j ++)
00114 {
00115
00116 *t1++ = zero; *t2++ = zero;
00117 *t3++ = zero; *t4++ = zero;
00118 ++src;
00119
00120 if (useScharr)
00121 {
00122 for (int i = 1; i < w-1; i ++)
00123 {
00124 TF valx = -3*src[-1*w + -1] + 0*src[-1*w + 0] + 3*src[-1*w + 1]
00125 + -10*src[ 0*w + -1] + 0*src[ 0*w + 0] + 10*src[ 0*w + 1]
00126 + -3*src[ 1*w + -1] + 0*src[ 1*w + 0] + 3*src[ 1*w + 1];
00127
00128 TF valy = 3*src[-1*w + -1] + 10*src[-1*w + 0] + 3*src[-1*w + 1]
00129 + 0*src[ 0*w + -1] + 0*src[ 0*w + 0] + 0*src[ 0*w + 1]
00130 + -3*src[ 1*w + -1] + -10*src[ 1*w + 0] + -3*src[ 1*w + 1];
00131
00132 *t1++ = valx*valx; *t2++ = valx*valy;
00133 *t3++ = valx*valy; *t4++ = valy*valy;
00134 ++ src;
00135 }
00136 } else {
00137
00138 for (int i = 1; i < w-1; i ++)
00139 {
00140 TF valx = -1*src[-1*w + -1] + 0*src[-1*w + 0] + 1*src[-1*w + 1]
00141 + -2*src[ 0*w + -1] + 0*src[ 0*w + 0] + 2*src[ 0*w + 1]
00142 + -1*src[ 1*w + -1] + 0*src[ 1*w + 0] + 1*src[ 1*w + 1];
00143
00144 TF valy = 1*src[-1*w + -1] + 2*src[-1*w + 0] + 1*src[-1*w + 1]
00145 + 0*src[ 0*w + -1] + 0*src[ 0*w + 0] + 0*src[ 0*w + 1]
00146 + -1*src[ 1*w + -1] + -2*src[ 1*w + 0] + -1*src[ 1*w + 1];
00147
00148 *t1++ = valx*valx; *t2++ = valx*valy;
00149 *t3++ = valx*valy; *t4++ = valy*valy;
00150 ++ src;
00151 }
00152 }
00153
00154
00155 *t1++ = zero; *t2++ = zero;
00156 *t3++ = zero; *t4++ = zero;
00157 ++src;
00158 }
00159 break;
00160 case 5:
00161 for (int j = 2; j < h-2; j ++)
00162 {
00163
00164 *t1++ = zero; *t2++ = zero;
00165 *t3++ = zero; *t4++ = zero;
00166 ++src;
00167
00168 for (int i = 2; i < w-2; i ++)
00169 {
00170 TF valx = -1*src[-2*w + -2] + -2*src[-2*w + -1] + 0*src[-2*w + 0] + 2*src[-2*w + 1] + 1*src[-2*w + 2]
00171 + -4*src[-1*w + -2] + -8*src[-1*w + -1] + 0*src[-1*w + 0] + 8*src[-1*w + 1] + 4*src[-1*w + 2]
00172 + -6*src[ 0*w + -2] + -12*src[ 0*w + -1] + 0*src[ 0*w + 0] + 12*src[ 0*w + 1] + 6*src[ 0*w + 2]
00173 + -4*src[ 1*w + -2] + -8*src[ 1*w + -1] + 0*src[ 1*w + 0] + 8*src[ 1*w + 1] + 4*src[ 1*w + 2]
00174 + -1*src[ 2*w + -2] + -2*src[ 2*w + -1] + 0*src[ 2*w + 0] + 2*src[ 2*w + 1] + 1*src[ 2*w + 2];
00175
00176 TF valy = 1*src[-2*w + -2] + 4*src[-2*w + -1] + 6*src[-2*w + 0] + 4*src[-2*w + 1] + 1*src[-2*w + 2]
00177 + 2*src[-1*w + -2] + 8*src[-1*w + -1] + 12*src[-1*w + 0] + 8*src[-1*w + 1] + 2*src[-1*w + 2]
00178 + 0*src[ 0*w + -2] + 0*src[ 0*w + -1] + 0*src[ 0*w + 0] + 0*src[ 0*w + 1] + 0*src[ 0*w + 2]
00179 + -2*src[ 1*w + -2] + -8*src[ 1*w + -1] + -12*src[ 1*w + 0] + -8*src[ 1*w + 1] + -2*src[ 1*w + 2]
00180 + -1*src[ 2*w + -2] + -4*src[ 2*w + -1] + -6*src[ 2*w + 0] + -4*src[ 2*w + 1] + -1*src[ 2*w + 2];
00181
00182 *t1++ = valx*valx; *t2++ = valx*valy;
00183 *t3++ = valx*valy; *t4++ = valy*valy;
00184 ++ src;
00185 }
00186
00187 *t1++ = zero; *t2++ = zero;
00188 *t3++ = zero; *t4++ = zero;
00189 ++src;
00190 }
00191 break;
00192 }
00193
00194
00195
00196 switch(kernelSize)
00197 {
00198 case 3:
00199 for (int i = 0; i < w; i ++)
00200 {
00201 *t1++ = zero; *t2++ = zero;
00202 *t3++ = zero; *t4++ = zero;
00203 }
00204 break;
00205 case 5:
00206 for (int i = 0; i < w*2; i ++)
00207 {
00208 *t1++ = zero; *t2++ = zero;
00209 *t3++ = zero; *t4++ = zero;
00210 }
00211 break;
00212 }
00213
00214
00215 return tensorField;
00216
00217 }
00218
00219
00220
00221 Image<float> getTensorMag(const TensorField& tf)
00222 {
00223 GVX_TRACE(__PRETTY_FUNCTION__);
00224
00225 Image<float> mag(tf.t1.getDims(), NO_INIT);
00226
00227 Image<float>::iterator magPtr = mag.beginw();
00228
00229 Image<float>::const_iterator t1 = tf.t1.begin();
00230 Image<float>::const_iterator t4 = tf.t4.begin();
00231 Image<float>::const_iterator stop = tf.t1.end();
00232
00233 while (t1 != stop)
00234 {
00235 *magPtr = sqrt(*t1 + *t4);
00236
00237 magPtr++;
00238 ++t1;
00239 ++t4;
00240 }
00241
00242 return mag;
00243 }
00244
00245
00246
00247 TensorField getTensor(const EigenSpace& eigen)
00248 {
00249 GVX_TRACE(__PRETTY_FUNCTION__);
00250
00251 TensorField tf(eigen.l1.getDims(), NO_INIT);
00252
00253
00254 for(uint i=0; i<eigen.l1.size(); i++)
00255 {
00256 tf.t1.setVal(i, (eigen.l1.getVal(i)*eigen.e1[0].getVal(i)*eigen.e1[0].getVal(i)) +
00257 (eigen.l2.getVal(i)*eigen.e2[0].getVal(i)*eigen.e2[0].getVal(i)) );
00258
00259 tf.t2.setVal(i, (eigen.l1.getVal(i)*eigen.e1[0].getVal(i)*eigen.e1[1].getVal(i)) +
00260 (eigen.l2.getVal(i)*eigen.e2[0].getVal(i)*eigen.e2[1].getVal(i)) );
00261
00262 tf.t3.setVal(i, tf.t2.getVal(i));
00263
00264 tf.t4.setVal(i, (eigen.l1.getVal(i)*eigen.e1[1].getVal(i)*eigen.e1[1].getVal(i)) +
00265 (eigen.l2.getVal(i)*eigen.e2[1].getVal(i)*eigen.e2[1].getVal(i)) );
00266 }
00267
00268 return tf;
00269
00270 }
00271
00272
00273 EigenSpace getTensorEigen(const TensorField& tf)
00274 {
00275 GVX_TRACE(__PRETTY_FUNCTION__);
00276
00277 EigenSpace eigen;
00278
00279 eigen.e1 = ImageSet<float>(2, tf.t1.getDims(), NO_INIT);
00280 eigen.e2 = ImageSet<float>(2, tf.t1.getDims(), NO_INIT);
00281 eigen.l1 = Image<float>(tf.t1.getDims(), NO_INIT);
00282 eigen.l2 = Image<float>(tf.t1.getDims(), NO_INIT);
00283
00284 for(uint i=0; i<tf.t1.size(); i++)
00285 {
00286
00287 double trace = (tf.t1.getVal(i) + tf.t4.getVal(i))/2;
00288
00289 double a = tf.t1.getVal(i) - trace;
00290 double b = tf.t2.getVal(i);
00291
00292 double ab2 = sqrt((a*a) + (b*b));
00293
00294 eigen.l1.setVal(i, ab2 + trace);
00295 eigen.l2.setVal(i, -ab2 + trace);
00296
00297 double theta = atan2 (ab2-a, b);
00298
00299 eigen.e1[0].setVal(i, cos(theta));
00300 eigen.e1[1].setVal(i, sin(theta));
00301 eigen.e2[0].setVal(i, -sin(theta));
00302 eigen.e2[1].setVal(i, cos(theta));
00303 }
00304
00305 return eigen;
00306
00307 }
00308
00309
00310 void nonMaxSurp(TensorField& tf, float radius)
00311 {
00312 EigenSpace eigen = getTensorEigen(tf);
00313 Image<float> features = eigen.l1-eigen.l2;
00314
00315 for(int j=0; j<features.getHeight(); j++)
00316 for(int i=0; i<features.getWidth(); i++)
00317 {
00318 float val = features.getVal(i,j);
00319 if(val > 0)
00320 {
00321 float u = eigen.e1[1].getVal(i,j);
00322 float v = eigen.e1[0].getVal(i,j);
00323 float ang=atan(-u/v);
00324
00325
00326
00327 int dx = int(radius*cos(ang));
00328 int dy = int(radius*sin(ang));
00329
00330 if (features.coordsOk(i+dx, j-dy) &&
00331 features.coordsOk(i-dx, j+dy) )
00332 {
00333
00334 if (val < features.getVal(i+dx, j-dy) ||
00335 val <= features.getVal(i-dx, j+dy) )
00336 tf.setVal(i,j,0);
00337 }
00338 }
00339 }
00340 }
00341
00342
00343
00344 #include "inst/Image/TensorOps.I"
00345
00346
00347
00348
00349
00350
00351
00352
00353 #endif // !IMAGE_TENSOROPS_C_DEFINED