21/7/11

Error

Por alguna extraña razón ahora nadie puede comentar mis entradas :( ni yo mismo jaja. XD xD

19/7/11

Visión Computacional y Procesamiento de imágenes

Comenzaré a publicar todo acerca de los temas en los que estaré trabajando este verano científico, a continuación explico el concepto y aplicaciones  de la visión computacional y el procesamiento de imágenes.

Para empezar ¿Qué es visión ?

Algunos autores la definen como la capacidad que tiene el ojo humano para percibir nuestro entorno para despues ser interpretada por el cerebro.

Cito algunas definiciones :

  • Visión es saber que hay y dónde  mediante la vista. (Aristóteles)
  • Visión es un proceso  que produce a partir de imágenes del mundo exterior una descripción que es util al observador y que no tiene información irrelevante. (Marr)
Entonces la visión computacional  trata de emular esa capacidad  mediante herramientas computacionales que prodían ser camaras que captan la información del exterior y su posición espacial para despues reconocerlos e interpretarlos.

Por otro lado un área muy ligada a la visión computacional es el procesamiento de imágenes , pues ambos campos tienen mucho en común pero el objetivo final es otro, pues el procesamiento de imágenes esta orientado a MEJORAR la calidad de  las imágenes  para su posterior interpetración por una persona y la visión computacional trata de obtener atributos y descripciones para tratar de interpretar la imagen automaticamente.


Entonces concluimos que visión computacional va orientado a tratar de interpretar la imagén que percibe por sí misma y  el procesamiento de imágenes va destinado a mejorar la imagen para su posterior interpretación por una persona.

Aplicaciones:

*Visión Computacional
  • Reconocimiento de objetos y formas en una imagen.
  • Analizar objetos para determinar su calidad.
  • Descomposición de objetos en sus partes.

*Procesamiento de imágenes
  •  Remover defectos de una imagen.
  • Aumentar carácteristicas de una imagen (color ,contraste, estrutura).
  • Agregar colores y convertir imágenes monocromáticas.

Referencias Bibliográficas.

Libro  Procesamiento de Imágenes y Visión Computacional,  Enrique Sucar y Giovani Gómez.

Verano Científico

Este blog fue creado con el objetivo de subir tareas y avances de la materia "Lenguaje  ANSI-C" que impartió la Dra. Schaeffer durante el verano en la Facultad de Ingeniería Mecánica y Eléctrica(FIME) de la Universidad Autónoma de Nuevo León (UANL) a la cuál tuve la oportunidad de entrar como oyente. Todo esto debido a que estoy realizando la estadía del Verano Científico  en la UANL que tiene como meta acercar y motivar  a alumnos de nivel licenciatura a estudiar un posgrado .  Una de las actividades principales es la realización de una investigación  bajo la supervisión de un investigador,  en mi caso estaré supervisado por él M.C. David J. Ríos y asu vez también por la Dra. Elisa Schaeffer.

Entonces de ahora en adelante cambiará el enfoque de este blog pues ahora estaré subiendo entradas acerca de la investigación que realizaré.  Saludos y buenas noches.

14/7/11

Videos sobre Punteros

Les comparto este video que tomé de youtube donde explica lo más básico sobre punteros, como se declara, que imprime puntero,&puntero y *puntero, aunque es para el lenguaje c++ ,ansi c es muy parecido , es de gran ayuda para nosotros que apenas ingresamos al mundo de la programación. Agradecimientos al autor del video .Espero les sea de utilidad.

Arboles..

Para realizar la operación de borrado , se tienen que tener en consideracion varios cosas:



Borrar un nodo sin hijos ó nodo hoja: Simplemente se borra y se establece a nulo el apuntador

de su padre.

Borrar un nodo con un subárbol hijo: se borra el nodo y se asigna su subárbol hijo como subárbol de su padre.

Borrar un nodo con dos subárboles hijo: la solución está en reemplazar el valor del nodo por el

de su predecesor o por el de su sucesor en inorden y posteriormente borrar este nodo. Su predecesor en
inorden será el nodo más a la derecha de su subárbol izquierdo (mayor nodo del subarbol izquierdo), y su sucesor el nodo más a la izquierda de
su subárbol derecho (menor nodo del subarbol derecho).Aunque en realidad aún no he podido implementarlo =(.. pues el codigo no hace lo que debería.

Toda esta información la encontré en wikipedia. http://es.wikipedia.org/wiki/%C3%81rbol_binario_de_b%C3%BAsqueda


#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "bool.h"

#define DEBUG 1

// NOTA: faltan implementar las rotaciones
// dobles; por ahora no balancea bien

// un nodo de ruteo no cuenta duplicados
#define NO_VALIDO -1


  int next = 0;


struct nodo_de_arbol {
  char dato;
  int altura;
  int contador;

  int id;

  struct nodo_de_arbol* padre;
  struct nodo_de_arbol* izq; // hijo
  struct nodo_de_arbol* der; // otro hijo
};
typedef struct nodo_de_arbol nodo;

void borra(nodo* n) {
  if (n == NULL) {
    return;
  } else {
    borra(n->izq);
    borra(n->der);
    free(n);
  }
  return;
}

void muestra(nodo* n) {
  if (n == NULL) {
    return; // caso base de recursion
  } else {
    muestra(n->izq);

    if (n->izq != NULL && n->der != NULL) {
      printf("[%c, %d <%d / %d, %d>] ", 
         n->dato, n->altura, n->id,
         n->izq->id, n->der->id);
    } else {
      printf("(%c, %d <%d> #%d) ", 
         n->dato, n->altura, n->id,
         n->contador);
    }

    if (n->izq == NULL && n->der == NULL) {
      printf("%c[%d] ", n->dato, n->contador);
    }

    muestra(n->der);
  }
  return;
}
void elimina(nodo* n,nodo** raiz){
nodo-> NULL; 
}
void balancea(nodo* n, nodo** raiz) {
  int ai, ad, max, min, aalt, balt;
  nodo* t = NULL;
  nodo* u = NULL;
  nodo* v = NULL;
  nodo* a = NULL;
  nodo* b = NULL;
  nodo* p = NULL;
  nodo* x1 = NULL;
  nodo* x2 = NULL;

  if (n == NULL) {

    printf("Ya topamos con la raiz.\n");

    return;
  }
  if (n->izq == NULL ||
      n->der == NULL) {

    printf("No se puede sin hijos.\n");

    return;
  }
  
  t = n; // nodo actual
  assert(t != NULL);
  

  printf("Checando balance en %c (alt. %d).\n",
     t->dato, t->altura);


  u = n->izq; // hijo izquierdo
  assert(u != NULL);
  v = n->der; // hijo derecho
  assert(v != NULL);

  ai = u->altura;
  ad = v->altura;


  printf("Hijos %c (alt. %d) y %c (alt. %d).\n",
     u->dato, ai, v->dato, ad);


  max = (ai > ad) ? ai : ad;
  min = (ai > ad) ? ad : ai;

  if (max + 1 != t->altura) {
    t->altura = max + 1; // actualizar altura
  }

  if (max - min > 1) { // balancear
    p = t->padre; // padre del actual


    printf("%c a altura %d requiere balanceo.\n", 
       t->dato, t->altura);
    printf("Entrando tenemos:\n");
    if (p != NULL) {
      printf("p = %d, ", p->id);
    } else {
      printf("p = NULL, ");
    }
    printf("t = %d, \n", t->id);
    printf("u = %d, v = %d, \n", 
       u->id, v->id);

    
    if (ai <= ad - 2) { 
      // si hay demasiada altura a la der
      // => voltear "peso" hacia la izq.
      a = v->izq;
      b = v->der;
      assert(a != NULL);
      assert(b != NULL);
      aalt = a->altura;
      balt = b->altura;
      

      printf("a = %d, b = %d, \n", 
         a->id, b->id);


      if (aalt <= balt) { // rotacion simple izq
    printf("Simple izquierda.\n");
    if (p != NULL) {
      // v debe reemplazar a t como hijo
      if (p->izq == t) {
        p->izq = v;
      } else { // era derecho 
        p->der = v;
      }
    } else {
      // v es ahora raiz
      *raiz = v;
    }
    // el padre de t sera padre de v
    v->padre = p;
    // printf("Arreglado hacia arriba.\n");
    
    // v ahora es hijo izq de t
    // t es padre de v
    v->izq = t;
    t->padre = v;
    // el hijo der de t no cambia
    // printf("Arreglado entre t y v.\n");
    
    // a va a ser hijo derecho de t
    // t va a ser padre de a
    t->der = a;
    a->padre = t;
    // printf("Arreglado entre a y t.\n");


    if (p != NULL) {
      printf("v = %d es hijo de p = %d,\n",
         v->id, p->id);
    }
    printf("t = %d = %d es hijo de v = %d,\n",
           t->id, v->izq->id, v->id);
    printf("a = %d = %d es hijo de t = %d\n",
           a->id, t->der->id, t->id);
    printf("b = %d = %d es hijo de v = %d,\n",
           b->id, v->der->id, v->id);
    printf("u = %d = %d es hijo de t = %d.\n",
           u->id, t->izq->id, t->id);

    // para ni u ni b nada cambia
      } else { 
    printf("Simple derecha-izquierda.\n");
    x1 = a->izq;
    assert(x1 != NULL);
    x2 = a->der;
    assert(x2 != NULL);
    
    if (p != NULL) {
      if (p->izq == t) {
        p->izq = a; // w
      } else { // era der.
        p->der = a;
      }
    } else { // t era raiz
      *raiz = a; // avisar main
    }
    v->padre = a;
    a->der = v;
    t->padre = a;
    a->izq = t;
    v->izq = x2;
    x2->padre = v;
    t->der = x1;
    x1->padre = t;
      }
    } else if (ai >= ad + 2) {
      // voltear hacia la derecha
      a = u->izq;
      b = u->der;
      assert(a != NULL);
      assert(b != NULL);
      aalt = a->altura;
      balt = b->altura;
      if (aalt >= balt) { 
    printf("Simple derecha.\n");
    if (p != NULL) {
      if (p->izq == t) {
        p->izq = u;
      } else { // era derecho 
        p->der = u;
      }
    } else {
      // cambiando la raiz para ser u
      *raiz = u;
    }
    u->padre = p;
    // printf("Arreglado hacia arriba.\n");
    u->der = t;
    t->padre = u;
    // printf("Arreglado entre t y u.\n");
    t->izq = b;
    b->padre = t;
    // printf("Arreglado entre b y t.\n");
      } else { // (aalt < balt)
    printf("Doble izquierda derecha.\n");
    x1 = b->izq;
    assert(x1 != NULL);
    x2 = b->der;
    assert(x2 != NULL);
    
    if (p != NULL) {
      if (p->izq == t) {
        p->izq = b; // w
      } else { // era der.
        p->der = b;
      }
    } else { // t era raiz
      *raiz = b; // avisar main
    }
    u->padre = b;
    b->izq = u;
    t->padre = b;
    b->der = t;
    u->der = x1;
    x1->padre = u;
    t->izq = x2;
    x2->padre = t;
      }
    }
    if (p != NULL) {
      balancea(p, raiz);
    }
  } else {

    printf("%c esta bien (%d vs. %d).\n", 
       n->dato, ai, ad);

    // siempre checa hasta la raiz
    balancea(n->padre, raiz);
  }
  return;
}

bool agrega(char dato, nodo* arbol, nodo** n) {
  nodo* nuevo;
  nodo* reemplazo;
  char ruteo;
  if (arbol == NULL) {
    // caso especial de no tener nada aun
    nuevo = (nodo*)malloc(sizeof(nodo));
    nuevo->contador = 1;

    nuevo->id = next++;

    nuevo->altura = 1; // como hoja
    nuevo->dato = dato;
    nuevo->padre = NULL;
    nuevo->izq = NULL;
    nuevo->der = NULL;
    *n = nuevo; // nueva raiz
    return TRUE;
  } else {
    if (arbol->izq == NULL &&
    arbol->der == NULL) { // si es hoja

      if (arbol->dato == dato) {
    // iguales; agregar duplicidad
    arbol->contador++;
    return FALSE;
      }
      

      printf("Agregando %c en %c.\n",
         dato, arbol->dato);

      
      ruteo = (arbol->dato < dato ? 
           arbol->dato : dato);
      
      nuevo = (nodo*)malloc(sizeof(nodo));
      nuevo->contador = 1;

      nuevo->id = next++;

      nuevo->altura = 1; // como hoja
      nuevo->dato = dato;
      nuevo->padre = arbol;
      nuevo->izq = NULL;
      nuevo->der = NULL;

      reemplazo = (nodo*)malloc(sizeof(nodo));
      reemplazo->contador = arbol->contador;
      arbol->contador = NO_VALIDO;

      reemplazo->id = next++;

      reemplazo->altura = 1; // como hoja
      reemplazo->dato = arbol->dato;
      reemplazo->padre = arbol;
      reemplazo->izq = NULL;
      reemplazo->der = NULL;

      if (dato < arbol->dato) {
    arbol->izq = nuevo;
    arbol->der = reemplazo;
      } else if (dato > arbol->dato) {
    arbol->der = nuevo;
    arbol->izq = reemplazo;
      }

      arbol->dato = ruteo;
      arbol->altura = 2;
      balancea(arbol->padre, n);
    } else {
      if (dato <= arbol->dato) {
    agrega(dato, arbol->izq, n);
      } else { // mayor
    agrega(dato, arbol->der, n);
      }
    }
  }
  return TRUE;
}

int main(int argc, char** args) {
  nodo* raiz = NULL;
  char dato;
  int contador = 0;

  do {
    dato = getchar(); // lee un caracter
    if (!isspace(dato)) {
      if (agrega(dato, raiz, &raiz)) {
    contador++;
      }
      if (raiz != NULL) {
    printf("\nCon %d nodos, altura %d: \n",
           contador, raiz->altura);
    muestra(raiz);
    printf("\n");
      } else {
    printf("No hay nada.\n");
      }
    }
  } while (dato != '!'); // parar despues de !
  borra(raiz);

  return 1;
}

12/7/11

Tarea 5 : Pilas y Colas

La tarea consiste en reutilizar el codigo que se nos proporcionó en clase, para realizarle modificaciones para que funcionara como una pila y una cola.

En clase utilizamos el codigo : listas.c, el cual ordenaba de menor a mayor los datos ingresados, esta funcionalidad no es necesaria en una pila, pues una pila es una estructura en la cual el primer elemento es ingresar es el ultimo en salir y viceversa. En realidad la modificación era quitarle la parte que ordenaba de menor a mayor.

#include  <stdio.h>

#include  // imprimir (printf)
#include  // reservar memoria
#include "listas.h"

// eliminar todos los elementos de la lista
// opcion vaciar
elem* borrar(elem* esto) {
  elem* temp; // auxiliar 
  // iterativa
  while (esto != NULL) {
    temp = esto->siguiente;
    free(esto); // liberar
    esto = temp; // avanza al siguinte
  }
  return NULL; // que ya no hay lista
}

// checar si la lista contiene un valor dado
// devuelve verdad o falso
// recibe un puntero a un elemento de la lista
// implementacion recursiva
bool buscar(int valor, elem* aqui) {
  if (aqui != NULL) {

    //#define DEBUG
#ifdef DEBUG 
    printf("Buscando por %d en %d.\n", 
    valor, aqui->dato);
#endif // hasta aqui si no esta definido DEBUG

    // si el valor buscado esta en este elemento
    if (aqui->dato == valor) {

#ifdef DEBUG
      printf("Son iguales.\n");
#endif

      return TRUE; // busqueda exitosa

    } else if (aqui->dato > valor) {
      // ojo: lista esta ordenada de menor
      // a mayor (por construccion a traves
      // de la implementacion del metodo
      // insertar(...)

#ifdef DEBUG
      printf("Ya es mayor. No va a estar.\n");
#endif

      return FALSE; // busqueda fallida
    }
    // pasar la pelota al siguiente elemento
    return buscar(valor, aqui->siguiente);
  } else { // aqui es null
    // este elemento actual ya es null, o sea,
    // no en realidad es un elemento

#ifdef DEBUG
    printf("Ya se acabo. No estuvo.\n");
#endif
    return FALSE; // busqueda fallida
  }
}

// devuelve si o no se pudo eliminar
// (no se puede eliminar si no esta)
// valor cuyo elemento hay que eliminar
// (unicamente elimina el primer elemento
// cuyo valor coincide)
// elemento en el cual estamos buscando = aqui
// direccion del inicio de la lista
bool eliminar_elemento(int valor, elem* aqui, 
         elem** inicio) {
  if (aqui != NULL) { // si hay algo
    if (aqui->dato == valor) {
      // hay que borrar el elemento
      if (aqui->siguiente != NULL) {
 aqui->siguiente->anterior = 
   aqui->anterior; 
      }
      if (aqui->anterior == NULL) {
 *inicio = aqui->siguiente;
      } else {
 aqui->anterior->siguiente = 
   aqui->siguiente;
      }
      free(aqui); // borrame
      return TRUE; // eliminacion exitosa
    } else if (aqui->dato > valor) {
      return FALSE;
    }
    return eliminar_elemento(valor, 
        aqui->siguiente, 
        inicio);
  }
  return FALSE;
}

// interface para llamadas mas bonitas
bool eliminar(int valor, elem** inicio) {
  return 
    eliminar_elemento(valor, *inicio, inicio);
}

void imprime_elemento(elem* esto) {
  // iterativa
  while (esto != NULL) {
    printf("%d ", esto->dato);
    esto = esto->siguiente;
  }
  return;
}

// interfase que agrega [ ... ] y el \n
void imprimir(elem* lista) {
  printf("[ ");
  imprime_elemento(lista);
  printf("]\n");
  return;
}

// agregar un elemento en la posicion que
// le corresponde (valores de menor a mayor)
elem* insertar(int valor, elem* aqui) {
  elem* nuevo = NULL; // auxiliar
  // para crear el nuevo elemento
 
  //#ifdef DEBUG
  if (aqui != NULL) {
    printf("Estoy en %d, insertando un %d.\n",
    aqui->dato, valor);
  } else {
    printf("No hay nada.\n");
  }
  //#endif
 
  if (aqui == NULL) { // no hay nadie
    nuevo = (elem*)malloc(sizeof(elem));
    nuevo->dato = valor; // asignar dato
    nuevo->siguiente = NULL; // el unico
    nuevo->anterior = NULL; // el unico
    return nuevo;
  } else {
    //if (valor < aqui->dato) {
      nuevo = (elem*)malloc(sizeof(elem));
      nuevo->dato = valor; // pon el valor
      //if (aqui->anterior == NULL) {
 // aqui es el primer elemento
 nuevo->siguiente = aqui;
 aqui->anterior = nuevo;
 nuevo->anterior = NULL; 
 return nuevo;
 /*} else { // un chorro de flechas
 nuevo->anterior = aqui->anterior;
 nuevo->siguiente = aqui;
 nuevo->anterior->siguiente = nuevo;
 aqui->anterior = nuevo;
      }
    } else { // ni igual ni mayor
#ifdef DEBUG
      printf("Insertando algo mayor.\n");
#endif
      // implementacion recursiva
      if (aqui->siguiente != NULL) {
 insertar(valor, aqui->siguiente);
      } else { // este es el ultimo elemento
#ifdef DEBUG
 printf("Anexando al final.\n");
#endif
 nuevo = (elem*)malloc(sizeof(elem));
 nuevo->dato = valor;
 nuevo->siguiente = NULL; // el ultimo
 nuevo->anterior = aqui;
 aqui->siguiente = nuevo;
      }
    }
  }
  return aqui;
}
 */
// numeros pseudoaleatorios [MIN, MAX]
int pseudoaleatorio() {
  return ((rand() % (MAX - MIN + 1)) + MIN);
}
  }
}

7/7/11

+ Sobre Ciclos

Ahora utilizaré un ciclo for, para pedir las calificaciones de las materias para realizar un promedio.

Este Programa calcula el promedio. El usuario introduce la cantidad de materias y la calificación.

#include  <stdio.h>


int main(int argc, char** args){

  int a,c,x,ma;
  float p=0;

  printf("Programa que calcula el promedio de x cantidad de materias\n");
  printf("Dame el numero de materias de las cuales quieres obtener el promedio\n");
  scanf("%d",&x);
  c=getchar();
  ma=x;

  for(a=1;a<=ma;a++){
    printf("Dame la calificacion de la materia %d\n",a);
    scanf("%d",&x);
    c=getchar();
    p=p+x;
      

  }
  p=p/ma;

  printf("Tu promedio es de: %f\n",p);  

  return 1;

}

Serie de Fibonacci..

Aunque en realidad no es nada nuevo ,decidí agregarlo al blog pues ya he logrado realizarla sin conexion a internet , sin libros y apuntes. Ya hay mejora y eso es motivante. Saludos
#include 

int main (int argc, char** args){

int ap,p,a,c;// Inicializamos los valores antepasado,pasado, actual y un contador
printf("La serie fibonacci consiste en una secuencia de números \n");
printf("de tal forma que el valor siguiente en la serie es la suma\n");
printf("de sus dos valores anteriores,la serie empieza con 0 y 1\n");
printf("--Este programa determinara los primeros 20 valores de la serie--\n");
ap=0; // Valor antepasado de la serie que seria el 0
p=1; // Valor pasado de la serie es 1 


printf("%d\n",ap);
printf("%d\n",p);
for(c=2; c<=20; c++){

a=ap + p;
ap = p;
p= a;

printf("%d \n",a);


}

return 1; 
}