00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "jed_defs.h"
00025
00026
00027
00028 #include <stdio.h>
00029 #include <string.h>
00030 #include <stdlib.h>
00031
00032 #ifdef MOTIF_ENABLED // Librerias X Window System
00033 #include <Xm/Xm.h>
00034 #endif
00035
00036 #include "jed_gl.h"
00037
00038 #include "toolkits/media/jed_img.h"
00039
00040 #undef GL_COMPLETO
00041
00042
00043
00044
00045
00046 #define RANGO(a,b,c) { if (a < b) a = b; if (a > c) a = c; }
00047
00048 void
00049 calcular_funcion_gamma(BYTE funcion_gamma[256], double factor)
00050 {
00051 int i, j;
00052 double y, invgam;
00053
00054 if (factor < 0.0) {
00055 invgam = 1.0 / -factor;
00056 for (i=0; i<256; i++) {
00057 y = pow( ((double) i / 255.0), invgam) * 255.0;
00058 j = (int) floor(y + 0.5);
00059 RANGO(j,0,255);
00060 funcion_gamma[255-i] = j;
00061 }
00062 }
00063 else if (factor > 0.0) {
00064 invgam = 1.0 / factor;
00065 for (i=0; i<256; i++) {
00066 y = pow( ((double) i / 255.0), invgam) * 255.0;
00067 j = (int) floor(y + 0.5);
00068 RANGO(j,0,255);
00069 funcion_gamma[i] = j;
00070 }
00071 }
00072 else {
00073 for (i=0; i<256; i++) funcion_gamma[i] = 0;
00074 }
00075 }
00076
00077
00078
00079
00080
00081 IMAGEN::IMAGEN()
00082 {
00083
00084 }
00085
00086 IMAGEN::~IMAGEN()
00092 {
00093
00094 }
00095
00096 #ifdef NNN
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110 BOOLEAN
00111 IMAGEN::importar_ppm(FILE *fd)
00118 {
00119 #ifdef NONONO
00120 int xtam = 0, ytam = 0;
00121 int i, j;
00122 char buffer[MAX_LINE + 1];
00123 char *ptr = NULL;
00124 PIXEL_RGB pixel;
00125
00126 if ( !fd ) {
00127 fprintf(stderr, "ERROR: No se puede abrir el archivo.");
00128 fflush(stderr);
00129 return FALSE;
00130 }
00131
00132
00133 for ( i = 0; !feof(fd); i++ ) {
00134 if ( i >= MAX_LINE ) i = 0;
00135 fread(&buffer[i], sizeof(BYTE), 1, fd);
00136 buffer[i + 1] = '\0';
00137 if ( buffer[i] == '\n' && strcmp(buffer, "255\n") == 0 ) {
00138 break;
00139 }
00140 else if ( buffer[i] == '\n' ) {
00141 ptr = strtok(buffer, " \n");
00142 if ( ptr ) {
00143 xtam = atoi(ptr);
00144 ptr = strtok(NULL, " \n");
00145 if ( ptr ) {
00146 ytam = atoi(ptr);
00147 }
00148 }
00149 i = -1;
00150 }
00151 }
00152
00153 if ( xtam <= 0 || xtam > 2024 || ytam <=0 || ytam > 2024 ) {
00154 fprintf(stderr, "Imagen con tamanno %d X %d no aceptada.\n",
00155 xtam, ytam);
00156 fflush(stderr);
00157 return FALSE;
00158 }
00159
00160 if ( !init(xtam, ytam) ) {
00161 return FALSE;
00162 }
00163
00164
00165
00166 PIXEL_RGB *fila;
00167
00168 for ( i = y_tam - 1; i >= 0 ; i-- ) {
00169 fila = &((PIXEL_RGB *)Data)[i*x_tam];
00170 for ( j = 0; j < x_tam ; j++ ) {
00171 fread(&pixel, sizeof(PIXEL_RGB), 1, fd);
00172
00173
00174
00175
00176 fila[j] = pixel;
00177 }
00178 }
00179
00180 #endif
00181 return TRUE;
00182 }
00183
00184
00185
00186
00187
00188 IM_HISTOGRAMA::IM_HISTOGRAMA()
00189 {
00190 int i;
00191
00192 for ( i = 0; i < 256; i++ ) {
00193 data[i] = 0;
00194 }
00195 }
00196
00197 void
00198 IM_HISTOGRAMA::calcule(IMAGEN_PAL &imagen_grises)
00199 {
00200 int x, y;
00201 BYTE index;
00202
00203 for ( x = 0; x < imagen_grises.xtam(); x++ ) {
00204 for ( y = 0; y < imagen_grises.ytam(); y++ ) {
00205 index = imagen_grises.getcolorindex(x, y);
00206 data[index % 256]++;
00207 }
00208 }
00209 }
00210
00211 #ifdef GL_ENABLED
00212 void
00213 IM_HISTOGRAMA::pintar_gl(BYTE umbral)
00218 {
00219
00220 glMatrixMode(GL_PROJECTION); glPushMatrix();
00221 glLoadIdentity();
00222 glMatrixMode(GL_MODELVIEW); glPushMatrix();
00223 glLoadIdentity();
00224
00225
00226
00227
00228 int i;
00229 long max = 0;
00230 double x1 = -0.9, x2 = 0.9, y1 = -0.8, y2 = 0.8;
00231
00232 for ( i = 0; i < 256; i++ ) {
00233 if ( data[i] > max ) max = data[i];
00234 }
00235
00236
00237 glColor3f(1, 0, 0);
00238 glBegin(GL_LINES);
00239 for ( i = 0; i < 256; i++ ) {
00240 glVertex2d(x1 + (double)i/256, y1);
00241 glVertex2d(x1 + (double)i/256, y1 + ((double)data[i])/((double)max));
00242 }
00243 glEnd();
00244
00245 glColor3f(1, 1, 0);
00246 glBegin(GL_LINES);
00247 glVertex2d(x1, y1); glVertex2d(x1, y2);
00248 glVertex2d(x1, y1); glVertex2d(x2, y1);
00249 glEnd();
00250
00251 if ( umbral > 0 && umbral < 255 ) {
00252 glColor3f(0, 1, 0);
00253 glBegin(GL_LINES);
00254 glVertex2d(x1 + (double)umbral/256, y1);
00255 glVertex2d(x1 + (double)umbral/256, y2);
00256 glEnd();
00257 }
00258
00259
00260 glMatrixMode(GL_MODELVIEW); glPopMatrix();
00261 glMatrixMode(GL_PROJECTION); glPopMatrix();
00262 glMatrixMode(GL_MODELVIEW);
00263 }
00264 #endif
00265
00266 void
00267 IM_HISTOGRAMA::imprima(void)
00268 {
00269 int i;
00270
00271 for ( i = 0; i < 256; i++ ) {
00272
00273
00274
00275 printf("%ld\n", data[i]);
00276 }
00277 fflush(stdout);
00278 }
00279
00280 BYTE
00281 IM_HISTOGRAMA::generar_umbral_seleccion_iterativa(void)
00282
00283
00284
00285 {
00286 long i, told, umbral, a, b, c, d, N;
00287
00288
00289 umbral = 0; N = 0;
00290 for ( i = 0; i < 256; i++ ) {
00291 umbral += i * data[i];
00292 N += data[i];
00293 }
00294 umbral = (long)(umbral/(double)N);
00295
00296
00297 do {
00298 told = umbral;
00299 a = 0; b = 0;
00300 for ( i=0; i <= told; i++ ) {
00301 a += i*data[i];
00302 b += data[i];
00303 }
00304 b += b;
00305
00306 c = 0; d = 0;
00307 for ( i = told + 1; i < 256; i++ ) {
00308 c += i*data[i];
00309 d += data[i];
00310 }
00311 d += d;
00312
00313 if ( b == 0 ) b = 1;
00314 if ( d == 0 ) d = 1;
00315 umbral = a/b + c/d;
00316 } while ( umbral != told );
00317
00318 return (BYTE)umbral;
00319 }
00320
00321 BYTE
00322 IM_HISTOGRAMA::generar_umbral_otsu(void)
00330 {
00331 int min_index, max_index, i, umbral;
00332 double p[260], y, z, media_global, varianza_global;
00333 long N;
00334
00335 for ( i = 0, N = 0; i < 256; i++ ) N += data[i];
00336
00337
00338 for ( i = 0; i < 260; i++ ) p[i] = 0.0;
00339 for ( i = 1; i <= 256; i++ ) {
00340 p[i] = (double)data[i-1]/(double)N;
00341 }
00342
00343
00344
00345 media_global = otsu_u(p, 256);
00346 varianza_global = 0.0;
00347 for ( i = 1; i <= 256; i++ ) {
00348 varianza_global += (i-media_global) * (i-media_global) * p[i];
00349 }
00350
00351
00352
00353 for ( i = 1, min_index = -1, max_index = -1; i <= 256; i++ ) {
00354 if ( (min_index < 0) && (p[i] > 0.0) ) min_index = i;
00355 if ( p[i] > 0.0 ) max_index = i;
00356 }
00357
00358
00359 z = -1.0; umbral = 0;
00360 for ( i = min_index; i <= max_index; i++ ) {
00361 y = otsu_nu(p, i, media_global, varianza_global);
00362 if ( y >= z ) {
00363 z = y;
00364 umbral = i;
00365 }
00366 }
00367
00368 return (BYTE)umbral;
00369 }
00370
00371 double
00372 IM_HISTOGRAMA::otsu_u(double *p, int k)
00377 {
00378 int i;
00379 double x = 0.0;
00380
00381 for ( i = 1; i <= k; i++ ) x += (double)i * p[i];
00382 return x;
00383 }
00384
00385 double
00386 IM_HISTOGRAMA::otsu_w(double *p, int k)
00391 {
00392 int i;
00393 double x=0.0;
00394
00395 for ( i = 1; i <= k; i++ ) x += p[i];
00396 return x;
00397 }
00398
00399 double
00400 IM_HISTOGRAMA::otsu_nu(double *p,int k,double media_global,double varianza_global)
00401
00402
00403
00404 {
00405 double x, sum;
00406
00407 sum = otsu_w(p, k);
00408 x = media_global * sum - otsu_u(p, k);
00409 x = x * x;
00410 sum = sum * (1.0 - sum);
00411 if ( sum > 0 ) {
00412 x = x/sum;
00413 }
00414 else {
00415 x = 0.0;
00416 }
00417 return x / varianza_global;
00418 }
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 #endif // NNN
00430
00431
00432
00433
00434