NIREP
|
00001 #include "NIREPEvaluator.h" 00002 #include "NIREPInverseConsistencyError.h" 00003 #include "NIREPTransitivityError.h" 00004 #include "NIREPIntensityVariance.h" 00005 00006 #include "NIREPDefinitions.h" 00007 00008 /* +----------------+ 00009 | Public Methods | 00010 +----------------+ */ 00011 00012 /* 00013 function: NIREPEvaluator 00014 purpose: constructor 00015 overloads: NIREPEvaluator(NIREPDataManager *dm) 00016 */ 00017 NIREPEvaluator::NIREPEvaluator(void) 00018 { 00019 this->dataManager = NULL; 00020 //taskList = NULL; 00021 this->Init(); 00022 } 00023 00024 00025 /* 00026 function: NIREPEvaluator 00027 purpose: Class constructor that initializes the data manager 00028 overloads: NIREPEvaluator(void) 00029 */ 00030 NIREPEvaluator::NIREPEvaluator(NIREPDataManager *dm) 00031 { 00032 this->dataManager = dm; 00033 this->Init(); 00034 } 00035 00036 00037 /* 00038 function: ~NIREPEvaluator 00039 purpose: class destructor, destroying references to pointers 00040 */ 00041 NIREPEvaluator::~NIREPEvaluator(void){ 00042 //delete dataManager; 00043 //if(taskList) 00044 //{ 00045 // delete taskList; 00046 //} 00047 //taskList = NULL; 00048 } 00049 00050 00051 /* +-----------------+ 00052 | Private Methods | 00053 +-----------------+ */ 00054 00055 /* 00056 function: Init 00057 purpose: Initializes fList and all other parameters we have control over. 00058 output: initialized fList 00059 */ 00060 void NIREPEvaluator::Init() 00061 { 00062 } 00063 00064 00065 /* 00066 function: Evaluate 00067 purpose: evaluates the provided expression 00068 input: command std::string containing the abbreviation or expression to 00069 be retrieved (ex: _A3 or diff(_A1, _A2)) 00070 output: gec::SpatialData* containing the computed expression 00071 */ 00072 gec::SpatialData* NIREPEvaluator::Evaluate(const std::string& command, DisplayDescription * displayDescription) 00073 { 00074 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00075 std::string cmd = taskList->GetEvaluatorCommand(command) ; // unwrap to see if it's empty 00076 00077 gec::SpatialData* res = this->dataManager->GetLoadedSpatialDataListEntry(cmd, displayDescription); 00078 00079 // if it's empty, it's not in the data manager so we must execute the expression 00080 if(res == NULL){ 00081 std::string fcn = taskList->GetTaskFunction(command); 00082 std::vector<std::string> params = taskList->GetTaskParameters(command); 00083 00084 // Convert fcn to lower case for comparison 00085 std::transform(fcn.begin(), fcn.end(), fcn.begin(), ::tolower); 00086 00087 bool CMDprocessed = false; 00088 00089 if (fcn.compare(EvalCmd["TransformGrid"]) == 0){ 00090 if(params.size() == 1) { // ensure only four parameters 00091 //res = this->IntensityVariance(params,"ImageVariance"); 00092 res = this->TransformGrid(params[0], displayDescription); 00093 } else { 00094 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00095 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00096 wxLogError(temp); 00097 res = NULL; 00098 } 00099 CMDprocessed = true; // command was processed 00100 } 00101 00102 if (fcn.compare(EvalCmd["VectorField"]) == 0){ 00103 if(params.size() == 1) { // ensure only four parameters 00104 //res = this->IntensityVariance(params,"ImageVariance"); 00105 res = this->VectorField(params[0], displayDescription); 00106 } else { 00107 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00108 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00109 wxLogError(temp); 00110 res = NULL; 00111 } 00112 CMDprocessed = true; // command was processed 00113 } 00114 00115 if (fcn.compare(EvalCmd["IntensityVarianceImage"]) == 0){ 00116 if(params.size() == 2) { // ensure only four parameters 00117 //res = this->IntensityVariance(params,"ImageVariance"); 00118 res = this->IntensityVariance(params,fcn, displayDescription); 00119 } else { 00120 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00121 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00122 wxLogError(temp); 00123 res = NULL; 00124 } 00125 CMDprocessed = true; // command was processed 00126 } 00127 00128 if (fcn.compare(EvalCmd["IntensityVarianceTransform"]) == 0){ 00129 if(params.size() == 4){ // ensure only four parameters 00130 //res = this->IntensityVariance(params,"RegisteredImageVariance"); 00131 res = this->IntensityVariance(params,fcn, displayDescription); 00132 } else { 00133 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00134 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00135 wxLogError(temp); 00136 res = NULL; 00137 } 00138 CMDprocessed = true; // command was processed 00139 } 00140 00141 if (fcn.compare(EvalCmd["TransitivityErrorImage"]) == 0){ 00142 if(params.size() == 4){ // ensure only three parameters -- transAB, transBC, transCA, method 00143 res = this->TransitivityError(params[0],params[1],params[2],params[3], displayDescription); 00144 } else { 00145 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00146 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00147 wxLogError(temp); 00148 res = NULL; 00149 } 00150 CMDprocessed = true; // command was processed 00151 } 00152 00153 if (fcn.compare(EvalCmd["InverseConsistencyErrorImage"]) == 0){ 00154 if(params.size() == 3){ // ensure only one parameter -- fwdTrans, revTrans, method 00155 res = this->InverseConsistencyError(params[0],params[1],params[2], displayDescription); 00156 } else { 00157 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00158 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00159 wxLogError(temp); 00160 res = NULL; 00161 } 00162 CMDprocessed = true; // command was processed 00163 } 00164 00165 if (fcn.compare(EvalCmd["InvertTransformation"]) == 0){ 00166 if(params.size() == 1){ // ensure only one parameter -- transformation 00167 res = this->InvertTransformation(params[0], displayDescription); 00168 } else { 00169 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00170 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00171 wxLogError(temp); 00172 res = NULL; 00173 } 00174 CMDprocessed = true; // command was processed 00175 } 00176 00177 if (fcn.compare(EvalCmd["TransformImage"]) == 0){ 00178 if(params.size() == 2){ // ensure only two parameters -- spatial data, transformation 00179 res = this->Transform(params[0],params[1], displayDescription); 00180 } else { 00181 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00182 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00183 wxLogError(temp); 00184 res = NULL; 00185 } 00186 CMDprocessed = true; // command was processed 00187 } 00188 00189 if (fcn.compare(EvalCmd["Jacobian"]) == 0){ 00190 if(params.size() == 1){ // ensure only one parameter -- transformation 00191 res = this->Jacobian(params[0], displayDescription); 00192 } else { 00193 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00194 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00195 wxLogError(temp); 00196 res = NULL; 00197 } 00198 CMDprocessed = true; // command was processed 00199 } 00200 00201 if (fcn.compare(EvalCmd["Disp2"]) == 0){ 00202 if(params.size() == 1){ // ensure only one parameter -- transformation 00203 res = this->Disp(params[0],2, displayDescription); 00204 } else { 00205 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00206 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00207 wxLogError(temp); 00208 res = NULL; 00209 } 00210 CMDprocessed = true; // command was processed 00211 } 00212 00213 if (fcn.compare(EvalCmd["Disp1"]) == 0){ 00214 if(params.size() == 1){ // ensure only one parameter -- transformation 00215 res = this->Disp(params[0],1, displayDescription); 00216 } else { 00217 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00218 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00219 wxLogError(temp); 00220 res = NULL; 00221 } 00222 CMDprocessed = true; // command was processed 00223 } 00224 00225 if (fcn.compare(EvalCmd["Disp0"]) == 0){ 00226 if(params.size() == 1){ // ensure only one parameter -- transformation 00227 res = this->Disp(params[0],0, displayDescription); 00228 } else { 00229 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00230 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00231 wxLogError(temp); 00232 res = NULL; 00233 } 00234 CMDprocessed = true; // command was processed 00235 } 00236 00237 if (fcn.compare(EvalCmd["Diff"]) == 0){ 00238 if (params.size() == 2){ // ensure only two parameters -- image1, image2 00239 res = this->Diff(params[0],params[1], displayDescription); 00240 } else { 00241 wxString temp = wxT( "ERROR - Wrong number of parameters for command: " ); 00242 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00243 wxLogError(temp); 00244 res = NULL; 00245 } 00246 CMDprocessed = true; // command was processed 00247 } 00248 00249 if (fcn.compare(EvalCmd["Transformation"]) == 0){ 00250 if(params.size() == 3){ // ensure only three parameters -- source, target, algorithm 00251 res = this->ReadTransformation(params[0],params[1],params[2],displayDescription); 00252 } else { 00253 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00254 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00255 wxLogError(temp); 00256 res = NULL; 00257 } 00258 CMDprocessed = true; // command was processed 00259 } 00260 00261 if (fcn.compare(EvalCmd["SpatialData"]) == 0){ 00262 if (params.size() == 2){ // ensure only two parameters -- datasetID, dataID 00263 res = this->ReadSpatialData(params[0],params[1],displayDescription); 00264 } else { 00265 wxString temp = wxT("ERROR - Wrong number of parameters for command: "); 00266 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00267 wxLogError(temp); 00268 res = NULL; 00269 } 00270 CMDprocessed = true; // command was processed 00271 } 00272 if (!CMDprocessed){ 00273 wxString temp = wxT("ERROR - Command not known: "); 00274 temp.Append(wxString::Format (wxT("%s"), cmd.c_str())); 00275 wxLogError(temp); 00276 res = NULL; 00277 } 00278 } 00279 return res; 00280 } 00281 00282 00283 /* +--------------------+ 00284 | Evaluator Commands | 00285 +--------------------+ */ 00286 00287 /* 00288 function: ReadSpatialData 00289 purpose : reads spatial data from database 00290 input: datasetID std::string containing the ID of the dataset (ex: "1") 00291 dataID std::string containing the ID of the data (ex: "MRI") 00292 output : gec::SpatialData* pointer of data 00293 */ 00294 gec::SpatialData* NIREPEvaluator::ReadSpatialData(const std::string& datasetID, 00295 const std::string& dataID, 00296 DisplayDescription * displayDescription) 00297 { 00298 gec::SpatialData* res = NULL; 00299 00300 // before we can ask if it's there, we must form the database manager command 00301 // const std::string cmd = evaluatorCommands.fListTwo.find(0)->second + "(" + datasetID + "," + dataID + ")"; // GEC removed 00302 const std::string cmd = EvalCmd["SpatialData"] + "(" + datasetID + "," + dataID + ")"; // GEC added 00303 00304 // first ask the database if it's got it in memory 00305 // note: request should increment the reference counter of cmd 00306 // gec::SpatialData* res = NIREPDataManager::request(cmd); 00307 res = this->dataManager->GetLoadedSpatialDataListEntry(cmd, displayDescription); 00308 00309 // if it does not, request the DM load the image and then send it on its way 00310 if(res == NULL) 00311 if(this->dataManager->LoadSpatialData(datasetID, dataID, displayDescription)) 00312 res = this->dataManager->GetLoadedSpatialDataListEntry(cmd, displayDescription); 00313 00314 return res; 00315 } 00316 00317 00318 /* 00319 function: ReadTransformation 00320 purpose: reads transformation from database 00321 input: source std::string containing the name of the source (ex: "1") 00322 target std::string containing the name of the target (ex: "2") 00323 transformation std::string containing the name of the transformation 00324 (ex: "SICLE_param1") 00325 output: gec::SpatialData* pointer of data 00326 */ 00327 gec::SpatialData* NIREPEvaluator::ReadTransformation(const std::string& source, 00328 const std::string& target, 00329 const std::string& transformation, 00330 DisplayDescription * displayDescription) 00331 { 00332 gec::SpatialData* res = NULL; 00333 00334 // before we can ask if it's there, we must form the database manager command 00335 //const std::string cmd = 00336 // evaluatorCommands.fListTwo.find(1)->second+"(" + source + "," + target + "," + transformation + ")"; // GEC removed 00337 std::string cmd = EvalCmd["Transformation"]+"(" + source + "," + target + "," + transformation + ")"; // GEC added 00338 00339 // first ask the database if it's got it in memory 00340 // note: request should increment the reference counter of cmd 00341 // gec::SpatialData* res = NIREPDataManager::request(cmd); 00342 res = this->dataManager->GetLoadedSpatialDataListEntry(cmd, displayDescription); 00343 00344 // if it does not, request the DM load the image and then send it on its way 00345 if(res == NULL) 00346 if(this->dataManager->LoadTransformation(source, target, transformation, displayDescription)) 00347 res = this->dataManager->GetLoadedSpatialDataListEntry(cmd, displayDescription); 00348 00349 return res; 00350 } 00351 00352 00353 /* 00354 function: Diff 00355 purpose: computes the absolute difference image1-image2 00356 input: params std::vector<std::string> of the parameters 00357 output: gec::SpatialData* pointer of image data 00358 */ 00359 gec::SpatialData* NIREPEvaluator::Diff(const std::string& img1, const std::string& img2, DisplayDescription * displayDescription) 00360 { 00361 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00362 gec::SpatialData* res = NULL; 00363 00364 const gec::Image* im1 = dynamic_cast<const gec::Image *>(this->Evaluate(img1, displayDescription)); 00365 if(im1==NULL) { 00366 return NULL; 00367 } 00368 const gec::Image* im2 = dynamic_cast<const gec::Image *>(this->Evaluate(img2, displayDescription)); 00369 if(im2==NULL) { 00370 return NULL; 00371 } 00372 res = new gec::Image(*im1); 00373 dynamic_cast<gec::Image *>(res)->AbsDiff(im2); 00374 00375 //std::string cmd = evaluatorCommands.fListTwo.find(2)->second+"(" + taskList->GetEvaluatorCommand(img1) + "," + taskList->GetEvaluatorCommand(img2) + ")"; // GEC removed 00376 std::string cmd = EvalCmd["Diff"]+"(" + taskList->GetEvaluatorCommand(img1) + "," + taskList->GetEvaluatorCommand(img2) + ")"; // GEC added 00377 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00378 00379 return res; 00380 } 00381 00382 00383 /* 00384 function: Disp 00385 purpose: Extracts ith-displacement field from a transformation 00386 input: transformID Evaluator task ID (e.g. "_A1") 00387 index i-th index of transformation 00388 output: gec::SpatialData* pointer of data 00389 */ 00390 gec::SpatialData* NIREPEvaluator::Disp(const std::string& transformID, const unsigned int& index, DisplayDescription * displayDescription) 00391 { 00392 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00393 gec::SpatialData* res = NULL; 00394 00395 // obtain the transformation from the database 00396 const gec::Transformation* trans = dynamic_cast<const gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00397 if(trans == NULL) { 00398 return NULL; 00399 } 00400 res = trans->GetDispImage(index); 00401 00402 // NOTE: xDisp, yDisp and zDisp MUST be contiguous in the evaluatorTaskList for the next line to work! 00403 //std::string cmd = evaluatorCommands.fListTwo.find(3+index)->second + "(" + taskList->GetEvaluatorCommand(transformID) + ")"; // GEC removed 00404 std::string cmd; 00405 if (index == 0){ 00406 cmd = EvalCmd["Disp0"] + "(" + taskList->GetEvaluatorCommand(transformID) + ")"; // GEC added 00407 } else if (index == 1){ 00408 cmd = EvalCmd["Disp1"] + "(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00409 } else if (index == 2){ 00410 cmd = EvalCmd["Disp2"] + "(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00411 } 00412 00413 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00414 00415 return res; 00416 } 00417 00418 00419 /* 00420 function: Jacobian 00421 purpose: Computes the Jacobian of a transformation 00422 input: transformID Evaluator task ID (e.g. "_A1") 00423 output: gec::SpatialData* pointer of data 00424 */ 00425 gec::SpatialData* NIREPEvaluator::Jacobian(const std::string& transformID, DisplayDescription * displayDescription) 00426 { 00427 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00428 gec::SpatialData* res = NULL; 00429 00430 // obtain the transformation from the database 00431 const gec::Transformation* trans = dynamic_cast<const gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00432 if(trans == NULL) { 00433 return NULL; 00434 } 00435 00436 //float min, max; 00437 //int min_x, min_y, min_z, max_x, max_y, max_z; 00438 gec::Jacobian* jac = new gec::Jacobian(trans); 00439 //res = jac->JacobianDiscrete3D(min, max, min_x, min_y, min_z, max_x, max_y, max_z, trans, 1.0F, 1.0F, 1.0F); 00440 res = jac->GetImage(); 00441 delete jac; 00442 00443 //std::string cmd = evaluatorCommands.fListTwo.find(6)->second+"(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00444 std::string cmd = EvalCmd["Jacobian"] + "(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00445 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00446 00447 return res; 00448 } 00449 00450 00451 /* 00452 function: Transform 00453 purpose: Transforms a spatial data with a transformation 00454 input: imageID Evaluator task ID ("e.g. "_A1") 00455 transformID Evaluator task ID (e.g. "_A3") 00456 output: gec::SpatialData* pointer of data 00457 */ 00458 gec::SpatialData* NIREPEvaluator::Transform(const std::string& imageID, const std::string& transformID, DisplayDescription * displayDescription) 00459 { 00460 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00461 gec::SpatialData* res = NULL; 00462 00463 gec::SpatialData* data = this->Evaluate(imageID, displayDescription); 00464 if( data == NULL ) { 00465 return NULL; 00466 } 00467 gec::Transformation* trans = dynamic_cast<gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00468 if( trans == NULL ) { 00469 return NULL; 00470 } 00471 00472 switch(data->GetDataType()) { 00473 case gec::SpatialData::IMAGE: 00474 res = trans->Transform(data, gec::LINEAR); 00475 break; 00476 case gec::SpatialData::OBJECTMAP: 00477 res = trans->Transform(data, gec::NEARESTNEIGHBOR); 00478 break; 00479 case gec::SpatialData::TRANSFORMATION: 00480 res = trans->Transform(data, gec::LINEAR); 00481 break; 00482 default: 00483 std::cerr << "ERROR: UNSUPPORTED TRANSFORMATION TYPE" << std::endl; 00484 break; 00485 } 00486 00487 /*std::string cmd = evaluatorCommands.fListTwo.find(7)->second+"(" + taskList->GetEvaluatorCommand(imageID) + 00488 "," + taskList->GetEvaluatorCommand(transformID) + ")";*/ 00489 std::string cmd = EvalCmd["TransformImage"]+"(" + taskList->GetEvaluatorCommand(imageID) + 00490 "," + taskList->GetEvaluatorCommand(transformID) + ")"; 00491 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00492 00493 return res; 00494 } 00495 00496 /* 00497 function: Transform 00498 purpose: Transforms a spatial data with a transformation 00499 input: imageID Evaluator task ID ("e.g. "_A1") 00500 transformID Evaluator task ID (e.g. "_A3") 00501 output: gec::SpatialData* pointer of data 00502 */ 00503 //orientation, width, color for grid, color for background, 00504 gec::SpatialData* NIREPEvaluator::TransformGrid(const std::string& transformID, DisplayDescription * displayDescription) 00505 { 00506 00507 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00508 gec::SpatialData* res = NULL; 00509 00510 gec::Transformation* trans = dynamic_cast<gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00511 if( trans == NULL ) { 00512 return NULL; 00513 } 00514 00515 int gridSpace = 8; 00516 const int *dimension = trans->GetDimension(); 00517 gec::Image grid = gec::Image(gec::Image::UCHAR, dimension); 00518 unsigned char * dataPointer = static_cast<unsigned char *> (grid.GetVTKData()->GetScalarPointer() ); 00519 00520 00521 00522 00523 00524 for(int k=0; k < dimension[2]; k++) { 00525 for(int j=0; j< dimension[1]; j++) { 00526 for(int i=0; i< dimension[0]; i++) { 00527 //need to add in for the other two orientations 00528 00529 //if(i%gridSpace == 0 || j%gridSpace == 0) { 00530 // //value at this location is 255; 00531 // dataPointer[grid.GetIndex(i,j,k)] = 255; 00532 //} 00533 00534 if(j%gridSpace == 0 || k%gridSpace == 0) { 00535 //value at this location is 255; 00536 dataPointer[grid.GetIndex(i,j,k)] = 255; 00537 } 00538 00539 //if(i%gridSpace == 0 || k%gridSpace == 0) { 00540 // //value at this location is 255; 00541 // dataPointer[grid.GetIndex(i,j,k)] = 255; 00542 //} 00543 } 00544 } 00545 } 00546 00547 00548 res = trans->Transform(&grid, gec::LINEAR); 00549 00550 /*std::string cmd = evaluatorCommands.fListTwo.find(7)->second+"(" + taskList->GetEvaluatorCommand(imageID) + 00551 "," + taskList->GetEvaluatorCommand(transformID) + ")";*/ 00552 std::string cmd = EvalCmd["TransformGrid"]+"(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00553 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00554 00555 return res; 00556 } 00557 00558 /* 00559 function: Transform 00560 purpose: Transforms a spatial data with a transformation 00561 input: imageID Evaluator task ID ("e.g. "_A1") 00562 transformID Evaluator task ID (e.g. "_A3") 00563 output: gec::SpatialData* pointer of data 00564 */ 00565 //orientation, width, color for grid, color for background, scale factor (float, adjusts where end point is) 00566 gec::SpatialData* NIREPEvaluator::VectorField(const std::string& transformID, DisplayDescription * displayDescription) 00567 { 00568 00569 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00570 //gec::SpatialData* res = NULL; 00571 00572 gec::Transformation* trans = dynamic_cast<gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00573 if( trans == NULL ) { 00574 return NULL; 00575 } 00576 00577 int gridSpace = 8; 00578 const int *dimension = trans->GetDimension(); 00579 gec::Image *res = new gec::Image(gec::Image::UCHAR, dimension); 00580 00581 unsigned char * dataPointer = static_cast<unsigned char *> (res->GetVTKData()->GetScalarPointer() ); 00582 float * transDataPointer = static_cast<float *>(trans->GetVTKData()->GetScalarPointer()); 00583 00584 00585 //Debugging, remove after we solve orientation issues 00586 00587 00588 //for(int k=0; k < dimension[2]; k++) { 00589 // for(int j=0; j< dimension[1]; j++) { 00590 // for(int i=0; i< dimension[0]; i++) { 00591 // //value at this location is 256; 00592 // transDataPointer[trans->GetIndex(i,j,k,0)] = 0; 00593 // transDataPointer[trans->GetIndex(i,j,k,1)] = (7*j)/dimension[1]; 00594 // transDataPointer[trans->GetIndex(i,j,k,2)] = (0); 00595 // } 00596 // } 00597 //} 00598 //-----------End of debugging 00599 00600 for(int k=0; k < dimension[2]; k++) { 00601 for(int j=0; j< dimension[1]; j++) { 00602 for(int i=0; i< dimension[0]; i++) { 00603 //if(i == 0) { 00604 // dataPointer[res->GetIndex(i,j,k)] = 255; 00605 //} 00606 if(false) 00607 { 00608 } 00609 if( (i%gridSpace == 0) && (j%gridSpace == 0) ) { 00610 00611 // value at this location is 256; 00612 float fdx = transDataPointer[trans->GetIndex(i,j,k,0)] * 1;// ( (dimension[0]-1) /3); 00613 float fdy = transDataPointer[trans->GetIndex(i,j,k,1)] * 1;//( (dimension[1]-1)/3); 00614 int intfdx = (fdx ) + i; 00615 int intfdy = (fdy ) + j; 00616 00617 //y= mx + b 00618 //m = fdy/fdx 00619 if(intfdx < 0) { 00620 intfdx = 0; 00621 intfdy = float(j) - float(i) * (fdy/fdx); 00622 } 00623 else if( intfdx > dimension[0] -1) { 00624 intfdx = dimension[0] -1; 00625 intfdy = (float((dimension[0] -1))*(fdy/fdx))+ (float(j) - float(i) * (fdy/fdx) ); 00626 } 00627 00628 00629 if(intfdy < 0) { 00630 float temp = (fdy/fdx); 00631 float tempTwo = float(i) * (fdy/fdx); 00632 float tempThree = ( float(-j) + float(i) * (fdy/fdx) ); 00633 intfdx = ( float(-j) + float(i) * (fdy/fdx) ) * (fdx/fdy); 00634 intfdy = 0; 00635 } 00636 else if( intfdy > dimension[1] -1) { 00637 intfdx = ( (dimension[1] -1) + (float(-j) + float(i) * (fdy/fdx)) ) * (fdx/fdy); 00638 intfdy = dimension[1] -1; 00639 } 00640 00641 int x0 = i; 00642 int y0 = j; 00643 int dx = intfdx - i; 00644 int dy = intfdy - j; 00645 int stepx = -1; 00646 int stepy = -1; 00647 if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } 00648 if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } 00649 dy <<= 1; // dy is now 2*dy 00650 dx <<= 1; // dx is now 2*dx 00651 00652 00653 dataPointer[res->GetIndex(x0,y0,k)] = 255; 00654 if (dx > dy) { 00655 int fraction = dy - (dx >> 1); // same as 2*dy - dx 00656 while (x0 != (intfdx)) { 00657 if (fraction >= 0) { 00658 y0 += stepy; 00659 fraction -= dx; // same as fraction -= 2*dx 00660 } 00661 x0 += stepx; 00662 fraction += dy; // same as fraction -= 2*dy 00663 dataPointer[res->GetIndex(x0,y0,k)] = 255; 00664 } 00665 } else { 00666 int fraction = dx - (dy >> 1); 00667 while (y0 != (intfdy)) { 00668 if (fraction >= 0) { 00669 x0 += stepx; 00670 fraction -= dy; 00671 } 00672 y0 += stepy; 00673 fraction += dx; 00674 dataPointer[res->GetIndex(x0,y0,k)] = 255; 00675 } 00676 } 00677 00678 // function line(x0, y0, x1, y1) 00679 //dx := abs(x1-x0) 00680 //dy := abs(y1-y0) 00681 //if x0 < x1 then sx := 1 else sx := -1 00682 //if y0 < y1 then sy := 1 else sy := -1 00683 //err := dx-dy 00684 00685 //loop 00686 // setPixel(x0,y0) 00687 // if x0 = x1 and y0 = y1 exit loop 00688 // e2 := 2*err 00689 // if e2 > -dy then 00690 // err := err - dy 00691 // x0 := x0 + sx 00692 // end if 00693 // if e2 < dx then 00694 // err := err + dx 00695 // y0 := y0 + sy 00696 // end if 00697 //end loop 00698 00699 } 00700 } 00701 } 00702 } 00703 00704 00705 //res = trans->Transform(&grid, gec::LINEAR); 00706 //res = &grid; 00707 00708 /*std::string cmd = evaluatorCommands.fListTwo.find(7)->second+"(" + taskList->GetEvaluatorCommand(imageID) + 00709 "," + taskList->GetEvaluatorCommand(transformID) + ")";*/ 00710 std::string cmd = EvalCmd["VectorField"]+"(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00711 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00712 00713 return res; 00714 } 00715 00716 00717 /* 00718 function: InvertTransformation 00719 purpose: Computes the inverse of a transformation 00720 input: transformID Evaluator task ID (e.g. "_A1") 00721 output: gec::SpatialData* pointer of data 00722 */ 00723 gec::SpatialData* NIREPEvaluator::InvertTransformation(const std::string& transformID, DisplayDescription * displayDescription) 00724 { 00725 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00726 gec::SpatialData* res = NULL; 00727 00728 // obtain the transformation from the database 00729 gec::Transformation* trans = dynamic_cast<gec::Transformation *>(this->Evaluate(transformID, displayDescription)); 00730 if(trans == NULL) { 00731 return NULL; 00732 } 00733 // prepare invert transformation 00734 res = trans->Invert(); 00735 00736 //std::string cmd = evaluatorCommands.fListTwo.find(8)->second+"(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00737 std::string cmd = EvalCmd["InvertTransformation"] +"(" + taskList->GetEvaluatorCommand(transformID) + ")"; 00738 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00739 00740 return res; 00741 } 00742 00743 00744 /* 00745 function: InverseConsistencyError 00746 purpose: Computes the inverse consistency error of a pair transformations 00747 input: fwdTransID Evaluator task ID (e.g. "_A1") 00748 revTransID Evaluator task ID (e.g. "_A2") 00749 method Computation method (e.g. inv/comp) 00750 output: gec::SpatialData* pointer of data 00751 */ 00752 gec::SpatialData* NIREPEvaluator::InverseConsistencyError(const std::string& fwdTransID, 00753 const std::string& revTransID, 00754 const std::string& method, 00755 DisplayDescription * displayDescription) 00756 { 00757 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00758 gec::SpatialData* res = NULL; 00759 00760 gec::Transformation* u12 = dynamic_cast<gec::Transformation *>(this->Evaluate(fwdTransID, displayDescription)); 00761 if(u12 == NULL) { 00762 return NULL; 00763 } 00764 NIREPInverseConsistencyError* ice = new NIREPInverseConsistencyError(this); 00765 if(method == "inv") { 00766 // || h_12(x) - h_21^-1(x) ||^2 = || u_12(x) - u_21^-1(x) ||^2 00767 gec::Transformation* u21i = 00768 dynamic_cast<gec::Transformation *>(this->InvertTransformation(revTransID, displayDescription)); 00769 if(u21i == NULL) { 00770 return NULL; 00771 } 00772 res = ice->ComputeICEImage(u12, u21i); 00773 } else { 00774 // || h_21(h_12(x)) - x ||^2 = || h_21(x+u_12(x)) - x ||^2 00775 // = || u_12(x) + u_21(x+u_12(x)) ||^2 00776 gec::Transformation* u121 = 00777 dynamic_cast<gec::Transformation *>(this->Transform(fwdTransID, revTransID, displayDescription)); 00778 if(u121 == NULL) { 00779 return NULL; 00780 } 00781 res = ice->ComputeICEImage(u121); 00782 } 00783 delete ice; 00784 00785 /*std::string cmd = evaluatorCommands.fListTwo.find(9)->second+"(" + taskList->GetEvaluatorCommand(fwdTransID) + 00786 "," + taskList->GetEvaluatorCommand(revTransID) + 00787 "," + method + ")";*/ 00788 std::string cmd = EvalCmd["InverseConsistencyErrorImage"]+"(" + taskList->GetEvaluatorCommand(fwdTransID) + 00789 "," + taskList->GetEvaluatorCommand(revTransID) + 00790 "," + method + ")"; 00791 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00792 00793 return res; 00794 } 00795 00796 00797 /* 00798 function: TransitivityError 00799 purpose: Computes the transitivity error of transformations 00800 input: transABID Evaluator task ID (ex: "_A1") 00801 transBCID Evaluator task ID (ex: "_A2") 00802 transCAID Evaluator task ID (ex: "_A3") 00803 method Computation method (e.g. inv/comp) 00804 output: gec::SpatialData* pointer of data 00805 */ 00806 gec::SpatialData* NIREPEvaluator::TransitivityError(const std::string& transABID, 00807 const std::string& transBCID, 00808 const std::string& transACID, 00809 const std::string& method, 00810 DisplayDescription * displayDescription) 00811 { 00812 EvaluatorList * taskList = displayDescription->GetEvaluatorList(); 00813 gec::SpatialData* res = NULL; 00814 00815 gec::Transformation* abc = 00816 dynamic_cast<gec::Transformation *>(this->Transform(transBCID, transABID, displayDescription)); 00817 if(abc == NULL) { 00818 return NULL; 00819 } 00820 gec::Transformation* ac = 00821 dynamic_cast<gec::Transformation *>(this->Evaluate(transACID, displayDescription)); 00822 if(ac == NULL) { 00823 return NULL; 00824 } 00825 00826 NIREPTransitivityError* te = new NIREPTransitivityError(this); 00827 if(method == "inv") { 00828 // || h_12(h_23(x)) - h_13(x) ||^2 00829 // = || u_23(x) + u_12(x+u_23(x)) - u_13(x) ||^2 00830 res = te->ComputeTEImage(abc, ac); 00831 } else { 00832 // || h_31(h_12(h_23(x))) - x ||^2 00833 // = || u_23(x) + u_12(x+u_23(x)) + u_31(x+u_23(x)+u_12(x+u_23(x))) ||^2 00834 // Perhaps there's a better way to do this, but this works for now 00835 std::string cmd = EvalCmd["TransformImage"] + "(" 00836 + EvalCmd["TransformImage"] + "(" 00837 + taskList->GetEvaluatorCommand(transBCID) + "," 00838 + taskList->GetEvaluatorCommand(transABID) + ")," 00839 + taskList->GetEvaluatorCommand(transACID) + ")"; 00840 gec::Transformation* abca = 00841 dynamic_cast<gec::Transformation *>(ac->Transform(abc, gec::LINEAR)); 00842 if(abca == NULL) { 00843 return NULL; 00844 } 00845 this->dataManager->SetLoadedSpatialDataListEntry(cmd, abca); 00846 res = te->ComputeTEImage(abca); 00847 } 00848 delete te; 00849 00850 //std::string cmd = evaluatorCommands.fListTwo.find(10)->second+"(" + taskList->GetEvaluatorCommand(transABID) + 00851 // "," + taskList->GetEvaluatorCommand(transBCID) + 00852 // "," + taskList->GetEvaluatorCommand(transACID) + 00853 // "," + method + ")"; 00854 std::string cmd = EvalCmd["TransitivityErrorImage"]+"(" + taskList->GetEvaluatorCommand(transABID) + 00855 "," + taskList->GetEvaluatorCommand(transBCID) + 00856 "," + taskList->GetEvaluatorCommand(transACID) + 00857 "," + method + ")"; 00858 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00859 00860 return res; 00861 } 00862 00863 /* 00864 function: IntensityVariance 00865 purpose: Computes the intensity variance of a range of transformations 00866 input: arg vector of strings (ex "1,[2:3;4:8],014, MRI") 00867 output: gec::SpatialData* pointer of data 00868 */ 00869 gec::SpatialData* NIREPEvaluator::IntensityVariance(std::vector<std::string>& arg, 00870 std::string version, 00871 DisplayDescription * displayDescription) 00872 { 00873 gec::SpatialData* res = NULL; 00874 00875 NIREPIntensityVariance* iv = new NIREPIntensityVariance(this); 00876 arg.insert(arg.begin(),version); 00877 res = iv->ComputeIVImage(arg,displayDescription); 00878 std::string cmd; 00879 00880 //if(!arg[0].compare("RegisteredImageVariance")) { 00881 // cmd = evaluatorCommands.fListTwo.find(11)->second+"(" + arg[1] + 00882 // "," + arg[2] + 00883 // "," + arg[3] + 00884 // "," + arg[4] + ")"; 00885 //} else if(!arg[0].compare("ImageVariance")) { 00886 // cmd = evaluatorCommands.fListTwo.find(12)->second+"(" + arg[1] + 00887 // "," + arg[2] + ")"; 00888 //} 00889 if(!arg[0].compare(EvalCmd["IntensityVarianceTransform"])) { 00890 cmd = EvalCmd["IntensityVarianceTransform"]+"(" + arg[1] + 00891 "," + arg[2] + 00892 "," + arg[3] + 00893 "," + arg[4] + ")"; 00894 } else if(!arg[0].compare(EvalCmd["IntensityVarianceImage"])) { 00895 cmd = EvalCmd["IntensityVarianceImage"]+"(" + arg[1] + 00896 "," + arg[2] + ")"; 00897 } 00898 this->dataManager->SetLoadedSpatialDataListEntry(cmd, res); 00899 00900 return res; 00901 } 00902