#include "CImg.h"
#include <iostream>
#include <math.h>

using namespace cimg_library;
using namespace std;

CImg<double> imagen_RGB("sombras.bmp");
CImg<double> c3(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg<double> H(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg<double> S(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg<double> V(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);

CImg<double> R(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg<double> G(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg<double> B(imagen_RGB.dimx(),imagen_RGB.dimy(),1,1,0);
CImg <double> sumaA(imagen_RGB.dimx(),imagen_RGB.dimy());

CImg<double> semillero(c3.dimx(),c3.dimy(),1,1,0);

double d0=0.1; 




void recursi(int &max, int k,int l, double &media,double &suma,double &desvio,int &cantidad){

	max++;
	if (max<1500){

		

if (((k-1>0)&&(k-1<c3.dimx()))&&((l-1>0)&&(l-1<c3.dimy()))){

	if (semillero(k-1,l-1)==0){

	if ((V(k-1,l-1)<0.50)&&(B(k-1,l-1)<0.50)&&(S(k-1,l-1)>=0.0)   ){
		if (sumaA(k-1,l-1)==0){

	if ((((c3(k-1,l-1)-media)) <d0)&&(((c3(k-1,l-1)-media)) >-d0)){
	//si pertenece:
	cantidad++;
	suma=suma+c3(k-1,l-1);
	media=suma/cantidad;


	semillero(k-1,l-1)=1;
cout<<"1";
	
	recursi(max,k-1,l-1,media,suma,desvio,cantidad);
max--;

}
}
}
}}

if (((k-1>0)&&(k-1<c3.dimx()))&&((l>0)&&(l<c3.dimy()))){

	if (semillero(k-1,l)==0){
	if ((V(k-1,l)<0.50)&&(B(k-1,l)<0.5)&&(S(k-1,l)>=0.0)   ){
		if (sumaA(k-1,l)==0){
	if ((((c3(k-1,l)-media)) <d0)&&(((c3(k-1,l)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k-1,l);
	media=suma/cantidad;
 
	semillero(k-1,l)=1;
cout<<"2";
	recursi(max,k-1,l,media,suma,desvio,cantidad);
max--;

}
}
}
}}



if (((k-1>0)&&(k-1<c3.dimx()))&&((l+1>0)&&(l+1<c3.dimy()))){

	if (semillero(k-1,l+1)==0){
if ((V(k-1,l+1)<0.50)&&(B(k-1,l+1)<0.50)&&(S(k-1,l+1)>=0.0)   ){
		if (sumaA(k-1,l+1)==0){
	if ((((c3(k-1,l+1)-media)) <d0)&&(((c3(k-1,l+1)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k-1,l+1);
	media=suma/cantidad;


	semillero(k-1,l+1)=1;
cout<<"3";
	recursi(max,k-1,l+1,media,suma,desvio,cantidad);
max--;

}
}
}}}




if (((k>0)&&(k<c3.dimx()))&&((l-1>0)&&(l-1<c3.dimy()))){

	if (semillero(k,l-1)==0){
if ((V(k,l-1)<0.50)&&(B(k,l-1)<0.50)&&(S(k,l-1)>=0.0)   ){
		if (sumaA(k,l-1)==0){
if ((((c3(k,l-1)-media)) <d0)&&(((c3(k,l-1)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k,l-1);
	media=suma/cantidad;

	semillero(k,l-1)=1;
cout<<"4";
	recursi(max,k,l-1,media,suma,desvio,cantidad);
max--;

}
}
}}}

if (((k>0)&&(k<c3.dimx()))&&((l+1>0)&&(l+1<c3.dimy()))){

	if (semillero(k,l+1)==0){
if ((V(k,l+1)<0.50)&&(B(k,l+1)<0.50)&&(S(k,l+1)>=0.0)   ){
		if (sumaA(k,l+1)==0){
if ((((c3(k,l+1)-media)) <d0)&&(((c3(k,l+1)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k,l+1);
	media=suma/cantidad;

	semillero(k,l+1)=1;
cout<<"5";
	recursi(max,k,l+1,media,suma,desvio,cantidad);
max--;

}
}
}}}


if (((k+1>0)&&(k+1<c3.dimx()))&&((l-1>0)&&(l-1<c3.dimy()))){

	if (semillero(k+1,l-1)==0){
if ((V(k+1,l-1)<0.50)&&(B(k+1,l-1)<0.50)&&(S(k+1,l-1)>=0.02)   ){
		if (sumaA(k+1,l-1)==0){
	if ((((c3(k+1,l-1)-media)) <d0)&&(((c3(k+1,l-1)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k+1,l-1);
	media=suma/cantidad;

	semillero(k+1,l-1)=1;
cout<<"6";
	recursi(max,k+1,l-1,media,suma,desvio,cantidad);
max--;

}
}
}
}}

if (((k+1>0)&&(k+1<c3.dimx()))&&((l>0)&&(l<c3.dimy()))){

	if (semillero(k+1,l)==0){
if ((V(k+1,l)<0.50)&&(B(k+1,l)<0.50)&&(S(k+1,l)>=0.02)   ){
		if (sumaA(k+1,l)==0){
	if ((((c3(k+1,l)-media)) <d0)&&(((c3(k+1,l)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k+1,l);
	media=suma/cantidad;
	semillero(k+1,l)=1;
cout<<"7";
	recursi(max,k+1,l,media,suma,desvio,cantidad);
max--;

}
}
}
}}



if (((k+1>0)&&(k+1<c3.dimx()))&&((l+1>0)&&(l+1<c3.dimy()))){

	if (semillero(k+1,l+1)==0){
if ((V(k+1,l+1)<0.50)&&(B(k+1,l+1)<0.50)&&(S(k+1,l+1)>=0.02)   ){
		if (sumaA(k+1,l+1)==0){
	if ((((c3(k+1,l+1)-media)) <d0)&&(((c3(k+1,l+1)-media)) >-d0)){
	//si pertenece:

	cantidad++;
	suma=suma+c3(k+1,l+1);
	media=suma/cantidad;

	semillero(k+1,l+1)=1;
cout<<"8";
	recursi(max,k+1,l+1,media,suma,desvio,cantidad);
max--;

}

		}
}}}







}// if cantidad region	

}





void ejer1(){
	

CImg<double> imagen_HSV(imagen_RGB.dimx(),imagen_RGB.dimy());

CImgDisplay ventana(imagen_RGB,"imagen_RGB");
	




imagen_HSV=imagen_RGB.get_RGBtoHSV();

cimg_forXY(imagen_HSV,x2,y2){
	
	H(x2,y2)=(imagen_HSV(x2,y2,0,0)*(180.0/3.14))*(255.0/360.0);
	S(x2,y2)=imagen_HSV(x2,y2,0,1)*255;
	V(x2,y2)=imagen_HSV(x2,y2,0,2)*255;
	

	R(x2,y2)=imagen_RGB(x2,y2,0,0);
	G(x2,y2)=imagen_RGB(x2,y2,0,1);
	B(x2,y2)=imagen_RGB(x2,y2,0,2);
	//calculo c3:
	if ((R(x2,y2)==0)&&(G(x2,y2)==0)){R(x2,y2)=0.001;}//para evitar el dividir por cero , nada mas !
	if (R(x2,y2)>=G(x2,y2)){c3(x2,y2)=atan(B(x2,y2)/R(x2,y2));}else{c3(x2,y2)=atan(B(x2,y2)/G(x2,y2));}
	//-----------
}
CImgDisplay ventana442(S,"S");
CImgDisplay ventana441(B,"B");
CImgDisplay ventana4(V,"V");
CImgDisplay ventana8(c3,"c3");

cimg_forXY(imagen_HSV,x,y){
	
	H(x,y)=imagen_HSV(x,y,0,0);
	S(x,y)=imagen_HSV(x,y,0,1);
	V(x,y)=imagen_HSV(x,y,0,2);

}



//filtro a c3;

CImg<double> h(5,5);
h(0,0)=1.0/25.0;
h(0,1)=1.0/25.0;
h(0,2)=1.0/25.0;
h(0,3)=1.0/25.0;
h(0,4)=1.0/25.0;
h(1,0)=1.0/25.0;
h(1,1)=1.0/25.0;
h(1,2)=1.0/25.0;
h(1,3)=1.0/25.0;
h(1,4)=1.0/25.0;
h(2,0)=1.0/25.0;
h(2,1)=1.0/25.0;
h(2,2)=1.0/25.0;
h(2,3)=1.0/25.0;
h(2,4)=1.0/25.0;
h(3,0)=1.0/25.0;
h(3,1)=1.0/25.0;
h(3,2)=1.0/25.0;
h(3,3)=1.0/25.0;
h(3,4)=1.0/25.0;
h(4,0)=1.0/25.0;
h(4,1)=1.0/25.0;
h(4,2)=1.0/25.0;
h(4,3)=1.0/25.0;
h(4,4)=1.0/25.0;

c3.convolve(h);
//V.convolve(h); //le agregue un filtro
//c3.normalize(0,255);// esto lo agrugue yo!
//c3.threshold(200);
//cimg_forXY(c3,a9,b9){c3(a9,b9)=exp(c3(a9,b9));}
CImgDisplay ventana10(c3,"c3 filtrada");





//sobel 
double umbral=64;
CImg<double> imagenA=V; imagenA.channel(0);imagenA.normalize(0,255);
CImg<double> imagen2A=V;imagen2A.channel(0);imagenA.normalize(0,255);
CImg<double> imagen3A=V;imagen3A.channel(0);imagenA.normalize(0,255);
CImg<double> imagen4A=V;imagen4A.channel(0);imagenA.normalize(0,255);
	
CImg<double> sobel_v(3,3,1,1,0);
sobel_v(0,0)=-1;
sobel_v(0,1)=-2;
sobel_v(0,2)=-1;
sobel_v(1,0)=0;
sobel_v(1,1)=0;
sobel_v(1,2)=0;
sobel_v(2,0)=1;
sobel_v(2,1)=2;
sobel_v(2,2)=1;

imagenA.convolve(sobel_v);
cimg_forXY(imagenA,x3,y3){imagenA(x3,y3)=abs(imagenA(x3,y3));}
imagenA.threshold(umbral);
//CImgDisplay venta(imagenA,"A");


CImg<double> sobel_h(3,3,1,1,0);
sobel_h(0,0)=-1;
sobel_h(0,1)=0;
sobel_h(0,2)=1;
sobel_h(1,0)=-2;
sobel_h(1,1)=0;
sobel_h(1,2)=2;
sobel_h(2,0)=-1;
sobel_h(2,1)=0;
sobel_h(2,2)=1;

imagen2A.convolve(sobel_h);
cimg_forXY(imagenA,x4,y4){imagen2A(x4,y4)=abs(imagen2A(x4,y4));}
imagen2A.threshold(umbral);




CImg<double> sobel_diag(3,3,1,1,0);
sobel_diag(0,0)=0;
sobel_diag(0,1)=1;
sobel_diag(0,2)=2;
sobel_diag(1,0)=-1;
sobel_diag(1,1)=0;
sobel_diag(1,2)=1;
sobel_diag(2,0)=-2;
sobel_diag(2,1)=-1;
sobel_diag(2,2)=0;


imagen3A.convolve(sobel_diag);
cimg_forXY(imagen3A,x5,y5){imagen3A(x5,y5)=abs(imagen3A(x5,y5));}
imagen3A.threshold(umbral);


 
CImg<double> sobel_diag2(3,3,1,1,0);
sobel_diag2(0,0)=-2;
sobel_diag2(0,1)=-1;
sobel_diag2(0,2)=0;
sobel_diag2(1,0)=-1;
sobel_diag2(1,1)=0;
sobel_diag2(1,2)=1;
sobel_diag2(2,0)=0;
sobel_diag2(2,1)=1;
sobel_diag2(2,2)=2;


imagen4A.convolve(sobel_diag2);
cimg_forXY(imagen4A,x6,y6){imagen4A(x6,y6)=abs(imagen4A(x6,y6));}
imagen4A.threshold(umbral);



cimg_forXY(sumaA,x7,y7){sumaA(x7,y7)=(imagenA(x7,y7)+imagen2A(x7,y7)+imagen3A(x7,y7)+imagen4A(x7,y7));}
sumaA.convolve(h);
CImgDisplay ventana54A(sumaA,"suma de binarios");

;
//--------aca termina sobel-------------



//--colocamos semillas-----------------
int total=0;
CImg<double> semilla(9,9);
CImg<double> semilla_ord(9,9);
double media=0;
cimg_forXY(c3,a,b){ media=media+c3(a,b);}
media=media/(c3.dimx()*c3.dimy());
cout<<"media: "<<media<<endl;

int c=0;
CImg<double> semilla_R(9,9),semilla_G(9,9),semilla_B(9,9);
CImg<double> semilla_RGB(9,9,1,3,0);
CImg<double> semilla_HSV(9,9,1,3,0);
double media_V=0;
double media_S=0;
double media_B=0;


B.normalize(0,1);//-----


int k=4; 
while (k<(c3.dimx()-5)){
int l=4;
while (l<(c3.dimy()-5)){


semilla=c3.get_crop(k-4,l-4,0,0, k+4,l+4,0,0,true);
semilla_ord=semilla.get_sort(true);

//umbrales de V,B y S
semilla_R=R.get_crop(k-4,l-4,0,0, k+4,l+4,0,0,true);
semilla_G=G.get_crop(k-4,l-4,0,0, k+4,l+4,0,0,true);
semilla_B=B.get_crop(k-4,l-4,0,0, k+4,l+4,0,0,true);

double suma_semilla=0;
double media_semilla=0;
double desvio_semilla=0;
int cant_region=81;

cimg_forXY(semilla,a3,b3){suma_semilla=suma_semilla+semilla(a3,b3);
	semilla_RGB(a3,b3,0,0)=semilla_R(a3,b3,0,0);semilla_RGB(a3,b3,0,1)=semilla_G(a3,b3,0,1);semilla_RGB(a3,b3,0,2)=semilla_B(a3,b3,0,2);}



media_semilla=suma_semilla/81.0;


cimg_forXY(semilla,a5,b5){desvio_semilla=+desvio_semilla+pow((semilla(a5,b5)-media_semilla),2);}
desvio_semilla=desvio_semilla/81;


semilla_HSV=semilla_RGB.get_RGBtoHSV();

cimg_forXY(semilla_HSV,a2,b2){
	media_V=media_V+semilla_HSV(a2,b2,0,2);
	media_S=media_S+semilla_HSV(a2,b2,0,1);
	media_B=media_B+semilla_RGB(a2,b2,0,2);
}
media_V=media_V/81.0;
media_S=media_S/81.0;
media_B=media_B/81.0;



if ((media_V<0.50)&&(media_B<0.50)&&(media_S>0.02)   ){
	
	bool esta_en_otro=false;
	for (int x=-4;x<5;x++) {for (int y=-4;y<5;y++) {if (semillero(k-x,l-y)==1){esta_en_otro=true;}}}// para ser semilla ninguno  de los pixels deben perteneeer a otra ventana previa

	if (esta_en_otro==false){	


	if (semilla(4,4)==semilla_ord(8,8)){
		cout<<"*";
		bool es_semilla=true;
		cimg_forXY(semilla,i,j){if ((i!=4)&&(j!=4)){ if (semilla(i,j)<media*1.1){es_semilla=false;}}}	
 	
		if (es_semilla){l=l+4;//total++;if (total>10){break;	}
			if ((l<c3.dimy())&&(k<c3.dimx())){
				imagen_RGB(k,l,0,0)=255;
				imagen_RGB(k,l,0,1)=255;
				imagen_RGB(k,l,0,2)=255;}
			c++;cout<<c<<" "; 


	int max=0;
	recursi(max,k,l,media_semilla,suma_semilla,desvio_semilla,cant_region);



	}// if de es semilla
	

cout<<endl;




}//if de mayor
}//if de umbrales
}//if de esta en otro
l++;
}//l
k++;
}//k


CImgDisplay brbb(imagen_RGB,"");
cimg_forXY(imagen_RGB,p,q){if (semillero(p,q)==1){imagen_RGB(p,q,0,0)=255;
				imagen_RGB(p,q,0,1)=255;
				imagen_RGB(p,q,0,2)=255;}}

CImgDisplay bbb(imagen_RGB,"Regiones");









while (!ventana.is_closed){}
}






int main() {

ejer1();
	
return 0;
}
