00001
00008
00009
00010
00011
00012
00013
00014
00120 #include "quickshift.h"
00121 #include "mathop.h"
00122
00123 #include <string.h>
00124 #include <math.h>
00125 #include <stdio.h>
00126
00127
00149 VL_INLINE
00150 vl_qs_type
00151 vl_quickshift_distance(vl_qs_type const * I,
00152 int N1, int N2, int K,
00153 int i1, int i2,
00154 int j1, int j2)
00155 {
00156 vl_qs_type dist = 0 ;
00157 int d1 = j1 - i1 ;
00158 int d2 = j2 - i2 ;
00159 int k ;
00160 dist += d1*d1 + d2*d2 ;
00161
00162
00163 for (k = 0 ; k < K ; ++k) {
00164 vl_qs_type d =
00165 I [i1 + N1 * i2 + (N1*N2) * k] -
00166 I [j1 + N1 * j2 + (N1*N2) * k] ;
00167 dist += d*d ;
00168 }
00169 return dist ;
00170 }
00171
00193 VL_INLINE
00194 vl_qs_type
00195 vl_quickshift_inner(vl_qs_type const * I,
00196 int N1, int N2, int K,
00197 int i1, int i2,
00198 int j1, int j2)
00199 {
00200 vl_qs_type ker = 0 ;
00201 int k ;
00202 ker += i1*j1 + i2*j2 ;
00203 for (k = 0 ; k < K ; ++k) {
00204 ker +=
00205 I [i1 + N1 * i2 + (N1*N2) * k] *
00206 I [j1 + N1 * j2 + (N1*N2) * k] ;
00207 }
00208 return ker ;
00209 }
00210
00221 VL_EXPORT
00222 VlQS *
00223 vl_quickshift_new(vl_qs_type const * image, int height, int width,
00224 int channels)
00225 {
00226 VlQS * q = vl_malloc(sizeof(VlQS));
00227
00228 q->image = (vl_qs_type *)image;
00229 q->height = height;
00230 q->width = width;
00231 q->channels = channels;
00232
00233 q->medoid = VL_FALSE;
00234 q->tau = VL_MAX(height,width)/50;
00235 q->sigma = VL_MAX(2, q->tau/3);
00236
00237 q->dists = vl_malloc(sizeof(vl_qs_type)*height*width);
00238 q->parents = vl_malloc(sizeof(int)*height*width);
00239 q->density = vl_malloc(sizeof(vl_qs_type)*height*width);
00240
00241 return q;
00242 }
00243
00249 VL_EXPORT
00250 void vl_quickshift_process(VlQS * q)
00251 {
00252 vl_qs_type const *I = q->image;
00253 int *parents = q->parents;
00254 vl_qs_type *E = q->density;
00255 vl_qs_type *dists = q->dists;
00256 vl_qs_type *M = 0, *n = 0 ;
00257 vl_qs_type sigma = q->sigma ;
00258 vl_qs_type tau = q->tau;
00259 vl_qs_type tau2 = tau*tau;
00260
00261 int K = q->channels, d;
00262 int N1 = q->height, N2 = q->width;
00263 int i1,i2, j1,j2, R, tR;
00264
00265 d = 2 + K ;
00266
00267 if (q->medoid) {
00268 M = (vl_qs_type *) vl_calloc(N1*N2*d, sizeof(vl_qs_type)) ;
00269 n = (vl_qs_type *) vl_calloc(N1*N2, sizeof(vl_qs_type)) ;
00270 }
00271
00272 R = (int) ceil (3 * sigma) ;
00273 tR = (int) ceil (tau) ;
00274
00275
00276
00277
00278
00279
00280
00281
00282 if (n) {
00283 for (i2 = 0 ; i2 < N2 ; ++ i2) {
00284 for (i1 = 0 ; i1 < N1 ; ++ i1) {
00285 n [i1 + N1 * i2] = vl_quickshift_inner(I,N1,N2,K,
00286 i1,i2,
00287 i1,i2) ;
00288 }
00289 }
00290 }
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307 for (i2 = 0 ; i2 < N2 ; ++ i2) {
00308 for (i1 = 0 ; i1 < N1 ; ++ i1) {
00309
00310 int j1min = VL_MAX(i1 - R, 0 ) ;
00311 int j1max = VL_MIN(i1 + R, N1-1) ;
00312 int j2min = VL_MAX(i2 - R, 0 ) ;
00313 int j2max = VL_MIN(i2 + R, N2-1) ;
00314
00315
00316
00317 for (j2 = j2min ; j2 <= j2max ; ++ j2) {
00318 for (j1 = j1min ; j1 <= j1max ; ++ j1) {
00319 vl_qs_type Dij = vl_quickshift_distance(I,N1,N2,K, i1,i2, j1,j2) ;
00320
00321 vl_qs_type Fij = - exp(- Dij / (2*sigma*sigma)) ;
00322
00323
00324 E [i1 + N1 * i2] -= Fij ;
00325
00326 if (M) {
00327
00328 int k ;
00329 M [i1 + N1*i2 + (N1*N2) * 0] += j1 * Fij ;
00330 M [i1 + N1*i2 + (N1*N2) * 1] += j2 * Fij ;
00331 for (k = 0 ; k < K ; ++k) {
00332 M [i1 + N1*i2 + (N1*N2) * (k+2)] +=
00333 I [j1 + N1*j2 + (N1*N2) * k] * Fij ;
00334 }
00335 }
00336
00337 }
00338 }
00339
00340 }
00341 }
00342
00343
00344
00345
00346
00347 if (q->medoid) {
00348
00349
00350
00351
00352
00353
00354
00355 for (i2 = 0 ; i2 < N2 ; ++i2) {
00356 for (i1 = 0 ; i1 < N1 ; ++i1) {
00357
00358 vl_qs_type sc_best = 0 ;
00359
00360 vl_qs_type j1_best = i1 ;
00361 vl_qs_type j2_best = i2 ;
00362
00363 int j1min = VL_MAX(i1 - R, 0 ) ;
00364 int j1max = VL_MIN(i1 + R, N1-1) ;
00365 int j2min = VL_MAX(i2 - R, 0 ) ;
00366 int j2max = VL_MIN(i2 + R, N2-1) ;
00367
00368 for (j2 = j2min ; j2 <= j2max ; ++ j2) {
00369 for (j1 = j1min ; j1 <= j1max ; ++ j1) {
00370
00371 vl_qs_type Qij = - n [j1 + j2 * N1] * E [i1 + i2 * N1] ;
00372 int k ;
00373
00374 Qij -= 2 * j1 * M [i1 + i2 * N1 + (N1*N2) * 0] ;
00375 Qij -= 2 * j2 * M [i1 + i2 * N1 + (N1*N2) * 1] ;
00376 for (k = 0 ; k < K ; ++k) {
00377 Qij -= 2 *
00378 I [j1 + j2 * N1 + (N1*N2) * k] *
00379 M [i1 + i2 * N1 + (N1*N2) * (k + 2)] ;
00380 }
00381
00382 if (Qij > sc_best) {
00383 sc_best = Qij ;
00384 j1_best = j1 ;
00385 j2_best = j2 ;
00386 }
00387 }
00388 }
00389
00390
00391
00392
00393
00394 parents [i1 + N1 * i2] = j1_best + N1 * j2_best + 1 ;
00395 dists[i1 + N1 * i2] = sc_best ;
00396 }
00397 }
00398
00399 } else {
00400
00401
00402
00403
00404
00405 for (i2 = 0 ; i2 < N2 ; ++i2) {
00406 for (i1 = 0 ; i1 < N1 ; ++i1) {
00407
00408 vl_qs_type E0 = E [i1 + N1 * i2] ;
00409 vl_qs_type d_best = VL_QS_INF ;
00410 vl_qs_type j1_best = i1 ;
00411 vl_qs_type j2_best = i2 ;
00412
00413 int j1min = VL_MAX(i1 - tR, 0 ) ;
00414 int j1max = VL_MIN(i1 + tR, N1-1) ;
00415 int j2min = VL_MAX(i2 - tR, 0 ) ;
00416 int j2max = VL_MIN(i2 + tR, N2-1) ;
00417
00418 for (j2 = j2min ; j2 <= j2max ; ++ j2) {
00419 for (j1 = j1min ; j1 <= j1max ; ++ j1) {
00420 if (E [j1 + N1 * j2] > E0) {
00421 vl_qs_type Dij = vl_quickshift_distance(I,N1,N2,K, i1,i2, j1,j2) ;
00422 if (Dij <= tau2 && Dij < d_best) {
00423 d_best = Dij ;
00424 j1_best = j1 ;
00425 j2_best = j2 ;
00426 }
00427 }
00428 }
00429 }
00430
00431
00432
00433
00434 parents [i1 + N1 * i2] = j1_best + N1 * j2_best + 1 ;
00435 dists[i1 + N1 * i2] = sqrt(d_best) ;
00436 }
00437 }
00438 }
00439
00440 if (M) vl_free(M) ;
00441 if (n) vl_free(n) ;
00442 }
00443
00449 void vl_quickshift_delete(VlQS * q)
00450 {
00451 if (q) {
00452 if (q->parents) vl_free(q->parents);
00453 if (q->dists) vl_free(q->dists);
00454 if (q->density) vl_free(q->density);
00455
00456 vl_free(q);
00457 }
00458 }