
/**
    Simple example of background segmentation for a Robocup football
    field.
We want to label each coloe by its pure color. We change nay kinds of green to pure green. 
We also do this for yellow, white, orange and red color.
Any color, that the program doesn't regcognize, it will change to a black color.
 
*/

/**
    This program requires the PPM library (part of the netpbm package).
    Try "man libppm" for documentation.
*/

#include <stdio.h>
#include <ppm.h>

/**
    Process an image by marking "background" pixels red.
*/

void
ProcessImage(
    pixel     **pPixelIn,       /* Input pixel data */
    pixel     **pPixelOut,      /* Output pixel data */
    int         cCols,          /* Number of columns in input/output imgs */
    int         cRows,          /* Number of rows in input/output imgs */
    pixval      pixvalMax       /* Maximum pixel value */
);

bool checkGreenColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
);
bool checkYellowColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
);
bool checkOrangeColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
);
bool checkRedColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
);
bool checkWhiteColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
);
/**
    Main
*/

int
main(
    int argc,                   /**< Number of input arguments */
    char *argv[]                /**< Input arguments */
)
{
    pixel **ppPixelIn;
    pixel **ppPixelOut;
    int cCols, cRows;
    pixval pixvalMax;
    FILE *pFile;

    /* Initialize the PPM library */

    ppm_init( &argc, argv );

    /* Open the PPM file */

    pFile = fopen( "field.ppm", "r" );
    if ( pFile == NULL ) {
        fprintf( stderr, "%s %d: could not open field.ppm\n", __FILE__,
                 __LINE__ );
        exit( -1 );
    }

    /* Read the image file in its entirety into memory */

    ppPixelIn =  ppm_readppm( pFile, &cCols, &cRows, &pixvalMax );
    if ( ppPixelIn == NULL ) {
        fprintf( stderr, "%s %d: could not read pixel data from field.ppm\n",
                 __FILE__, __LINE__ );
        exit( -1 );
    }
    fclose( pFile );

    /* Allocate a new PPM of the same size */

    ppPixelOut = ppm_allocarray( cCols, cRows );
    if ( ppPixelOut == NULL ) {
        fprintf( stderr, "%s %d: could not allocate pixel data\n",
                 __FILE__, __LINE__ );
        exit( -1 );
    }

    /* Process the input image, writing new data to the output image */

    ProcessImage( ppPixelIn, ppPixelOut, cCols, cRows, pixvalMax );

    /* Open output file */

    pFile = fopen( "fieldout.ppm", "w" );
    if ( pFile == NULL ) {
        fprintf( stderr, "%s %d: could not create fieldout.ppm\n",
                 __FILE__, __LINE__ );
        exit( -1 );
    }

    /* Write output image to the output file */

    ppm_writeppm( pFile, ppPixelOut, cCols, cRows, pixvalMax, 0 );
    fclose( pFile );

    return 0;
}


/**
    Process an image by marking "background" pixels red.
*/

void
ProcessImage(
    pixel **pPixelIn,
    pixel **pPixelOut,
    int cCols,
    int cRows,
    pixval pixvalMax
)
{
    int iRow, iCol;

    /* For each row and column of the image */
	
    for ( iRow = 0; iRow < cRows; iRow++ ) {
        for ( iCol = 0; iCol < cCols; iCol++ ) {

            /* Extract the red, green, and blue components of the pixel */

            pixval pixvalR = PPM_GETR( pPixelIn[iRow][iCol] );
            pixval pixvalG = PPM_GETG( pPixelIn[iRow][iCol] );
            pixval pixvalB = PPM_GETB( pPixelIn[iRow][iCol] );

	if(checkGreenColor(pixvalR,pixvalG,pixvalB,pixvalMax))
	{
		//change any green pixel to a  pure green pixel
		pixvalR = 0;
 		pixvalG = 225;
		pixvalB = 0;
	}
	else if (checkOrangeColor(pixvalR,pixvalG,pixvalB,pixvalMax))
	{
		//change any orange pixel to a pure orange pixel
		pixvalR = 255;
 		pixvalG = 113;
		pixvalB = 9;
	}
	else if (checkYellowColor(pixvalR,pixvalG,pixvalB,pixvalMax))
	{
		//change any yellow pixel to a pure yellow pixel
		pixvalR = 255;
 		pixvalG = 245;
		pixvalB = 45;
	}	
	else if (checkRedColor(pixvalR,pixvalG,pixvalB,pixvalMax))
	{
		//change any red pixel to a pure red pixel
		pixvalR = 255;
 		pixvalG = 44;
		pixvalB = 3;
	}
	else if (checkWhiteColor(pixvalR,pixvalG,pixvalB,pixvalMax))
	{
		//change any white pixel to a pure white pixel
		pixvalR = 255;
 		pixvalG = 255;
		pixvalB = 255;
	}
	else
	{
		//change unclassified color to black
		pixvalR = 0;
 		pixvalG = 0;
		pixvalB = 0;
	}

           
     
	  
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////	   
      /* Write the pixel value to the output image */

            PPM_ASSIGN( pPixelOut[iRow][iCol], pixvalR, pixvalG, pixvalB );
        }
    }
	
}
bool checkWhiteColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
)
{
    //check if the red component is ok
    if ( pixvalR >= 0.96 * pixvalMax )
    {
	//check if the green component is ok
	if (pixvalG >= 0.96 * pixvalMax )
	{	
	   //check the blue component is ok
	   if ( pixvalB >= 0.96 * pixvalMax )
           {
		return TRUE;
	   }		
	}
    }
    return FALSE;
}
bool checkRedColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
)
{
    //check if the red component is ok
    if ( pixvalR >= 0.80 * pixvalMax )
    {
	//check if the green component is ok
	if (pixvalG >= 0.16 * pixvalMax && pixvalG <= 0.34 * pixvalMax)
	{	
	   //check the blue component is ok
	   if ( pixvalB <= 0.4 * pixvalMax)
           {
		return TRUE;
	   }		
	}
    }
    return FALSE;
}
bool checkOrangeColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
)
{
    //check if the red component is ok
    if ( pixvalR >= 0.95 * pixvalMax )
    {
	//check if the green component is ok
	if (pixvalG >= 0.38 * pixvalMax && pixvalG <= 0.81 * pixvalMax)
	{	
	   //check the blue component is ok
	   if ( pixvalB <= 0.11 * pixvalMax)
           {
		return TRUE;
	   }		
	}
    }
    return FALSE;
}
bool checkYellowColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
)
{
    //check if the red component is ok
    if ( pixvalR >= 0.94 * pixvalMax )
    {
	//check if the green component is ok
	if (pixvalG >= 0.77)
	{	
	   //check the blue component is ok
	   if (pixvalB >= 0.04 * pixvalMax && pixvalB <= 0.47 * pixvalMax)
           {
		return TRUE;
	   }		
	}
    }
    return FALSE;
}
bool checkGreenColor
(
    pixval pixvalR,
    pixval pixvalG,
    pixval pixvalB,
    pixval pixvalMax	
)
{
    //check if the red component is ok
    if ( pixvalR >= 0.23 * pixvalMax && pixvalR <= 0.52 * pixvalMax)
    {
	//check if the green component is ok
	if (pixvalG >= 0.28 * pixvalMax && pixvalG <= 0.54 * pixvalMax)
	{	
	   //check the blue component is ok
	   if (pixvalB >= 0.03 * pixvalMax && pixvalB <= 0.17 * pixvalMax)
           {
		return TRUE;
	   }		
	}
    }
    return FALSE;
}
