//v1.0a #include "stdafx.h" #include "contrast.h" using namespace std; bool contrast(DS_cube * cube, unsigned char percent, void * dlg_share) { register unsigned short int i; register unsigned char ic; unsigned short int iinc; unsigned char smoothingoption; smoothingoption = 0; //setup the progress bar parameters PoroMediaDialogShare* dlg = (PoroMediaDialogShare*) dlg_share; dlg->pbar_simulation_progress.SetRange(0, 2*cube->wZ-1); dlg->pbar_simulation_progress.SetPos(0); dlg->pbar_simulation_progress.SetStep(1); unsigned long int* hist = new unsigned long int [256]; //initialise histogram for(ic=0; ic < 255; ic++) hist[ic]=0; hist[255] = 0; //determine how many slices to analyse-> faster process //iinc = 1 + (cube->wX*cube->wY*cube->wZ) / (100*100*100); //100^3pixels, arbitrary value iinc = 1; { char log_txt[512]; sprintf(log_txt, "contrast: #slice step =%d", iinc); write_to_log(log_txt); } for (i=0/*1*/; i < /*=*/ cube->wZ; i=i+iinc) { if (i >= cube->wZ) //because of the i+=iinc loop control continue; //fill histogram for (register unsigned short int aa=0; aa < cube->wY; aa++) for (register unsigned short int bb=0; bb < cube->wX; bb++) ++hist[ cube->data[i][aa][bb] ]; //update progress bar dlg->pbar_simulation_progress.StepIt(); } /* if(smoothingoption==3) { unsigned long int* hist3=(unsigned long int*)malloc(sizeof(unsigned long int)*256); if(!hist3) { write_to_log("Threshold: out of memory for hist3"); } hist3[0]=hist[0]; for(ic=1; ic<=254; ic++) hist3[ic]=(hist[ic-1]+hist[ic]+hist[ic+1])/3; hist3[255]=hist[255]; for(ic=0; ic<255; ic++) hist[ic]=hist3[ic]; hist[255]=hist3[255]; if (hist3) free(hist3); } if(smoothingoption==5) { unsigned long int* hist5=(unsigned long int*)malloc(sizeof(unsigned long int)*256); if(!hist5) { write_to_log("Threshold: out of memory for hist5"); } hist5[0]=hist[0]; hist5[1]=(hist[0]+hist[1]+hist[2])/3; for(i=2;i<=253;i++) hist5[i]=(hist[i-2]+hist[i-1]+hist[i]+hist[i+1]+hist[i+2])/5; hist5[255]=hist[255]; hist5[254]=(hist[255]+hist[254]+hist[253])/3; for(i=0;i<=255;i++) hist[i]=hist5[i]; if (hist5) free(hist5); } //contrast enhancement { float p = 0.0005; //0.05% chosen arbitrarily unsigned long long limit = 0; limit = (unsigned long long) (p * (cube->wZ/iinc) * cube->wY * cube->wX); //find min for(ic=1; ic < 254; ic++) if ((hist[ic] > limit) & (hist[ic+1] > limit) & (hist[ic+2] > limit)) break; unsigned char imin = ic; { char log_txt[512]; sprintf(log_txt, "contrast: imin= %d (p=%.2f%%)", imin, 100*p); write_to_log(log_txt); } //update progress bar dlg->pbar_simulation_progress.StepIt(); //max for(ic=254; ic > 0 ; ic--) if ((hist[ic] > limit) & (hist[ic-1] > limit) & (hist[ic-2] > limit)) break; unsigned char imax = ic; { char log_txt[512]; sprintf(log_txt, "contrast: imax= %d (p=%.2f%%)", imax, 100*p); write_to_log(log_txt); } //update progress bar dlg->pbar_simulation_progress.StepIt(); //float coeff =0; //coeff = 255 / (float)(imax - imin); ////update cube values //for(i=0; i < cube->wZ; i++) // for (register unsigned short int aa=0; aa < cube->wY; aa++) // for (register unsigned short int bb=0; bb < cube->wX; bb++) // if ( cube->data[i][aa][bb] <= imin ) // cube->data[i][aa][bb] = 0; // else // cube->data[i][aa][bb] = (unsigned char)(0.5 + (float)(cube->data[i][aa][bb] - imin) * coeff ); */ //low values grayscale enhancement unsigned long long sum = 0; //unsigned long long limit = 0; //float p = (float)percent / 100; float p = (float)percent / 100; unsigned long long limit = (unsigned long long) (p * (cube->wZ/iinc) * cube->wY * cube->wX); sum = hist[0]; for(ic=1; ic < 255; ic++) { sum += hist[ic]; if (sum > limit) break; } unsigned char imin = ic; { char log_txt[512]; sprintf(log_txt, "contrast: imin= %d (p=%.2f%%)", imin, 100*p); write_to_log(log_txt); } sum = hist[255];; for(ic=254; ic >0; ic--) { sum += hist[ic]; if (sum > limit) break; } unsigned char imax = ic; { char log_txt[512]; sprintf(log_txt, "contrast: imax= %d (p=%.2f%%)", imax, 100*p); write_to_log(log_txt); } /* { char log_txt[512]; sprintf(log_txt, "contrast: ic= %d (p=%.2f%%)", ic, 100*p); write_to_log(log_txt); } //update progress bar dlg->pbar_simulation_progress.StepIt(); float coeff =0; //imax = 255; //coeff = 255 / (float)(255-ic); coeff = 255 / (float)(imax - ic); //update cube values for(i=0; i < cube->wZ; i++) for (register unsigned short int aa=0; aa < cube->wY; aa++) for (register unsigned short int bb=0; bb < cube->wX; bb++) if ( cube->data[i][aa][bb] <= ic ) cube->data[i][aa][bb] = 0; else cube->data[i][aa][bb] = (unsigned char)(0.5 + (float)(cube->data[i][aa][bb] - ic) * coeff ); */ if ( imax-imin < 200) { float coeff = 255 / (float)(imax - imin); //update cube values for(i=0; i < cube->wZ; i++) { for (register unsigned short int aa=0; aa < cube->wY; aa++) for (register unsigned short int bb=0; bb < cube->wX; bb++) { if ( cube->data[i][aa][bb] <= imin ) cube->data[i][aa][bb] = 0; else if ( cube->data[i][aa][bb] >= imax ) cube->data[i][aa][bb] = 255; else cube->data[i][aa][bb] = (unsigned char)(0.5 + (float)(cube->data[i][aa][bb] - imin) * coeff ); } //update progress bar dlg->pbar_simulation_progress.StepIt(); } } //free histogram delete hist; //{//write final value out to the log // char log_txt[512]; // sprintf(log_txt, "Threshold: final = %d", result.value); // write_to_log(log_txt); //} return true; } bool contrast_boost(DS_cube * cube, unsigned char iteration, void * dlg_share) { register unsigned short int i, j, k; unsigned char imin1, imax1;//, imin2, imax2, imin3, imax3, imin4, imax4, imin5, imax5; //setup the progress bar parameters PoroMediaDialogShare* dlg = (PoroMediaDialogShare*) dlg_share; dlg->pbar_simulation_progress.SetRange(0, cube->wZ-1); dlg->pbar_simulation_progress.SetPos(0); dlg->pbar_simulation_progress.SetStep(1); unsigned char mid_value = dlg->filter_aniso_midpoint; //decision values //based on an average point @ mid_value //and a 12 iteration run //cut-off start @ +/- 40 //cut-off end @ +/- 16 imin1 = mid_value - 40 + 2*iteration; imax1 = mid_value + 40 - 2*iteration; //imin2 = (unsigned char) (mid_value - 46 + 2.5*iteration); //imax2 = (unsigned char) (mid_value + 46 - 2.5*iteration); //imin3 = mid_value - 52 + 3*iteration; //imax3 = mid_value + 52 - 3*iteration; //imin4 = (unsigned char) (mid_value - 58 + 3.5*iteration); //imax4 = (unsigned char) (mid_value + 58 - 3.5*iteration); //imin5 = mid_value - 64 + 4*iteration; //imax5 = mid_value + 64 - 4*iteration; //update cube values for (k=0; k < cube->wZ; k++) { for (j=0; j < cube->wY; j++) for (i=0; i < cube->wX; i++) { //1 if ( cube->data[k][j][i] <= imin1 ) { if ( cube->data[k][j][i] > (unsigned char)(imin1/5) ) cube->data[k][j][i] -= 1 + (unsigned char)((imin1 - cube->data[k][j][i]) /5); //else // cube->data[k][j][i] = 0; } else if ( cube->data[k][j][i] >= imax1 ) { if ( cube->data[k][j][i] < 255-(unsigned char)((255-imax1)/5) ) cube->data[k][j][i] += 1 + (unsigned char)((cube->data[k][j][i] - imax1) /5); //else // cube->data[k][j][i] = 255; } } //update progress bar dlg->pbar_simulation_progress.StepIt(); } //update cube values //for (k=0; k < cube->wZ; k++) //{ // for (j=0; j < cube->wY; j++) // for (i=0; i < cube->wX; i++) // { // //5 // if ( cube->data[k][j][i] <= imin5 ) // { // if (cube->data[k][j][i] > 0) // --cube->data[k][j][i]; // } // else if ( cube->data[k][j][i] >= imax5 ) // { // if (cube->data[k][j][i] < 255) // ++cube->data[k][j][i]; // } // //4 // if ( cube->data[k][j][i] <= imin4 ) // { // if (cube->data[k][j][i] > 0) // --cube->data[k][j][i]; // } // else if ( cube->data[k][j][i] >= imax4 ) // { // if (cube->data[k][j][i] < 255) // ++cube->data[k][j][i]; // } // //3 // if ( cube->data[k][j][i] <= imin3 ) // { // if (cube->data[k][j][i] > 0) // --cube->data[k][j][i]; // } // else if ( cube->data[k][j][i] >= imax3 ) // { // if (cube->data[k][j][i] < 255) // ++cube->data[k][j][i]; // } // //2 // if ( cube->data[k][j][i] <= imin2 ) // { // if (cube->data[k][j][i] > 0) // --cube->data[k][j][i]; // } // else if ( cube->data[k][j][i] >= imax2 ) // { // if (cube->data[k][j][i] < 255) // ++cube->data[k][j][i]; // //1 // if ( cube->data[k][j][i] <= imin1 ) // { // if (cube->data[k][j][i] > 0) // --cube->data[k][j][i]; // } // else if ( cube->data[k][j][i] >= imax1 ) // { // if (cube->data[k][j][i] < 255) // ++cube->data[k][j][i]; // } // } // } // //update progress bar // dlg->pbar_simulation_progress.StepIt(); //} return true; } bool contrast_boost_simple(DS_cube * cube, unsigned char below, unsigned char above, void * dlg_share) { register unsigned short int i, j, k; //setup the progress bar parameters PoroMediaDialogShare* dlg = (PoroMediaDialogShare*) dlg_share; dlg->pbar_simulation_progress.SetRange(0, cube->wZ-1); dlg->pbar_simulation_progress.SetPos(0); dlg->pbar_simulation_progress.SetStep(1); //display message in filter window char win_txt [512]; sprintf(win_txt, "Contrast Boost..."); dlg->txt_field_progress.SetWindowText(win_txt); //update cube values for (k=0; k < cube->wZ; k++) { for (j=0; j < cube->wY; j++) for (i=0; i < cube->wX; i++) { if ( (cube->data[k][j][i] <= below) && (cube->data[k][j][i]) ) cube->data[k][j][i] --; else if ( (cube->data[k][j][i] >= above) && ((unsigned char)~cube->data[k][j][i]) ) cube->data[k][j][i] ++; } //update progress bar dlg->pbar_simulation_progress.StepIt(); } return true; } bool contrast_extremum(DS_cube * cube, void * dlg_share) { //unfinished register unsigned short int i, j; //#1 - Z //temporary slices DS_slice* dslice = new DS_slice(cube->wY, cube->wX); DS_slice* dslice_extremum = new DS_slice(cube->wY, cube->wX); //deltas - short int DS_slice_si* dx = new DS_slice_si(dslice->wY, dslice->wX-1); DS_slice_si* dy = new DS_slice_si(dslice->wY-1, dslice->wX); //calculate intermediate results (gradients&deltas) { for (i=0; i<dslice->wX-1; i++) for (j=0; j<dslice->wY-1; j++) { //x dx->data[j][i] = dslice->data[j][i+1] - dslice->data[j][i]; //y dy->data[j][i] = dslice->data[j+1][i] - dslice->data[j][i]; } i=dslice->wX-1; for (j=0; j<dslice->wY-1; j++) { //y dy->data[j][i] = dslice->data[j+1][i] - dslice->data[j][i]; } j=dslice->wY-1; for (i=0; i<dslice->wX-1; i++) { //x dx->data[j][i] = dslice->data[j][i+1] - dslice->data[j][i]; } } //initialise extremums for (i=0; i<dslice_extremum->wX; i++) for (j=0; j<dslice_extremum->wY; j++) dslice_extremum->data[j][i] = 128; //write temporary slice @ depth k cube->to_DS_slice(dslice, 0); //find local extremums //{ // //register unsigned char min, max; // for (i=0; i<dslice->wX-1; i++) // if (dx->data[j][i] * dx->data[j][i+1] >= 0) // dx->data[j][i+1] = 0; // min = max = dslice[0][i]; // for (j=1; j<dslice->wY; j++) // { // if (dslice[j[i] < min // } // //} //setup the progress bar parameters PoroMediaDialogShare* dlg = (PoroMediaDialogShare*) dlg_share; dlg->pbar_simulation_progress.SetRange(0, 2*cube->wZ-1); dlg->pbar_simulation_progress.SetPos(0); dlg->pbar_simulation_progress.SetStep(1); return true; }