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

00001 /*=========================================================================
00002 
00003   Library   : Image Registration Toolkit (IRTK)
00004   Module    : $Id: irtkMultiThreadedImageRigidRegistration.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 irtkMultiThreadedImageRigidRegistrationEvaluate
00018 {
00019 
00021   irtkImageRigidRegistration *_filter;
00022 
00024   irtkSimilarityMetric *_metric;
00025 
00026 public:
00027 
00028   irtkMultiThreadedImageRigidRegistrationEvaluate(irtkImageRigidRegistration *filter) {
00029     // Initialize filter
00030     _filter = filter;
00031 
00032     // Initialize metric
00033     _metric = filter->_metric;
00034     _metric->Reset();
00035   }
00036 
00037   irtkMultiThreadedImageRigidRegistrationEvaluate(irtkMultiThreadedImageRigidRegistrationEvaluate &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   ~irtkMultiThreadedImageRigidRegistrationEvaluate() {
00052     if (_metric != _filter->_metric) queue.push(_metric);
00053   }
00054 
00055   void join(irtkMultiThreadedImageRigidRegistrationEvaluate &rhs) {
00056     // Combine metrics
00057     _metric->Combine(rhs._metric);
00058   }
00059 
00060   void operator()(const blocked_range<int> &r) {
00061     int i, j, k, t;
00062 
00063     // Create iterator
00064     irtkHomogeneousTransformationIterator iterator((irtkHomogeneousTransformation *)_filter->_transformation);
00065 
00066     // Loop over all voxels in the target (reference) volume
00067 
00068     for (t = 0; t < _filter->_target->GetT(); t++) {
00069       for (k = r.begin(); k != r.end(); k++) {
00070 
00071         // Initialize iterator
00072         iterator.Initialize(_filter->_target, _filter->_source, 0, 0, k);
00073 
00074         // Pointer to voxels in target image
00075         irtkGreyPixel *ptr2target = _filter->_target->GetPointerToVoxels(0, 0, k, t);
00076 
00077         for (j = 0; j < _filter->_target->GetY(); j++) {
00078           for (i = 0; i < _filter->_target->GetX(); i++) {
00079             // Check whether reference point is valid
00080             if (*ptr2target >= 0) {
00081               // Check whether transformed point is inside source volume
00082               if ((iterator._x > _filter->_source_x1) && (iterator._x < _filter->_source_x2) &&
00083                   (iterator._y > _filter->_source_y1) && (iterator._y < _filter->_source_y2) &&
00084                   (iterator._z > _filter->_source_z1) && (iterator._z < _filter->_source_z2)) {
00085                 // Add sample to metric
00086                 _metric->Add(*ptr2target, round(_filter->_interpolator->EvaluateInside(iterator._x, iterator._y, iterator._z, t)));
00087               }
00088               iterator.NextX();
00089             } else {
00090               // Advance iterator by offset
00091               iterator.NextX(*ptr2target * -1);
00092               i          -= (*ptr2target) + 1;
00093               ptr2target -= (*ptr2target) + 1;
00094             }
00095             ptr2target++;
00096           }
00097           iterator.NextY();
00098         }
00099         iterator.NextZ();
00100       }
00101     }
00102   }
00103 };
00104 
00105 #endif