/vol/vipdata/irtk/packages/registration/include/irtkMultiThreadedImageFreeFormRegistration.h

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkMultiThreadedImageFreeFormRegistration.h 2 2008-12-23 12:40:14Z dr $
00005   Copyright : Imperial College, Department of Computing
00006               Visual Information Processing (VIP), 2008 onwards
00007   Date      : $Date: 2008-12-23 12:40:14 +0000 (Tue, 23 Dec 2008) $
00008   Version   : $Revision: 2 $
00009   Changes   : $Author: dr $
00010 
00011 =========================================================================*/
00012 
00013 #ifdef HAS_TBB
00014 
00015 extern concurrent_queue<irtkSimilarityMetric *> queue;
00016 
00017 class irtkMultiThreadedImageFreeFormRegistrationEvaluate
00018 {
00019 
00021   irtkImageFreeFormRegistration *_filter;
00022 
00024   irtkSimilarityMetric *_metric;
00025 
00026 public:
00027 
00028   irtkMultiThreadedImageFreeFormRegistrationEvaluate(irtkImageFreeFormRegistration *filter) {
00029     // Initialize filter
00030     _filter = filter;
00031 
00032     // Initialize metric
00033     _metric = filter->_metric;
00034     _metric->Reset();
00035   }
00036 
00037   irtkMultiThreadedImageFreeFormRegistrationEvaluate(irtkMultiThreadedImageFreeFormRegistrationEvaluate &r, split) {
00038 
00039     // Initialize filter
00040     _filter = r._filter;
00041 
00042     // Copy similarity metric
00043     if (queue.pop_if_present(_metric) == false) {
00044       _metric = irtkSimilarityMetric::New(_filter->_metric);
00045     }
00046 
00047     // Reset similarity metric
00048     _metric->Reset();
00049   }
00050 
00051   ~irtkMultiThreadedImageFreeFormRegistrationEvaluate() {
00052     if (_metric != _filter->_metric) queue.push(_metric);
00053   }
00054 
00055   void join(irtkMultiThreadedImageFreeFormRegistrationEvaluate &rhs) {
00056     // Combine metrics
00057     _metric->Combine(rhs._metric);
00058   }
00059 
00060   void operator()(const blocked_range<int> &r) {
00061     // Image coordinates
00062     int i, j, k, t;
00063     // World coordinates
00064     double x, y, z;
00065     // Pointer to reference data
00066     irtkGreyPixel *ptr2target;
00067     irtkGreyPixel *ptr2tmp;
00068     float *ptr;
00069 
00070     // Loop over all voxels in the target (reference) volume
00071     for (t = 0; t < _filter->_target->GetT(); t++) {
00072       for (k = r.begin(); k != r.end(); k++) {
00073         ptr2target = _filter->_target->GetPointerToVoxels(0, 0, k, t);
00074         ptr2tmp    = _tmpImage->GetPointerToVoxels(0, 0, k, t);
00075         ptr        = &(_filter->_mffdLookupTable[3*k*_filter->_target->GetX()*_filter->_target->GetY()]);
00076         for (j = 0; j < _filter->_target->GetY(); j++) {
00077           for (i = 0; i < _filter->_target->GetX(); i++) {
00078             // Check whether reference point is valid
00079             if (*ptr2target >= 0) {
00080               x = i;
00081               y = j;
00082               z = k;
00083               _filter->_target->ImageToWorld(x, y, z);
00084               _filter->_affd->LocalDisplacement(x, y, z);
00085               x += ptr[0];
00086               y += ptr[1];
00087               z += ptr[2];
00088               _filter->_source->WorldToImage(x, y, z);
00089               // Check whether transformed point is inside volume
00090               if ((x > _filter->_source_x1) && (x < _filter->_source_x2) &&
00091                   (y > _filter->_source_y1) && (y < _filter->_source_y2) &&
00092                   (z > _filter->_source_z1) && (z < _filter->_source_z2)) {
00093                 // Add sample to metric
00094                 *ptr2tmp =  round(_filter->_interpolator->EvaluateInside(x, y, z, t));
00095                 _metric->Add(*ptr2target, *ptr2tmp);
00096               } else {
00097                 *ptr2tmp = -1;
00098               }
00099             }
00100             // Increment pointers to next voxel
00101             ptr2tmp++;
00102             ptr2target++;
00103             ptr += 3;
00104           }
00105         }
00106       }
00107     }
00108   }
00109 };
00110 
00111 class irtkMultiThreadedImageFreeFormRegistrationEvaluateGradient
00112 {
00113 
00115   irtkImageFreeFormRegistration *_filter;
00116 
00117   float _step, *_dx;
00118 
00119 public:
00120 
00121   irtkMultiThreadedImageFreeFormRegistrationEvaluateGradient(irtkImageFreeFormRegistration *filter, float *dx, float step) {
00122     _dx     = dx;
00123     _step   = step;
00124     _filter = filter;
00125   }
00126 
00127   void operator()(const blocked_range<int> &r) const {
00128     int i;
00129 
00130     // Loop over all voxels in the target (reference) volume
00131     for (i = r.begin(); i != r.end(); i++) {
00132       if (_filter->_affd->irtkTransformation::GetStatus(i) == _Active) {
00133         _dx[i] = _filter->EvaluateDerivative(i, _step);
00134       } else {
00135         _dx[i] = 0;
00136       }
00137     }
00138   }
00139 };
00140 
00141 #endif