#include <iostream>
#include "EasyBMP.h"
#include "allegro.h"
#define X 740
#define Y 570
#define F 10000
using namespace std;
class Pixel
{
public:
short int red;
short int green;
short int blue;
short int alfa;
unsigned int zona;
bool pas,prepas;
};
class Relieve{
public:
bool frontera;
};
void CargarImagen (Pixel CCD[X][Y])
{
int i,j;
BMP imagen;
imagen.ReadFromFile("m64.bmp");
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
CCD[i][j].red=(int) imagen(i,j)->Red;
CCD[i][j].green=(int) imagen(i,j)->Green;
CCD[i][j].blue=(int) imagen(i,j)->Blue;
CCD[i][j].alfa=(int) imagen(i,j) ->Alpha;
CCD[i][j].pas=false;
CCD[i][j].prepas=false;
CCD[i][j].zona=0;
}
}
}
void GraficarCCD(Pixel array[X][Y])
{
int i,j;
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
putpixel(screen,i,j,makeacol(array[i][j].red,array[i][j].green,array[i][j].blue,array[i][j].alfa));
}
}
}
void GraficarMascara(Relieve Mascara[X][Y])
{
int i,j;
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
if(Mascara[i][j].frontera)
putpixel(screen,i,j,makeacol(255,255,255,255));
else putpixel(screen,i,j,makeacol(0,0,0,0));
}
}
}
void GraficarCCDMascara(Pixel CCD[X][Y],Relieve Mascara[X][Y])
{
int i,j;
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
if(Mascara[i][j].frontera) putpixel(screen,i,j,makeacol(255,255,255,255));
else
{
putpixel(screen,i,j,makeacol(CCD[i][j].red,CCD[i][j].green,CCD[i][j].blue,CCD[i][j].alfa));
}
}
}
}
int CalcularFrontera (Pixel CCD[X][Y],Relieve Mascara[X][Y])
{
int i,j, corte, indice;
cout<<"Por favor, escriba el valor de corte para calcular la frontera de luminosidad."<<endl<<endl;
do{
cout<<"Numero entre 0 y 255: "<<endl;
cin>>corte;
}while(corte<-1 || corte>255);
for(i=1;i<X-1;i++){
for(j=1;j<Y-1;j++){
if(CCD[i][j].red>corte){
if(CCD[i+1][j].red<corte || CCD[i-1][j].red<corte || CCD[i][j+1].red<corte || CCD[i][j-1].red<corte)
{
Mascara[i][j].frontera=true;
}
else Mascara[i][j].frontera=false;
}
}
}
GraficarMascara(Mascara);
do{
cout<<"Pulse 1 para refrescar la pantalla"<<endl;
cout<<"Pulse 2 para superponer el filtro de saturacion a la imagen"<<endl;
cout<<"Pulse 3 para cambiar el limite de saturacion"<<endl;
cout<<"Pulse 4 para aceptar el limite de saturacion"<<endl;
cin>>indice;
if(indice==1)
{
GraficarCCD(CCD);
GraficarMascara(Mascara);
}
if(indice==2)
{
GraficarCCDMascara(CCD,Mascara);
}
if(indice==3)
{
cout<<"Por favor, escriba el valor de corte para calcular la frontera de luminosidad."<<endl<<endl;
do{
cout<<"Numero entre 0 y 255: "<<endl;
cin>>corte;
}while(corte<-1 || corte>255);
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
Mascara[i][j].frontera=false;
}
}
for(i=1;i<X-1;i++){
for(j=1;j<Y-1;j++){
if(CCD[i][j].blue>corte){
if(CCD[i+1][j].blue<corte || CCD[i-1][j].blue<corte || CCD[i][j+1].blue<corte || CCD[i][j-1].blue<corte)
{
Mascara[i][j].frontera=true;
}
else Mascara[i][j].frontera=false;
}
}
}
GraficarCCD(CCD);
GraficarMascara(Mascara);
}
}while(indice!=4);
return corte;
}
void CalcularZonas (Pixel CCD[X][Y],int corte_sat)
{
class buf
{
public:
int k;
int l;
};
int i,j,z,b,p,m;
int zonas=0;
z=0;
b=0;
buf buffer[F];
for(m=0;m<F;m++)
{
buffer[m].k=-1;
buffer[m].l=-1;
}
for(i=0;i<X;i++)
{
for(j=0;j<Y;j++)
{
if(CCD[i][j].red>corte_sat && CCD[i][j].pas==false && CCD[i][j].prepas==false)
{
z++;
b=0;
CCD[i][j].zona=z;
CCD[i][j].prepas=true;
CCD[i][j].pas=true;
if(CCD[i+1][j].red>corte_sat && CCD[i+1][j].prepas==false && CCD[i+1][j].pas==false)
{
buffer[b].k=i+1;
buffer[b].l=j;
b++;
CCD[i+1][j].prepas=true;
}
if(CCD[i][j+1].red>corte_sat && CCD[i][j+1].prepas==false && CCD[i][j+1].pas==false)
{
buffer[b].k=i;
buffer[b].l=j+1;
b++;
CCD[i][j+1].prepas=true;
}
if(CCD[i-1][j].red>corte_sat && CCD[i-1][j].prepas==false && CCD[i-1][j].pas==false)
{
buffer[b].k=i-1;
buffer[b].l=j;
b++;
CCD[i-1][j].prepas=true;
}
if(CCD[i][j-1].red>corte_sat && CCD[i][j-1].prepas==false && CCD[i][j-1].pas==false)
{
buffer[b].k=i;
buffer[b].l=j-1;
b++;
CCD[i][j-1].prepas=true;
}
if(CCD[i+1][j+1].red>corte_sat && CCD[i+1][j+1].prepas==false && CCD[i+1][j+1].pas==false)
{
buffer[b].k=i+1;
buffer[b].l=j+1;
b++;
CCD[i+1][j+1].prepas=true;
}
if(CCD[i+1][j-1].red>corte_sat && CCD[i+1][j-1].prepas==false && CCD[i+1][j-1].pas==false)
{
buffer[b].k=i+1;
buffer[b].l=j-1;
b++;
CCD[i+1][j-1].prepas=true;
}
if(CCD[i-1][j+1].red>corte_sat && CCD[i-1][j+1].prepas==false && CCD[i-1][j+1].pas==false)
{
buffer[b].k=i-1;
buffer[b].l=j+1;
b++;
CCD[i-1][j+1].prepas=true;
}
if(CCD[i-1][j-1].red>corte_sat && CCD[i-1][j-1].prepas==false && CCD[i-1][j-1].pas==false)
{
buffer[b].k=i-1;
buffer[b].l=j-1;
b++;
CCD[i-1][j-1].prepas=true;
}
p=-1;
do {
p++;
CCD[buffer[p].k][buffer[p].l].pas=true;
CCD[buffer[p].k][buffer[p].l].zona=z;
buffer[p].k=-1;
buffer[p].l=-1;
if((CCD[(buffer[1+p].k)+1][buffer[1+p].l].red>corte_sat) && (CCD[(buffer[1+p].k+1)][buffer[1+p].l].prepas==false) && (CCD[(buffer[1+p].k+1)][buffer[1+p].l].pas==false))
{
buffer[b].k=buffer[1+p].k+1;
buffer[b].l=buffer[1+p].l;
b++;
}
if((CCD[(buffer[1+p].k)][buffer[1+p].l+1].red>corte_sat) && (CCD[(buffer[1+p].k)][buffer[1+p].l+1].prepas==false) && (CCD[(buffer[1+p].k)][buffer[1+p].l+1].pas==false))
{
buffer[b].k=buffer[1+p].k;
buffer[b].l=buffer[1+p].l+1;
b++;
}
if((CCD[(buffer[1+p].k)-1][buffer[1+p].l].red>corte_sat) && (CCD[(buffer[1+p].k)-1][buffer[1+p].l].prepas==false) && (CCD[(buffer[1+p].k)-1][buffer[1+p].l].pas==false))
{
buffer[b].k=buffer[1+p].k-1;
buffer[b].l=buffer[1+p].l;
b++;
}
if((CCD[buffer[1+p].k][(buffer[1+p].l)-1].red>corte_sat) && (CCD[buffer[1+p].k][(buffer[1+p].l)-1].prepas==false) && (CCD[(buffer[1+p].k)][(buffer[1+p].l)-1].pas==false))
{
buffer[b].k=buffer[1+p].k;
buffer[b].l=buffer[1+p].l-1;
b++;
}
if((CCD[(buffer[1+p].k)+1][(buffer[1+p].l)+1].red>corte_sat) && (CCD[(buffer[1+p].k)+1][(buffer[1+p].l)+1].prepas==false) && (CCD[(buffer[1+p].k)+1][(buffer[1+p].l)+1].pas==false))
{
buffer[b].k=buffer[1+p].k+1;
buffer[b].l=buffer[1+p].l+1;
b++;
}
if((CCD[(buffer[1+p].k)+1][(buffer[1+p].l)-1].red>corte_sat) && (CCD[(buffer[1+p].k)+1][(buffer[1+p].l)-1].prepas==false) && (CCD[(buffer[1+p].k)+1][(buffer[1+p].l)-1].pas==false))
{
buffer[b].k=buffer[1+p].k+1;
buffer[b].l=buffer[1+p].l-1;
b++;
}
if((CCD[(buffer[1+p].k)-1][(buffer[1+p].l)+1].red>corte_sat) && (CCD[(buffer[1+p].k)-1][(buffer[1+p].l)+1].prepas==false) && (CCD[(buffer[1+p].k)-1][(buffer[1+p].l)+1].pas==false))
{
buffer[b].k=buffer[1+p].k-1;
buffer[b].l=buffer[1+p].l+1;
b++;
}
if((CCD[(buffer[1+p].k)-1][(buffer[1+p].l)-1].red>corte_sat) && (CCD[(buffer[1+p].k)-1][(buffer[1+p].l)-1].prepas==false) && (CCD[(buffer[1+p].k)-1][(buffer[1+p].l)-1].pas==false))
{
buffer[b].k=buffer[1+p].k-1;
buffer[b].l=buffer[1+p].l-1;
b++;
}
} while((buffer[1+p].k)!=-1);
}
else
{
CCD[i][j].pas=true;
}
}
}
cout<<z<<endl;
}
void GraficarCCDZona(Pixel array[X][Y])
{
int i,j;
for(i=0;i<X;i++){
for(j=0;j<Y;j++){
if(array[i][j].zona!=0)
{
putpixel(screen,i,j,makeacol(array[i][j].red,array[i][j].green,array[i][j].blue,array[i][j].alfa));
}
else{
putpixel(screen,i,j,makeacol(0,0,0,0));
}
}
}
}
int main()
{
string pausa;
int corte_sat;
Pixel CCD[X][Y];
Relieve Mascara[X][Y];
allegro_init();
set_color_depth(16);
set_write_alpha_blender();
set_gfx_mode(GFX_AUTODETECT_WINDOWED,740,570,0,0);
CargarImagen(CCD);
GraficarCCD(CCD);
corte_sat=CalcularFrontera(CCD,Mascara);
cin>>pausa;
CalcularZonas(CCD,corte_sat);
GraficarCCDZona(CCD);
cin>>pausa;
allegro_exit();
return 0;
}