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
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
#include <volume_io/internal_volume_io.h>
00094
#include <bicpl/trans.h>
00095
#include <bicpl/numerical.h>
00096
00097
#ifndef lint
00098
static char rcsid[] =
"$Header: /software/source//libraries/bicpl/Transforms/compute_xfm.c,v 1.17 2000/02/06 15:30:50 stever Exp $";
00099
#endif
00100
00101
00102
00103
private void compute_procrustes_transform(
int npoints,
00104 Real **tag_list1,
00105 Real **tag_list2,
00106 Trans_type trans_type,
00107 General_transform *transform);
00108
private void compute_arb_param_transform(
int npoints,
00109 Real **tag_list1,
00110 Real **tag_list2,
00111 Trans_type trans_type,
00112 General_transform *transform);
00113
private void compute_12param_transform(
int npoints,
00114 Real **tag_list1,
00115 Real **tag_list2,
00116 Trans_type trans_type,
00117 General_transform *transform);
00118
private void compute_tps_transform(
int npoints,
00119 Real **tag_list1,
00120 Real **tag_list2,
00121 Trans_type trans_type,
00122 General_transform *transform);
00123
00124
private void concat_transformation_matrix(
00125 Transform *lt,
00126 Real center[],
00127 Real translations[],
00128 Real scales[],
00129 Real shears[],
00130 Transform *rotation );
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 public void compute_transform_from_tags(
00150
int npoints,
00151 Real **tag_list1,
00152 Real **tag_list2,
00153 Trans_type trans_type,
00154 General_transform *transform)
00155 {
00156
00157
00158
if( ((trans_type ==
TRANS_LSQ6) ||
00159 (trans_type ==
TRANS_LSQ7) ||
00160 (trans_type ==
TRANS_LSQ9) ||
00161 (trans_type ==
TRANS_LSQ10) ||
00162 (trans_type ==
TRANS_LSQ12)) &&
00163 (npoints <
MIN_POINTS_LINEAR) )
00164 {
00165 create_linear_transform(transform, NULL);
00166
return;
00167 }
00168
00169
00170
00171
if( (trans_type ==
TRANS_TPS) && (npoints <
MIN_POINTS_TPS) )
00172 {
00173 create_linear_transform(transform, NULL);
00174
return;
00175 }
00176
00177
switch (trans_type)
00178 {
00179
case TRANS_LSQ6:
00180
case TRANS_LSQ7:
00181
compute_procrustes_transform( npoints, tag_list1, tag_list2,
00182 trans_type, transform );
00183
break;
00184
00185
case TRANS_LSQ9:
00186
case TRANS_LSQ10:
00187
compute_arb_param_transform( npoints, tag_list1, tag_list2,
00188 trans_type, transform );
00189
break;
00190
00191
case TRANS_LSQ12:
00192
compute_12param_transform( npoints, tag_list1, tag_list2,
00193 trans_type, transform );
00194
break;
00195
00196
case TRANS_TPS:
00197
compute_tps_transform( npoints, tag_list1, tag_list2,
00198 trans_type, transform );
00199
break;
00200
00201
default:
00202 print_error(
00203
"Invalid transform type in compute_transform_from tags\n" );
00204
00205 exit(EXIT_FAILURE);
00206 }
00207 }
00208
00209
00210
00211
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227 private void compute_procrustes_transform(
00228
int npoints,
00229 Real **tag_list1,
00230 Real **tag_list2,
00231 Trans_type trans_type,
00232 General_transform *transform)
00233 {
00234 Transform rotation;
00235
int i;
00236 Real translation[N_DIMENSIONS];
00237 Real centre_of_rotation[N_DIMENSIONS];
00238 Real scale, scales[N_DIMENSIONS];
00239 Real shears[N_DIMENSIONS];
00240 Transform linear_transform;
00241
00242
00243
00244
procrustes( npoints, N_DIMENSIONS, tag_list1, tag_list2, translation,
00245 centre_of_rotation, &rotation, &scale );
00246
00247
00248
00249
if( trans_type ==
TRANS_LSQ6 )
00250 scale = 1.0;
00251
00252 for_less( i, 0, N_DIMENSIONS )
00253 {
00254 scales[i] = scale;
00255 shears[i] = 0.0;
00256 }
00257
00258
00259
00260
concat_transformation_matrix( &linear_transform, centre_of_rotation,
00261 translation, scales, shears, &rotation );
00262
00263 create_linear_transform( transform, &linear_transform );
00264 }
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284 private void compute_arb_param_transform(
00285
int npoints,
00286 Real **tag_list1,
00287 Real **tag_list2,
00288 Trans_type trans_type,
00289 General_transform *transform )
00290 {
00291 Transform rotation;
00292 Real translation[N_DIMENSIONS];
00293 Real centre_of_rotation[N_DIMENSIONS], scale;
00294 Real scales[N_DIMENSIONS];
00295 Real shears[N_DIMENSIONS], angles[N_DIMENSIONS];
00296
int i;
00297 Transform linear_transform;
00298
00299
if( trans_type !=
TRANS_LSQ9 && trans_type !=
TRANS_LSQ10 )
00300 {
00301 print_error(
"Error in compute_arb_param_transform().\n" );
00302 print_error(
"Trans_type (=%d) requested is not LSQ9 or LSQ10.\n",
00303 trans_type );
00304 exit(EXIT_FAILURE);
00305 }
00306
00307
00308
00309
procrustes( npoints, N_DIMENSIONS, tag_list1, tag_list2, translation,
00310 centre_of_rotation, &rotation, &scale );
00311
00312
if( !
rotmat_to_ang( &rotation, angles ) )
00313 {
00314 print_error(
"Error in compute_arb_param_transform().\n");
00315 print_error(
"Cannot extract angles from rotation matrix.\n");
00316 exit(EXIT_FAILURE);
00317 }
00318
00319 for_less( i, 0, N_DIMENSIONS )
00320 {
00321 shears[i] = 0.0;
00322 scales[i] = scale;
00323 }
00324
00325
if( !
optimize_simplex( tag_list1, tag_list2,
00326 npoints, trans_type,
00327 centre_of_rotation,
00328 translation,
00329 scales,
00330 shears,
00331 angles) )
00332 {
00333 print_error(
"Error in compute_arb_param_transform(),\n");
00334 print_error(
"in call to optimize_simplex().\n");
00335 exit(EXIT_FAILURE);
00336 }
00337
00338
build_transformation_matrix( &linear_transform,
00339 centre_of_rotation,
00340 translation,
00341 scales,
00342 shears,
00343 angles );
00344
00345
00346 create_linear_transform( transform, &linear_transform );
00347 }
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361
00362 private void make_rots(
00363 Transform *xmat,
00364 Real rot_x,
00365 Real rot_y,
00366 Real rot_z )
00367 {
00368 Transform tx, ty, tz;
00369
00370
make_rotation_transform( -rot_x, X, &tx ) ;
00371
make_rotation_transform( -rot_y, Y, &ty ) ;
00372
make_rotation_transform( -rot_z, Z, &tz ) ;
00373
00374 concat_transforms( xmat, &tx, &ty );
00375 concat_transforms( xmat, xmat, &tz );
00376 }
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393 private void concat_transformation_matrix(
00394 Transform *lt,
00395 Real center[],
00396 Real translations[],
00397 Real scales[],
00398 Real shears[],
00399 Transform *rotation )
00400 {
00401 Transform T, SH, S, C;
00402
00403
00404
00405
00406
00407
make_translation_transform( translations[X] - center[X],
00408 translations[Y] - center[Y],
00409 translations[Z] - center[Z], &T );
00410
00411
00412
00413
make_rots( &SH, shears[0], shears[1], shears[2] );
00414
00415
00416
00417
make_scale_transform( scales[X], scales[Y], scales[Z], &S );
00418
00419
00420
00421
make_translation_transform( center[X], center[Y], center[Z], &C );
00422
00423 concat_transforms( lt, &T, rotation );
00424 concat_transforms( lt, lt, &S );
00425 concat_transforms( lt, lt, &SH );
00426 concat_transforms( lt, lt, &C );
00427 }
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444 public void build_transformation_matrix(
00445 Transform *lt,
00446 Real center[],
00447 Real translations[],
00448 Real scales[],
00449 Real shears[],
00450 Real rotations[] )
00451 {
00452 Transform R;
00453
00454
00455
00456
make_rots( &R, rotations[0], rotations[1], rotations[2] );
00457
00458
concat_transformation_matrix( lt, center, translations, scales,
00459 shears, &R );
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483 private void compute_12param_transform(
00484
int npoints,
00485 Real **tag_list1,
00486 Real **tag_list2,
00487 Trans_type trans_type,
00488 General_transform *transform)
00489 {
00490 Real *x, solution[N_DIMENSIONS + 1];
00491
int d, dim;
00492
int point;
00493 Transform linear_transform;
00494
00495
00496
00497
if( trans_type !=
TRANS_LSQ12 )
00498 {
00499 print_error(
"Internal error in compute_12param_transform!\n");
00500 exit(EXIT_FAILURE);
00501 }
00502
00503
00504
00505 make_identity_transform( &linear_transform );
00506
00507 ALLOC( x, npoints );
00508
00509
00510
00511 for_less( dim, 0, N_DIMENSIONS )
00512 {
00513
00514
00515 for_less( point, 0, npoints )
00516 x[point] = tag_list1[point][dim];
00517
00518
00519
00520
least_squares( npoints, N_DIMENSIONS, tag_list2, x, solution );
00521
00522
00523
00524 Transform_elem( linear_transform, dim, N_DIMENSIONS ) = solution[0];
00525 for_less( d, 0, N_DIMENSIONS )
00526 Transform_elem( linear_transform, dim, d ) = solution[1+d];
00527 }
00528
00529
00530
00531 create_linear_transform( transform, &linear_transform );
00532
00533
00534
00535 FREE( x );
00536 }
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547
00548
00549
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559 private void compute_tps_transform(
00560
int npoints,
00561 Real **tag_list1,
00562 Real **tag_list2,
00563 Trans_type trans_type,
00564 General_transform *transform)
00565 {
00566 Real **displacements;
00567 General_transform inv_transform;
00568
00569
00570
00571
if (trans_type !=
TRANS_TPS)
00572 {
00573 print_error(
"Wrong trans type in compute_tps_transform\n");
00574 exit(EXIT_FAILURE);
00575 }
00576
00577
00578
00579 ALLOC2D( displacements, npoints+1+N_DIMENSIONS, N_DIMENSIONS );
00580
00581
get_nonlinear_warp( tag_list1, tag_list2, displacements, npoints,
00582 N_DIMENSIONS, N_DIMENSIONS );
00583
00584
00585
00586 create_thin_plate_transform_real( &inv_transform, N_DIMENSIONS, npoints,
00587 tag_list1, displacements );
00588
00589
00590
00591 create_inverse_general_transform( &inv_transform, transform );
00592
00593
00594
00595 delete_general_transform(&inv_transform);
00596
00597
00598
00599 FREE2D( displacements );
00600 }