lM_coocur.c

Go to the documentation of this file.
00001 /*
00002 *    Copyright (c) 2007. The BATI team. All right reserved.
00003 *
00004 *    This file is part of BATI library.
00005 *
00006 *    BATI library is free software: you can redistribute it and/or modify
00007 *    it under the terms of the GNU General Public License as published by
00008 *    the Free Software Foundation, either version 3 of the License, or
00009 *    (at your option) any later version.
00010 *
00011 *    BATI library  is distributed in the hope that it will be useful,
00012 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 *    GNU General Public License for more details.
00015 *
00016 *    You should have received a copy of the GNU General Public License
00017 *    along with BATI library.  If not, see <http://www.gnu.org/licenses/>.
00018 */
00019 
00020 /* ****************************M_coocur.c**************************/
00021 /*                                                                    */
00022 /* ********************************************************************/
00023 
00032   /* doc suivantes en sous-partie */
00033 
00034 // #define _ISOC99_SOURCE
00035 #include <math.h>
00036 #include <stdlib.h>
00037 #include <string.h>
00038 #include <limits.h>
00039 #include "volume.h"
00040 #include <curses.h>
00041 
00042 #include "M_coocur.h"
00043 
00044 //#define with_curses
00045 
00046 void updateContrast(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00047 {
00048     glcmData->contrast += (row - col) * (row - col) * (newValue - oldValue);
00049 }
00050 
00051 double finalizeContrast(GlcmData *glcmData)
00052 {
00053     return glcmData->contrast / (double) glcmData->nonZeros;
00054 }
00055 
00056 // double computeCorrelation(GlcmData *glcmData)
00057 // {
00058 //     int i, j;
00059 //     unsigned long tmp = 0;
00060 // 
00061 //     if (glcmData->variance_x == 0 || glcmData->variance_y == 0)
00062 //         return 0;
00063 // 
00064 //     for(j = 0; j < 256; j++)
00065 //         for(i = 0; i < 256; i++)
00066 //             tmp += (j - glcmData->moyenne_y) * (i - glcmData->moyenne_x) * glcmData->Matcoocur[j][i];
00067 //     return ((double)tmp) / (glcmData->valnon * glcmData->variance_x * glcmData->variance_y);
00068 // }
00069 
00070 void updateCorrelation(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00071 {
00072 //     glcmData->
00073 }
00074 
00075 double finalizeCorrelation(GlcmData *glcmData)
00076 {
00077 }
00078 
00079 void updateDirectivity(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00080 {
00081     if (row == col)
00082         glcmData->directivity += (newValue - oldValue);
00083 }
00084 
00085 double finalizeDirectivity(GlcmData *glcmData)
00086 {
00087     return glcmData->directivity / (double) glcmData->nonZeros;
00088 }
00089 
00090 void updateEntropy(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00091 {
00092     if (newValue != 0) {
00093         glcmData->m_log_m += newValue * log10(newValue);
00094         glcmData->sum += newValue;
00095     }
00096     if (oldValue != 0) {
00097         glcmData->m_log_m -= oldValue * log10(oldValue);
00098         glcmData->sum -= oldValue;
00099     }
00100 }
00101 
00102 double finalizeEntropy(GlcmData *glcmData)
00103 {
00104     return 1 - (glcmData->m_log_m - log10(glcmData->nonZeros) * glcmData->sum) / (glcmData->nonZeros * log10(glcmData->nonZeros));
00105 }
00106 
00107 void updateHomogeneity(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00108 {
00109     glcmData->homogeneity += (newValue * newValue - oldValue * oldValue);
00110 }
00111 
00112 double finalizeHomogeneity(GlcmData *glcmData)
00113 {
00114     return glcmData->homogeneity / (double) glcmData->nonZeros;
00115 }
00116 
00117 void updateLocalHomogeneity(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00118 {
00119     glcmData->localHomogeneity += (newValue - oldValue) / (1 + (row - col) * (row - col));
00120 }
00121 
00122 double finalizeLocalHomogeneity(GlcmData *glcmData)
00123 {
00124     return glcmData->localHomogeneity / (double) glcmData->nonZeros;
00125 }
00126 
00127 void updateSumAverage(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00128 {
00129     glcmData->sumAverage += (row + col) * (newValue - oldValue);
00130 }
00131 
00132 double finalizeSumAverage(GlcmData *glcmData)
00133 {
00134     return glcmData->sumAverage / (double) glcmData->nonZeros;
00135 }
00136 
00137 void updateSumEntropy(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00138 {
00139     glcmData->anti_diagonals_sums[row + col] += (newValue - oldValue);
00140 }
00141 
00142 double finalizeSumEntropy(GlcmData *glcmData)
00143 {
00144     double result = 0;
00145     int i;
00146     for (i = 0; i < 256 * 2 - 1; i ++)
00147         if (glcmData->anti_diagonals_sums[i] != 0)
00148             result += glcmData->anti_diagonals_sums[i] * log10(glcmData->anti_diagonals_sums[i]);
00149     return result / (double) glcmData->nonZeros;
00150 }
00151 
00152 void updateUniformity(int row, int col, int oldValue, int newValue, GlcmData *glcmData)
00153 {
00154     if (row == col)
00155         glcmData->uniformity += (newValue * newValue - oldValue * oldValue);   
00156 }
00157 
00158 double finalizeUniformity(GlcmData *glcmData)
00159 {
00160     return glcmData->uniformity / (double) (glcmData->nonZeros * glcmData->nonZeros);
00161 }
00162 
00163 GlcmAttribute attributes[total_attributes] =
00164 {
00165     { .name = "Constrast", .short_name = "Con", .update = updateContrast, .finalize = finalizeContrast},
00166     { .name = "Correlation", .short_name = "Cor", .update = updateCorrelation, .finalize = finalizeCorrelation},
00167     { .name = "Directivity", .short_name = "Dir", .update = updateDirectivity, .finalize = finalizeDirectivity},
00168     { .name = "Entropy", .short_name = "Ent", .update = updateEntropy, .finalize = finalizeEntropy},
00169     { .name = "Homogeneity", .short_name = "Hom", .update = updateHomogeneity, .finalize = finalizeHomogeneity},
00170     { .name = "Local Homogeneity", .short_name = "LHo", .update = updateLocalHomogeneity, .finalize = finalizeLocalHomogeneity},
00171     { .name = "Sum average", .short_name = "SAv", .update = updateSumAverage, .finalize = finalizeSumAverage},
00172     { .name = "Sum entropy", .short_name = "SEn", .update = updateSumEntropy, .finalize = finalizeSumEntropy},
00173     { .name = "Uniformity", .short_name = "Uni", .update = updateUniformity, .finalize = finalizeUniformity},
00174 };
00175 
00176 void initGlcmData(GlcmData *glcmData)
00177 {
00178     int row, col;
00179     for (row = 0; row < 256; row ++)
00180         for(col = 0; col < 256; col ++)
00181             glcmData->Matcoocur[row][col] = 0;
00182     glcmData->nonZeros = 0;
00183     glcmData->contrast = 0;
00184     glcmData->directivity = 0;
00185     glcmData->m_log_m = 0;
00186     glcmData->sum = 0;
00187     glcmData->homogeneity = 0;
00188     glcmData->localHomogeneity = 0;
00189     glcmData->sumAverage = 0;
00190     glcmData->uniformity = 0;
00191     for (row = 0; row < 256; row ++)
00192         glcmData->anti_diagonals_sums[row] = 0;
00193 }
00194 
00195 void valueUpdateGlcmData(int row, int col, int oldValue, int newValue, GlcmData *glcmData, Mcoocur_t *des)
00196 {
00197     int i;
00198     for (i = 0; i < total_attributes; i++)
00199         if (des->do_output[i])
00200             attributes[i].update(row, col, oldValue, newValue, glcmData);
00201     
00202     if (oldValue != 0 && newValue == 0)
00203         glcmData->nonZeros --;
00204     else if (oldValue == 0 && newValue != 0)
00205         glcmData->nonZeros ++;
00206 }
00207 
00208 void pixelUpdateGlcmData(int x, int y, int z, int increment, GlcmData *glcmData, ima3Du1* im0, Mcoocur_t *des)
00209 {
00210     int row = im0->data[z][y][x];
00211     int col = im0->data[z + des->dz][y + des->dy][x + des->dx];
00212     
00213     int oldValue = glcmData->Matcoocur[row][col];
00214     int newValue = oldValue + increment;
00215     glcmData->Matcoocur[row][col] = newValue;
00216 
00217     valueUpdateGlcmData(row, col, oldValue, newValue, glcmData, des);
00218 }
00219 
00220 /* *************************  INITIALISATION  ***************************/
00231 int Mcoocur_init(Mcoocur_t* des, ima3Du1* im0, ima3Dd* imres[])
00232 {
00233     int i;
00234     /* image resultat */
00235 
00236     for (i = 0; i < total_attributes; i++)
00237     {
00238         if (des->do_output[i])
00239         {
00240             imres[i] = (ima3Dd *) malloc(sizeof(ima3Dd));
00241             imres[i]->dimx=im0->dimx;
00242             imres[i]->dimy=im0->dimy;
00243             imres[i]->dimz=im0->dimz;
00244             allouer_ima3Dd (imres[i]);
00245             imres[i]->lgtete= im0->lgtete;
00246             imres[i]->dept = 64;
00247         }
00248         else
00249             imres[i] = 0;
00250     }
00251     return 0;
00252 }
00253 
00254 /* *************************  LECTURE  *******************************/
00264 param* Mcoocur_lect(Mcoocur_t *des, param *ptp, char *debq)
00265 {
00266     char question[500];
00267     int i;
00268     //Taille de la fenetre sur X
00269     sprintf(question, "%s winx", debq);
00270     lec_param(question, ptp);
00271     des->winx = atoi(ptp->rep);
00272     ptp = ptp->next;
00273     //Taille de la fenetre sur Y
00274     sprintf(question, "%s winy", debq);
00275     lec_param(question, ptp);
00276     des->winy= atoi(ptp->rep);
00277     ptp = ptp->next;
00278 
00279     //Taille de la fenetre sur Z
00280     sprintf(question, "%s winz", debq);
00281     lec_param(question, ptp);
00282     des->winz = atoi(ptp->rep);
00283     ptp = ptp->next;
00284 
00285     //Vecteur de calcule de la distance
00286     sprintf(question, "%s dx ", debq);
00287     lec_param(question, ptp);
00288     des->dx = atoi(ptp->rep);
00289     ptp = ptp->next;
00290 
00291     //Vecteur de calcule de la distance
00292     sprintf(question, "%s dy", debq);
00293     lec_param(question, ptp);
00294     des->dy = atoi(ptp->rep);
00295     ptp = ptp->next;
00296 
00297     //Vecteur de calcule de la distance
00298     sprintf(question, "%s dz ", debq);
00299     lec_param(question, ptp);
00300     des->dz = atoi(ptp->rep);
00301     ptp = ptp->next;
00302 
00303     //Choix de l'atribut
00304     for (i = 0; i < total_attributes; i++)
00305     {
00306         sprintf(question, "%s %s (0/1)", debq, attributes[i].name);
00307         lec_param(question, ptp);
00308         des->do_output[i] = (ptp->rep[0] == '1');
00309         ptp = ptp->next;
00310     }
00311     return(ptp);
00312 }
00313 
00314 /* *************************  CALCUL  ***************************/
00324 int Mcoocur_calc(Mcoocur_t *des, ima3Du1* im0, ima3Dd *imres[])
00325 {
00326     // For attribute computation
00327     GlcmData glcmData;
00328 
00329     // For evaluating speed performance
00330     unsigned long total_iterations;
00331     unsigned long iterations_per_tick;
00332     unsigned long total_ticks, tick;
00333     double tick_percent, percent;
00334     struct timeval tv;
00335     double tick_start_time, tick_end_time;
00336     unsigned long estimated_time;
00337     int hours, minutes, seconds;
00338 
00339     // Calculate the limits for x, y and z depending on the size of the direction vector
00340     int xMin, xMax, yMin, yMax, zMin, zMax;
00341     if (des->winx > 0) {
00342         xMin = 0; // min limit is given by the image
00343         xMax = im0->dimx - des->winx - des->dx; // max limit is given by the direction vector
00344     } else {
00345         xMin = des->dx; // min limit is given by the direction vector
00346         xMax = im0->dimx - des->winx; // max limit is given by the image
00347     }
00348     if (des->winy > 0) {
00349         yMin = 0; // min limit is given by the image
00350         yMax = im0->dimy - des->winy - des->dy; // max limit is given by the direction vector
00351     } else {
00352         yMin = des->dy; // min limit is given by the direction vector
00353         yMax = im0->dimy - des->winy;
00354     }
00355     if (des->winz > 0) {
00356         zMin = 0; // min limit is given by the image
00357         zMax = im0->dimz - des->winz - des->dz; // max limit is given by the direction vector
00358     } else {
00359         zMin = des->dz; // min limit is given by the direction vector
00360         zMax = im0->dimz - des->winz; // max limit is given by the image
00361     }
00362 
00363     //Calculate the relative position of the output image
00364     int xPos, yPos, zPos;
00365     xPos = (des->winx + des->dx) / 2;
00366     yPos = (des->winy + des->dy) / 2;
00367     zPos = (des->winz + des->dz) / 2;
00368     
00369     //Attributes Computation
00370 
00371     // Speed performance measuring
00372     // There are 6 loops: dimx, dimy, dimz
00373     // One tick is one iteration of the loop dimy, so there will be a total of aprox dimx * dimy ticks
00374 
00375     // Speed performance measuring variables
00376     iterations_per_tick = (zMax - zMin); // dimz
00377     total_ticks = (xMax - xMin) * (yMax - yMin); // dimx * dimy
00378     
00379     total_iterations = iterations_per_tick * total_ticks;
00380     tick_percent = 100 / (double)total_ticks; // =aprox 100/(dimx * dimy)
00381     percent = 0;
00382     tick = 0;
00383     gettimeofday(&tv, 0);
00384     tick_start_time = tv.tv_sec + tv.tv_usec/1000000.;
00385 
00386     // Actual attributes computation
00387 #ifdef with_curses
00388     initscr();
00389     mvprintw(2, 0, "Attributes Computation started on %s", ctime(&tv.tv_sec));
00390     refresh();
00391 #endif
00392  
00393     int row, col;
00394     int x, y, z;
00395     
00396 
00397     // First step init
00398     initGlcmData(&glcmData);
00399     for(z = zMin; z < zMin + des->winz; z ++)
00400         for(y = yMin; y < yMin + des->winy; y ++)
00401             for(x = xMin; x < xMin + des->winx; x ++) {
00402                 row = im0->data[z][y][x];
00403                 col = im0->data[z + des->dz][y + des->dz][x + des->dz];
00404                 glcmData.Matcoocur[row][col]++;
00405             }
00406 
00407     for(row = 0; row < 256; row++)
00408         for(col = 0; col < 256; col++)
00409             valueUpdateGlcmData(row, col, 0, glcmData.Matcoocur[row][col], &glcmData, des);
00410             
00411     int xIncrement = -1, yIncrement = -1;
00412     int xStart, xEnd;
00413     int yStart, yEnd;
00414     int xAddStart, xAddEnd, xSubStart, xSubEnd;
00415     int yAddStart, yAddEnd, ySubStart, ySubEnd;
00416     int zAddStart, zAddEnd, zSubStart, zSubEnd;
00417     
00418     int wx, wy, wz;
00419             
00420     xAddStart = 0;
00421     xSubStart = 0;
00422     xAddEnd = -1;
00423     xSubEnd = -1;
00424     yAddStart = 0;
00425     ySubStart = 0;
00426     yAddEnd = -1;
00427     ySubEnd = -1;
00428     zAddStart = 0;
00429     zAddEnd = 0;
00430     zSubStart = - 1;
00431     zSubEnd = -1;
00432     
00433                 FILE *f;
00434                 f = fopen("nonZeros.dump", "w");
00435     z = zMin;
00436     while(1) { // Loop exit is made trough a break statement
00437         // Togle y axis advance direction (snake-like iteration trough the image)
00438         if (yIncrement == -1) {
00439             yIncrement = +1;
00440             yStart = yMin;
00441             yEnd = yMax;
00442         } else {
00443             yIncrement = -1;
00444             yStart = yMax - 1;
00445             yEnd = yMin - 1;
00446         }
00447 
00448         y = yStart;
00449         while(1) { // Loop exit is made trough a break statement
00450             // Togle x axis advance direction (snake-like iteration trough the image)
00451             if (xIncrement == -1) {
00452                 xIncrement = +1;
00453                 xStart = xMin;
00454                 xEnd = xMax;
00455             } else {
00456                 xIncrement = -1;
00457                 xStart = xMax - 1;
00458                 xEnd = xMin -1;
00459             }
00460 
00461             x = xStart;
00462             while(1) { // Loop exit is made trough a break statement
00463                 // Substract the contribution of pixels not anymore part of the window
00464                 for (wz = zSubStart; wz < zSubEnd; wz++)
00465                     for (wy = ySubStart; wy < ySubEnd; wy++)
00466                         for (wx = xSubStart; wx < xSubEnd; wx++)
00467                             pixelUpdateGlcmData(wx, wy, wz, -1, &glcmData, im0, des);
00468                 
00469                 // Add the contribution of those pixels new to the window
00470                 for (wz = zAddStart; wz < zAddEnd; wz++)
00471                     for (wy = yAddStart; wy < yAddEnd; wy++)
00472                         for (wx = xAddStart; wx < xAddEnd; wx++)
00473                             pixelUpdateGlcmData(wx, wy, wz, +1, &glcmData, im0, des);
00474                 
00475 //                 fprintf(f, "%d\n", glcmData.nonZeros);
00476                 int i;
00477                 for (i = 0; i < total_attributes; i++)
00478                     if (des->do_output[i])
00479                         imres[i]->data[z + zPos][y + yPos][x + xPos] = attributes[i].finalize(&glcmData);
00480                         
00481                 if (x + xIncrement == xEnd) // will there be a next iteration of this loop?
00482                     break;
00483                 else {
00484                     if (xIncrement == +1) {
00485                         xAddStart = x + des->winx;
00486                         xAddEnd = x + des->winx + 1;
00487                         xSubStart = x;
00488                         xSubEnd = x + 1;
00489                     } else {
00490                         xAddStart = x - 1;
00491                         xAddEnd = x;
00492                         xSubStart = x + des->winx - 1;
00493                         xSubEnd = x + des->winx;
00494                     }
00495                     yAddStart = ySubStart = y;
00496                     yAddEnd = ySubEnd = y + des->winy;
00497                     zAddStart = zSubStart = z;
00498                     zAddEnd = zSubEnd = z + des->winz;
00499                     x += xIncrement;
00500                 }
00501             }
00502             // Speed performance measuring logic
00503             gettimeofday(&tv, 0);
00504             tick ++;
00505             tick_end_time = tv.tv_sec + tv.tv_usec/1000000.;
00506             percent += tick_percent;
00507             estimated_time = (total_ticks - tick) * (tick_end_time - tick_start_time);
00508             hours = estimated_time / (60 * 60);
00509             estimated_time %= (60 * 60);
00510             minutes = estimated_time / 60;
00511             seconds = estimated_time % 60;
00512 #ifdef with_curses
00513             mvprintw(3, 0,
00514                     "Attributes Computation: %06.2f %%, %012.2f iterations/sec, %03d:%02d:%02d estimated time remaning",
00515                     (float)percent,
00516                     iterations_per_tick / (tick_end_time - tick_start_time),
00517                     hours,
00518                     minutes,
00519                     seconds
00520                 );
00521             refresh();
00522 #endif
00523             tick_start_time = tick_end_time;
00524             
00525             if (y + yIncrement == yEnd) // will there be a next iteration of this loop?
00526                 break;
00527             else {
00528                 if (yIncrement == +1) {
00529                     yAddStart = y + des->winy;
00530                     yAddEnd = y + des->winy + 1;
00531                     ySubStart = y;
00532                     ySubEnd = y + 1;
00533                 } else {
00534                     yAddStart = y - 1;
00535                     yAddEnd = y;
00536                     ySubStart = y + des->winy - 1;
00537                     ySubEnd = y + des->winy;
00538                 }
00539                 xAddStart = xSubStart = x;
00540                 xAddEnd = xSubEnd = x + des->winx;
00541                 zAddStart = zSubStart = z;
00542                 zAddEnd = zSubEnd = z + des->winz;
00543                 y += yIncrement;
00544             }
00545         }
00546         
00547         if (z + 1 >= zMax) // will there be a next iteration of this loop?
00548             break;
00549         else {
00550             zAddStart = z + des->winy;
00551             zAddEnd = z + des->winy + 1;
00552             zSubStart = z;
00553             zSubEnd = z + 1;
00554             xAddStart = xSubStart = x;
00555             xAddEnd = xSubEnd = x + des->winx;
00556             yAddStart = ySubStart = y;
00557             yAddEnd = ySubEnd = y + des->winy;
00558             z++;
00559         }
00560     }
00561 
00562     gettimeofday(&tv, 0);
00563 #ifdef with_curses
00564     mvprintw(10, 0, "Exit on %s", ctime(&tv.tv_sec));
00565     refresh();
00566     endwin();
00567 #endif
00568 fclose(f);
00569                 
00570     return(0);
00571 }
00572 
00573   /* fin doc en sous partie */

Generated on Tue Apr 22 13:31:06 2008 for volume by  doxygen 1.5.3