NIREP
|
00001 #include "NIREPIntensityVariance.h" 00002 00003 //Gets called from the Evaluator to compute the Statistic 00004 TextTable NIREPIntensityVariance::ComputeStatistic(const std::vector<std::string>& arg, DisplayDescription * displayDescription) 00005 { 00006 TextTable resultTextTable; 00007 this->Expand(arg); 00008 this->Compute(arg,displayDescription); 00009 00010 std::vector<float> values; 00011 00012 int *dims = result->GetVTKData()->GetDimensions(); 00013 const int size = dims[0] * dims[1] * dims[2]; 00014 00015 float * resultData = static_cast<float*>(result->GetVTKData()->GetScalarPointer()); 00016 for(int i=0;i<size;i++) 00017 { 00018 if(resultData[i] != 0) { 00019 int debugStop = 0; 00020 } 00021 values.push_back( resultData[i] ); 00022 } 00023 00024 int debugStop = 0; 00025 resultTextTable.Value.push_back(values); 00026 00027 return resultTextTable; 00028 } 00029 00030 //Gets called from the Evaluator to compute the image 00031 gec::SpatialData* NIREPIntensityVariance::ComputeIVImage(const std::vector<std::string>& arg, DisplayDescription * displayDescription) 00032 { 00033 this->Expand(arg); 00034 this->Compute(arg,displayDescription); 00035 return result; 00036 } 00037 00038 //mean: u = E{x} = 1/N * sum(x_i) from i=1 to N, where N is the number of images 00039 //Standard deviation: = E{x^2} = 1/N * sum( (x_i)^2 ) from i=1 to N, where N is the number of images 00040 //Variance: E{ (x-u)^2 } = E{x^2} - u^2 00041 void NIREPIntensityVariance::ImageVariance(const std::vector<std::string>& arg, DisplayDescription * displayDescription) { 00042 //intialize the mean image to all zeros and to the corresponding dimensions, spacing and we 00043 //want a float image to do computations. 00044 if(this->evaluator->ReadSpatialData(datasetID[0],arg[3],displayDescription) == NULL) { 00045 return; 00046 } 00047 gec::Image *mean = new gec::Image(gec::Image::FLOAT, 00048 dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[0],arg[2],displayDescription))->GetVTKData()->GetDimensions(), 00049 dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[0],arg[2],displayDescription))->GetVTKData()->GetSpacing()); 00050 if(mean == NULL) { 00051 return; 00052 } 00053 //intialize the result image to the same parameters as mean 00054 result = new gec::Image( *mean ); 00055 if(result == NULL) { 00056 return; 00057 } 00058 00059 //get the scalar pointers because that is how we have to do the computations 00060 float *meanData = static_cast<float*>(mean->GetVTKData()->GetScalarPointer()); 00061 float *resultData = static_cast<float*>(result->GetVTKData()->GetScalarPointer()); 00062 00063 //get the dimensions and spacing 00064 int *dims = mean->GetVTKData()->GetDimensions(); 00065 const int size = dims[0] * dims[1] * dims[2]; 00066 00067 //run through a for loop for each data that the user wants to use 00068 //to figure out the variance 00069 for(int h=0;h<datasetID.size();h++) 00070 { 00071 gec::Image *temp3 = dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[h],arg[2],displayDescription)); 00072 if(temp3 == NULL) { 00073 return; 00074 } 00075 unsigned char *temp3Data = static_cast<unsigned char*>(temp3->GetVTKData()->GetScalarPointer()); 00076 00077 //run through a for loop for each data point in the images to do the computations 00078 for(int i=0;i<size;i++) 00079 { 00080 meanData[i] = meanData[i] + static_cast<float>(temp3Data[i]); 00081 resultData[i] = resultData[i] + static_cast<float>(temp3Data[i]) * static_cast<float>(temp3Data[i]); 00082 } 00083 00084 //release the data from the data manager 00085 //this way we are conserving memory 00086 const std::string cmd = "SpatialData(" + datasetID[h] + "," + arg[2] + ")"; 00087 this->evaluator->GetDataManager()->ReleaseLoadedSpatialDataListEntry(cmd); 00088 } 00089 00090 //Do our final computations 00091 mean->Mul(1.0f/static_cast<float>(datasetID.size())); 00092 mean->Mul(mean); 00093 result->Mul(1.0f/static_cast<float>(datasetID.size())); 00094 result->Sub(mean); 00095 } 00096 00097 00098 //mean: u = E{x} = 1/N * sum(x_i) from i=1 to N, where N is the number of images 00099 //Standard deviation: = E{x^2} = 1/N * sum( (x_i)^2 ) from i=1 to N, where N is the number of images 00100 //Variance: E{ (x-u)^2 } = E{x^2} - u^2 00101 void NIREPIntensityVariance::RegisteredImageVariance(const std::vector<std::string>& arg, DisplayDescription * displayDescription) { 00102 //need to read in corresponding mri image and call transform 00103 00104 //intialize the mean image to all zeros and to the corresponding dimensions, spacing and we 00105 //want a float image to do computations. 00106 if(this->evaluator->ReadSpatialData(datasetID[0],arg[3],displayDescription) == NULL) { 00107 return; 00108 } 00109 gec::Image *mean = new gec::Image(gec::Image::FLOAT, 00110 dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[0],arg[3],displayDescription))->GetVTKData()->GetDimensions(), 00111 dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[0],arg[3],displayDescription))->GetVTKData()->GetSpacing()); 00112 if(mean == NULL) { 00113 return; 00114 } 00115 //intialize the result image to the same parameters as mean 00116 result = new gec::Image( *mean ); 00117 if(result == NULL) { 00118 return; 00119 } 00120 00121 00122 //get the dimensions and spacing 00123 int *dims = mean->GetVTKData()->GetDimensions(); 00124 const int size = dims[0] * dims[1] * dims[2]; 00125 00126 //get the scalar pointers because that is how we have to do the computations 00127 float * resultData = static_cast<float*>(result->GetVTKData()->GetScalarPointer()); 00128 float * meanData = static_cast<float*>(mean->GetVTKData()->GetScalarPointer()); 00129 00130 //run through a for loop for each data that the user wants to use 00131 //to figure out the variance 00132 for(int h=1;h<datasetID.size();h++) 00133 { 00134 gec::Transformation *temp3Trans = dynamic_cast<gec::Transformation *>(this->evaluator->ReadTransformation(datasetID[h],datasetID[0],arg[4],displayDescription)); 00135 if(temp3Trans == NULL) { 00136 return; 00137 } 00138 gec::Image *temp3Image = new gec::Image(*dynamic_cast<gec::Image *>(this->evaluator->ReadSpatialData(datasetID[h],arg[3],displayDescription))); 00139 if(temp3Image == NULL) { 00140 return; 00141 } 00142 00143 00144 gec::Image *temp3 = dynamic_cast<gec::Image *>(temp3Trans->Transform(temp3Image, gec::LINEAR)); 00145 if(temp3 == NULL) { 00146 return; 00147 } 00148 00149 unsigned char *temp3Data = static_cast<unsigned char*>(temp3->GetVTKData()->GetScalarPointer()); 00150 00151 //run through a for loop for each data point in the images to do the computations 00152 for(int i=0;i<size;i++) 00153 { 00154 meanData[i] = meanData[i] + static_cast<float>(temp3Data[i]); 00155 resultData[i] = resultData[i] + static_cast<float>(temp3Data[i]) * static_cast<float>(temp3Data[i]); 00156 } 00157 00158 //release the data from the data manager 00159 //this way we are conserving memory 00160 const std::string cmd = "Transformation("+ datasetID[h] + "," + datasetID[0] + "," + arg[4] + ")";; 00161 this->evaluator->GetDataManager()->ReleaseLoadedSpatialDataListEntry(cmd); 00162 00163 const std::string cmdTwo = "SpatialData(" + datasetID[h] + "," + arg[3] + ")"; 00164 this->evaluator->GetDataManager()->ReleaseLoadedSpatialDataListEntry(cmdTwo); 00165 } 00166 00167 //Do our final computations 00168 mean->Mul(1.0f/static_cast<float>(datasetID.size()-1)); 00169 mean->Mul(mean); 00170 result->Mul(1.0f/static_cast<float>(datasetID.size()-1)); 00171 result->Sub(mean); 00172 } 00173 00174 void NIREPIntensityVariance::Compute(const std::vector<std::string>& arg, DisplayDescription * displayDescription) 00175 { 00176 if(!arg[0].compare("ImageVariance")) { 00177 this->ImageVariance(arg,displayDescription); 00178 } 00179 else if(!arg[0].compare("RegisteredImageVariance")) { 00180 this->RegisteredImageVariance(arg,displayDescription); 00181 } 00182 } 00183 00184 //Expand out the part that is something like: [14;4:5;8:11] to a vector 00185 //that contains [14,4,5,8,9,10,11] 00186 void NIREPIntensityVariance::Expand(const std::vector<std::string>& arg) 00187 { 00188 //First we pull out the part that we want to expand from the argument list 00189 std::string stringToExpand; 00190 if(!arg[0].compare("RegisteredImageVariance")) { 00191 std::stringstream outTwo; 00192 if(atoi(arg[1].c_str()) < 10) 00193 outTwo<<"00"; 00194 else if(atoi(arg[1].c_str())<100) 00195 outTwo<<"0"; 00196 outTwo << atoi(arg[1].c_str()); 00197 datasetID.push_back(outTwo.str()); 00198 stringToExpand = arg[2]; 00199 stringToExpand.erase(0,1); 00200 stringToExpand.erase(stringToExpand.find_last_of("]"),1); 00201 00202 } 00203 else if(!arg[0].compare("ImageVariance")) { 00204 stringToExpand = arg[1]; 00205 stringToExpand.erase(0,1); 00206 stringToExpand.erase(stringToExpand.find_last_of("]"),1); 00207 } 00208 00209 00210 //This is where we begin the process of expanding 00211 00212 //first we have to have a char * to pass to strtok 00213 //Since we are using strings, and c_str() returns 00214 //a const char*, we are going to copy the data from 00215 //c_str to a new variable called strtokStringToExpand 00216 //which will be passed to strtok to tokenize bassed 00217 //on ";" 00218 char * strtokStringToExpand = new char[stringToExpand.size()+1](); 00219 memcpy(strtokStringToExpand,stringToExpand.c_str(),stringToExpand.size()+1); 00220 char* number = strtok (strtokStringToExpand,";"); 00221 00222 //keep tokenizing until we hit the end of the string 00223 while (number != NULL) 00224 { 00225 //Figure out if there is a : in the part that we 00226 //tokenized 00227 std::string numberTwo = number; 00228 size_t isColon = numberTwo.find_first_of(":"); 00229 std::string firstNumber; 00230 std::string secondNumber; 00231 //if there is a : then we figure out the first 00232 //number to expand from and the second number to expand to 00233 if(isColon != std::string::npos) { 00234 firstNumber = std::string(numberTwo,0,isColon); 00235 secondNumber = std::string(numberTwo,isColon+1, numberTwo.size()-isColon+1); 00236 } 00237 //if there is not a : then we set the first and second number 00238 //to the same value 00239 else { 00240 firstNumber = numberTwo; 00241 secondNumber = numberTwo; 00242 } 00243 //figure out the true number of the first number in terms 00244 //of integer 00245 int trueNumber = atoi(firstNumber.c_str()); 00246 for(int i=trueNumber; i<= atoi(secondNumber.c_str());i++) 00247 { 00248 //since when we store the values as three bits 00249 //in the database, we have to make sure that 00250 //the string has 3 bits based on the numbers 00251 //that is within the display descrption 00252 std::stringstream out; 00253 if(i < 10) 00254 out<<"00"; 00255 else if(i<100) 00256 out<<"0"; 00257 out << i; 00258 datasetID.push_back(out.str()); 00259 00260 } 00261 //get the next tokenized part 00262 number = strtok (NULL, ";"); 00263 } 00264 }