// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void XtArrayInitialization::initialize(EMMPM_Data::Pointer data) { size_t total; total = data->rows * data->columns; const float rangeMin = 0.0f; const float rangeMax = 1.0f; typedef boost::uniform_real<> NumberDistribution; typedef boost::mt19937 RandomNumberGenerator; typedef boost::variate_generator<RandomNumberGenerator&, NumberDistribution> Generator; NumberDistribution distribution(rangeMin, rangeMax); RandomNumberGenerator generator; Generator numberGenerator(generator, distribution); generator.seed(EMMPM_getMilliSeconds()); // seed with the current time /* Initialize classification of each pixel randomly with a uniform disribution */ for (size_t i = 0; i < total; i++) { data->xt[i] = numberGenerator() * data->classes; } }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- void acvmpm(EMMPM_Data* data, EMMPM_CallbackFunctions* callbacks) { double* yk; double sqrt2pi, current, con[EMMPM_MAX_CLASSES]; double x, post[EMMPM_MAX_CLASSES], sum, edge; int k, l, prior; int i, j, d; size_t ld, ijd, ij, lij, i1j1; int dims = data->dims; int rows = data->rows; int cols = data->columns; int classes = data->classes; unsigned char* y = data->y; unsigned char* xt = data->xt; double* probs = data->probs; double* m = data->m; double* v = data->v; double* ccost = data->ccost; double* ns = data->ns; double* ew = data->ew; double* sw = data->sw; double* nw = data->nw; char msgbuff[256]; float totalLoops; float currentLoopCount = 0.0; // double local_beta; size_t nsCols = data->columns - 1; // size_t nsRows = data->rows; size_t ewCols = data->columns; // size_t ewRows = data->rows - 1; size_t swCols = data->columns - 1; // size_t swRows = data->rows - 1; size_t nwCols = data->columns-1; // size_t nwRows = data->rows-1; memset(post, 0, EMMPM_MAX_CLASSES * sizeof(double)); memset(con, 0, EMMPM_MAX_CLASSES * sizeof(double)); totalLoops = (float)(data->emIterations * data->mpmIterations + data->mpmIterations); memset(msgbuff, 0, 256); data->progress++; yk = (double*)malloc(cols * rows * classes * sizeof(double)); sqrt2pi = sqrt(2.0 * M_PI); unsigned long long int millis = EMMPM_getMilliSeconds(); for (l = 0; l < classes; l++) { con[l] = 0; for (d = 0; d < dims; d++) { ld = dims * l + d; con[l] += -log(sqrt2pi * sqrt(v[ld])); } } for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { for (l = 0; l < classes; l++) { lij = (cols * rows * l) + (cols * i) + j; probs[lij] = 0; yk[lij] = con[l]; for (d = 0; d < dims; d++) { ld = dims * l + d; ijd = (dims * cols * i) + (dims * j) + d; yk[lij] += ((y[ijd] - m[ld]) * (y[ijd] - m[ld]) / (-2.0 * v[ld])); } } } } printf("Serial Millis to complete initialization: %llu \n", EMMPM_getMilliSeconds() - millis); /* Perform the MPM loops */ for (k = 0; k < data->mpmIterations; k++) { data->currentMPMLoop = k; if (data->cancel) { data->progress = 100.0; break; } data->inside_mpm_loop = 1; millis = EMMPM_getMilliSeconds(); for (i = 0; i < rows; i++) { for (j = 0; j < cols; j++) { ij = (cols * i) + j; sum = 0; for (l = 0; l < classes; l++) { /* edge penalties (in both x and y) */ prior = 0; edge = 0; if (i - 1 >= 0) { if (j - 1 >= 0) { i1j1 = (cols*(i-1))+j-1; if (xt[i1j1] != l) { prior++; i1j1 = (swCols*(i-1))+j-1; edge += sw[i1j1]; } } //Mark1 i1j1 = (cols*(i-1))+j; if (xt[i1j1] != l) { prior++; i1j1 = (ewCols*(i-1))+j; edge += ew[i1j1]; } //mark2 if (j + 1 < cols) { i1j1 = (cols*(i-1))+j+1; if (xt[i1j1] != l) { prior++; i1j1 = (nwCols*(i-1))+j; edge += nw[i1j1]; } } } //mark3 if (i + 1 < rows) { if (j - 1 >= 0) { i1j1 = (cols*(i+1))+j-1; if (xt[i1j1] != l) { prior++; i1j1 = (nwCols*(i))+j-1; edge += nw[i1j1]; } } //mark4 i1j1 = (cols*(i+1))+j; if (xt[i1j1] != l) { prior++; i1j1 = (ewCols*(i))+j; edge += ew[i1j1]; } //mark5 if (j + 1 < cols) { i1j1 = (cols*(i+1))+j+1; if (xt[i1j1] != l) { prior++; i1j1 = (swCols*(i))+j; edge += sw[i1j1]; } } } //mark6 if (j - 1 >= 0) { i1j1 = (cols*(i))+j-1; if (xt[i1j1] != l) { prior++; i1j1 = (nsCols*(i))+j-1; edge += ns[i1j1]; } } //mark7 if (j + 1 < cols) { i1j1 = (cols*(i))+j+1; if (xt[i1j1] != l) { prior++; i1j1 = (nsCols*(i))+j; edge += ns[i1j1]; } } lij = (cols * rows * l) + (cols * i) + j; post[l] = exp(yk[lij] - (data->workingBeta * (double)prior) - edge - (data->beta_c * ccost[lij]) - data->w_gamma[l]); sum += post[l]; } x = genrand_real2(data->rngVars); current = 0; for (l = 0; l < classes; l++) { lij = (cols * rows * l) + (cols * i) + j; ij = (cols*i)+j; if ((x >= current) && (x <= (current + post[l] / sum))) { xt[ij] = l; probs[lij] += 1.0; } current += post[l] / sum; } } } printf("Millis to complete loop: %llu \n", EMMPM_getMilliSeconds() - millis); EMMPM_ConvertXtToOutputImage(data, callbacks); if (callbacks->EMMPM_ProgressFunc != NULL) { data->currentMPMLoop = k; snprintf(msgbuff, 256, "MPM Loop %d", data->currentMPMLoop); callbacks->EMMPM_ProgressFunc(msgbuff, data->progress); } if (NULL != callbacks->EMMPM_ProgressStatsFunc) { currentLoopCount = data->mpmIterations * data->currentEMLoop + data->currentMPMLoop; data->progress = currentLoopCount / totalLoops * 100.0; callbacks->EMMPM_ProgressStatsFunc(data); } } data->inside_mpm_loop = 0; if (!data->cancel) { /* Normalize probabilities */ for (i = 0; i < data->rows; i++) { for (j = 0; j < data->columns; j++) { for (l = 0; l < classes; l++) { lij = (cols * rows * l) + (cols * i) + j; data->probs[lij] = data->probs[lij] / (double)data->mpmIterations; } } } } /* Clean Up Memory */ free(yk); }
// ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- int main(int argc,char *argv[]) { // unsigned long long int millis = EMMPM_getMilliSeconds(); #if defined (EMMPMLib_USE_PARALLEL_ALGORITHMS) tbb::task_scheduler_init init; std::cout << "Default Number of Threads: " << init.default_num_threads() << std::endl; #endif int err = 0; EMMPM_Data::Pointer data = EMMPM_Data::New(); // EMMPM_CallbackFunctions* callbacks = EMMPM_AllocateCallbackFunctionStructure(); #if 1 /* Parse the command line arguments */ EMMPMInputParser parser; err = parser.parseCLIArguments(argc, argv, data.get()); if (err < 0) { printf("Error trying to parse the arguments.\n"); return 0; } #else char* infile = (char*)(malloc(1024)); memset(infile, 0, 1024); snprintf(infile, 1024, "/Users/mjackson/Desktop/EMMPM.tif"); char* outfile = (char*)(malloc(1024)); memset(outfile, 0, 1024); snprintf(outfile, 1024, "/tmp/out.tif"); data->input_file_name = infile; data->output_file_name = outfile; data->emIterations = 1; data->mpmIterations = 1; data->in_beta = 1.0; data->classes = 2; data->dims = 1; data->initType = EMMPM_Basic; data->simulatedAnnealing = 0; data->grayTable[0] = 0; data->grayTable[1] = 255; data->verbose = 1; data->w_gamma[0] = 1.0; data->w_gamma[1] = 1.0; data->useCurvaturePenalty = 0; data->ccostLoopDelay = 0; data->beta_e = 1.0; data->beta_c = 0.0; data->r_max = 1.0; #endif /* Set the Callback functions to provide feedback */ Observer obs; CLIStatsDelegate::Pointer statsDelegate = CLIStatsDelegate::New(); // Get our input image from the Image IO functions TiffUtilities tifUtil; err = tifUtil.readInputImage(data); if (err < 0) { printf("Error Reading the input image.\n"); return 0; } InitializationFunction::Pointer initFunction = BasicInitialization::New(); // Set the initialization function based on the command line arguments switch(data->initType) { case EMMPM_ManualInit: initFunction = InitializationFunction::New(); break; case EMMPM_UserInitArea: initFunction = UserDefinedAreasInitialization::New(); break; default: break; } obs.updateProgressAndMessage("EM/MPM Starting.... ", 0); // Allocate all the memory here data->allocateDataStructureMemory(); if (err) { printf("Error allocating memory for the EMMPM Data Structure.\n %s(%d)\n", __FILE__, __LINE__); return 1; } EMMPM::Pointer emmpm = EMMPM::New(); emmpm->addObserver(&obs); emmpm->setData(data); emmpm->setStatsDelegate(statsDelegate.get()); emmpm->setInitializationFunction(initFunction); emmpm->execute(); err = tifUtil.writeOutputImage(data); if (err < 0) { return 0; } #if 0 #if defined (EMMPMLib_USE_PARALLEL_ALGORITHMS) std::cout << "Parrallel Time to Complete:"; #else std::cout << "Serial Time To Complete: "; #endif std::cout << (EMMPM_getMilliSeconds() - millis) << std::endl; #endif EMMPMUtilities::MonitorMeansAndVariances(data); // Write the stats file std::stringstream ss; ss << data->output_file_name << "_Stats.txt"; std::cout << "StatsFile: " << ss.str() << std::endl; FILE* f = fopen(ss.str().c_str(), "wb"); fprintf(f, "InputFile:%s\n", data->input_file_name); fprintf(f, "SegmentedFile:%s\n" , data->output_file_name); fprintf(f, "NumClasses:%d\n", data->classes); fprintf(f, "Class,Mu,Sigma\n"); // Remember the Sigma is the Square Root of the variance for(int i = 0; i < data->classes; ++i) { fprintf(f, "%d,%f,%f\n", i, data->mean[i] , sqrtf(data->variance[i]) ); } fclose(f); std::cout << "EM/MPM Ending" << std::endl; return 1; }