Skip to content

Instantly share code, notes, and snippets.

@groteck
Created February 28, 2012 21:36
Show Gist options
  • Save groteck/1935318 to your computer and use it in GitHub Desktop.
Save groteck/1935318 to your computer and use it in GitHub Desktop.
aan
#include "ami.h"
#include "ami_bmp.h"
#include <stdio.h>
#include<stdlib.h>
#include<string.h>
// funcion que nos permite unir los canales de dos imagenes, separados por una línea negra de
//4 pixeles
void aan_unir_canales_unsigned_char(unsigned char *canal1, unsigned char *canal2,
unsigned char **canal_output, int width, int height){
int i,j,k;
//asignamos memoria a la nueva imagen
*canal_output=(unsigned char*)malloc((((2*width)+4)*height)*sizeof(unsigned char));
//EL indice que cada byte en el vector se calcula en función de la posición que tendria
//en la matriz
for (i=0;i<height;i++){
k=0;
for(j=0;j<width;j++){
(*canal_output)[(i*((2*width)+4))+k]=canal1[i*width+j];
k++;
};
for(j=0;j<4;j++){
(*canal_output)[(i*((2*width)+4))+k]=0;
k++;
};
for(j=0;j<width;j++){
(*canal_output)[(i*((2*width)+4))+k]=canal2[i*width+j];
k++;
};
};
};
void aan_unir_canales_float(float *canal1, float *canal2, float **canal_output, int
width, int height) {
int i,j,k;
//asignamos memoria a la nueva imagen
*canal_output=(float*)malloc((((2*width)+4)*height)*sizeof(float));
//EL indice que cada byte en el vector se calcula en función de la posición que tendria
//en la matriz
for (i=0;i<height;i++){
k=0;
for(j=0;j<width;j++){
(*canal_output)[(i*((2*width)+4))+k]=canal1[i*width+j];
k++;
};
for(j=0;j<4;j++){
(*canal_output)[(i*((2*width)+4))+k]=0;
k++;
};
for(j=0;j<width;j++){
(*canal_output)[(i*((2*width)+4))+k]=canal2[i*width+j];
k++;
};
};
};
// función que devuelve el valor máximo y mínimo de un canal
void maxmin(unsigned char *canal, int width,int height,int valores[]){
int i,j;
valores[0]=(canal)[0];
valores[1]=(canal)[0];
for(i=0;i<height;i++){
for(j=0;j<width;j++){
if((canal)[(i*width)+j] < (valores[0])){
valores[0]=(canal)[(i*width)+j];
};
if((canal)[(i*width)+j]>valores[1]){
valores[1]=(canal)[(i*width)+j];
};
};
};
};
// funcion que normaliza una imagen
void aan_normalizar_canal_unsigned_char(unsigned char *canal_input, unsigned char
**canal_output, int width, int height){
int valores[2],i,j;
float cociente;
// buscamos el máximo y el mímino de los valores del vector
maxmin(canal_input,width,height,valores);
//reservamos memoria para el canal de salida
*canal_output=(unsigned char*)malloc((width*height)*sizeof(unsigned char));
cociente= 255/(valores[1]-valores[0]);
for(i=0;i<height;i++){
for(j=0;j<width;j++){
float mult = ((canal_input)[(i*width)+j])-valores[0];
//cada posición del nuevo canal tendra el pixel normalizado.
(*canal_output)[(i*width)+j]=mult*cociente;
};
};
};
void aan_normalizar_imagen_unsigned_char( unsigned char *red, unsigned char
*green, unsigned char *blue, int width, int height) {
unsigned char *red_normalizado,*blue_normalizado,*green_normalizado;
unsigned char *red_f,*blue_f,*green_f;
//normalizamos cada uno de los canales de la imagen
aan_normalizar_canal_unsigned_char(red,&red_normalizado,width,height);
aan_normalizar_canal_unsigned_char(green,&green_normalizado,width,height);
aan_normalizar_canal_unsigned_char(blue,&blue_normalizado,width,height);
//unimos lo canales normalizados, con los canales de la imagen original
aan_unir_canales_unsigned_char(red,red_normalizado,&red_f,width,height);
aan_unir_canales_unsigned_char(green,green_normalizado,&green_f,width,height);
aan_unir_canales_unsigned_char(blue,blue_normalizado,&blue_f,width,height);
char nombre[200];
printf("\n ¿Con que nombre desea guardar la imagen normalizada?\n");
scanf("%s",nombre);
//guardamos la imagen
ami_write_bmp(nombre,red_f,green_f,blue_f,((width*2)+4),height);
free(red_normalizado);
free(green_normalizado);
free(blue_normalizado);
free(red_f);
free(green_f);
free(blue_f);
};
//funcion que nos devuelve el mayor de 3 valores, e indica en rgb a que
//canal pertenecia.
unsigned char mayor(int a,int b,int c,int *rgb){
unsigned char valor;
valor = a;
*rgb=1;
if (b> valor){
valor = b;
*rgb=2;
};
if(c> valor){
valor = c;
*rgb=3;
};
return valor;
};
//funcion que nos devuelve el menor de tres valores
unsigned char menor(int a,int b,int c){
unsigned char valor;
valor = a;
if (b< valor){
valor = b;
};
if(c< valor){
valor = c;
};
return valor;
}
void extraer_hsv(char *nombre){
unsigned char *red1,*blue1,*green1;
unsigned char *V, *H, *S,maximo,minimo;
int width1,heigth1,i,j,rgb;
if(ami_read_bmp(nombre,&red1,&green1,&blue1,&width1,&heigth1)== 0){
//reservamos memoria para los canales de salida.
V=(unsigned char*)malloc((width1*heigth1)*sizeof(unsigned char));
H=(unsigned char*)malloc((width1*heigth1)*sizeof(unsigned char));
S=(unsigned char*)malloc((width1*heigth1)*sizeof(unsigned char));
for(i=0;i<heigth1;i++){
for(j=0;j<width1;j++){
// Para cada valor de los canales rojo verde azul, calculamos el máximo
// y mínimo en la posición respectiva y construimos los canales S V H
// siguiendo las fórmulas dadas
unsigned char rojo=red1[(i*width1)+j];
unsigned char verde=green1[(i*width1)+j];
unsigned char azul=blue1[(i*width1)+j];
maximo = mayor(rojo,verde,azul,&rgb);
minimo = menor(rojo,verde,azul);
V[(i*width1)+j]=maximo;
S[(i*width1)+j]=maximo-minimo;
// comprobamos a donde pertenece el máximo y construimos los canales en
// función de ello
switch (rgb){
case 1:{
float numerador = verde-azul;
float denominador= maximo-minimo;
float cociente = numerador / denominador;
int mult = 43 * cociente;
H[(i*width1)+j] = mult % 256;
break;
};
case 2:{
float numerador = azul-rojo;
float denominador= maximo-minimo;
float cociente = numerador / denominador;
float mult = 43 * cociente;
H[(i*width1)+j] = mult + 85;
break;
};
case 3:{
float numerador = rojo-verde;
float denominador= maximo-minimo;
float cociente = numerador / denominador;
float mult = 43 * cociente;
H[(i*width1)+j] = mult + 170;
break;
};
};
};
};
char*nombre2;
unsigned char *red,*blue,*green;
// unimos los 3 canales de las imagenes
nombre2 = malloc(255 * sizeof(char));
aan_unir_canales_unsigned_char(red1,H,&red,width1,heigth1);
aan_unir_canales_unsigned_char(green1,H,&green,width1,heigth1);
aan_unir_canales_unsigned_char(blue1,H,&blue,width1,heigth1);
// guardamos la nueva imagen
strcpy(nombre2,nombre);
ami_write_bmp(strncat(nombre2,"_H.bmp",6),red,green,blue,((width1*2)+4),heigth1);
aan_unir_canales_unsigned_char(red1,V,&red,width1,heigth1);
aan_unir_canales_unsigned_char(green1,V,&green,width1,heigth1);
aan_unir_canales_unsigned_char(blue1,V,&blue,width1,heigth1);
// guardamos la nueva imagen
strcpy(nombre2,nombre);
ami_write_bmp(strncat(nombre2,"_V.bmp",6),red,green,blue,((width1*2)+4),heigth1);
aan_unir_canales_unsigned_char(red1,S,&red,width1,heigth1);
aan_unir_canales_unsigned_char(green1,S,&green,width1,heigth1);
aan_unir_canales_unsigned_char(blue1,S,&blue,width1,heigth1);
// guardamos la nueva imagen
strcpy(nombre2,nombre);
ami_write_bmp(strncat(nombre2,"_S.bmp",6),red,green,blue,((width1*2)+4),heigth1);
// Liberamos la memoria usada
free(red);
free(green);
free(blue);
free(H);
free(S);
free(V);
}
else{
printf("\n lo sentimos, no hemos podido abrir la imagen indicada\n");
};
};
// Menu principal //////////////////////////////////////////////
int main(){
int opcion;
printf("\nPor favor indique que operación desea realizar:\n\n 1 Unir dos imágenes\n 2 Normalizar una imagen\n 3 Obtener canales HSV de una imagen\n 4 Unir dos imágenes con float\n\n");
scanf("%d",&opcion);
switch(opcion){
// opcion para unir 2 imagenes
case 1:{
char fichero1[200],fichero2[200],ficherosalida[200];
unsigned char *red1,*blue1,*green1,*red2,*blue2,*green2;
int width1,heigth1,width2,heigth2;
printf("\n Inserte el directorio de la primera imagen\n\n");
scanf("%s",fichero1);
printf("\n Inserte el directorio de la segunda imagen\n\n");
scanf("%s",fichero2);
printf("\n Inserte el directorio donde desea guardar la imagen obtenida\n\n");
scanf("%s",ficherosalida);
//Comprobamos que las imagenes se habran correctamente
if(ami_read_bmp(fichero1,&red1,&green1,&blue1,&width1,&heigth1)== 0){
if(ami_read_bmp(fichero2,&red2,&green2,&blue2,&width2,&heigth2)== 0){
unsigned char *red,*blue,*green;
// unimos los 3 canales de las imagenes
aan_unir_canales_unsigned_char(red1,red2,&red,width1,heigth1);
aan_unir_canales_unsigned_char(green1,green2,&green,width1,heigth1);
aan_unir_canales_unsigned_char(blue1,blue2,&blue,width1,heigth1);
// guardamos la nueva imagen
ami_write_bmp(ficherosalida,red,green,blue,((width1*2)+4),heigth1);
free(red);
free(green);
free(blue);
}
else printf("\n el directorio de la segunda imagen es incorrecto\n");
}
else{
printf("\n el directorio de la primera imagen es incorrecto\n");
};
break;
};
// opción para normalizar una imagen
case 2:{
char fichero1[200];
unsigned char *red1,*blue1,*green1;
int width1,heigth1;
printf("\n Inserte el directorio de la imagen a normalizar\n\n");
scanf("%s",fichero1);
if(ami_read_bmp(fichero1,&red1,&green1,&blue1,&width1,&heigth1)== 0){
//invocamos a la función que normaliza imagenes
aan_normalizar_imagen_unsigned_char(red1,green1,blue1,width1,heigth1);
}
else{
printf("\n lo sentimos, no hemos podido abrir la imagen indicada\n");
};
break;
};
// opcion para obtener los canales hsv
case 3:{
char fichero1[200];
printf("\n Inserte el directorio de la imagen a tratar\n\n");
scanf("%s",fichero1);
extraer_hsv(fichero1);
break;
};
case 4:{
char fichero1[200],fichero2[200],ficherosalida[200];
float *red1,*blue1,*green1,*red2,*blue2,*green2;
int width1,heigth1,width2,heigth2;
printf("\n Inserte el directorio de la primera imagen\n\n");
scanf("%s",fichero1);
printf("\n Inserte el directorio de la segunda imagen\n\n");
scanf("%s",fichero2);
printf("\n Inserte el directorio donde desea guardar la imagen obtenida\n\n");
scanf("%s",ficherosalida);
//Comprobamos que las imagenes se habran correctamente
if(ami_read_bmp(fichero1,&red1,&green1,&blue1,&width1,&heigth1)== 0){
if(ami_read_bmp(fichero2,&red2,&green2,&blue2,&width2,&heigth2)== 0){
float *red,*blue,*green;
// unimos los 3 canales de las imagenes
aan_unir_canales_float(red1,red2,&red,width1,heigth1);
aan_unir_canales_float(green1,green2,&green,width1,heigth1);
aan_unir_canales_float(blue1,blue2,&blue,width1,heigth1);
// guardamos la nueva imagen
ami_write_bmp(ficherosalida,red,green,blue,((width1*2)+4),heigth1);
free(red);
free(green);
free(blue);
}
else printf("\n el directorio de la segunda imagen es incorrecto\n");
}
else{
printf("\n el directorio de la primera imagen es incorrecto\n");
};
break;
};
};
return 0;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment