project1.cc.html
//**************************************************************************
//
//      CSE 486 Project #1
//      By Anirudh Modi (anirudh@bart.aero.psu.edu) on 1/29/99-Fri
//	 & Jim Geis (geis@cse.psu.edu)
//	 & Howard Elikan (elikan@cse.psu.edu)
//
//**************************************************************************
//	Running time of algorithm -> O[width x height]
//**************************************************************************
// 	Have implemented the following ->
//		1. Smoothening of histogram to determine minima/maxima
//		2. Basic image operations (+, -, =)
//		3. There is no memory leak
//**************************************************************************
#include <iostream.h>
#include <fstream.h>
#include <stdio.h>
#include <string.h>
#include <math.h>
#include "image.h"
//**************************************************************************
void ProcessImage (GrayImage *image, char *filename);
void modify (GrayImage *image);
double CompareMoments (GrayImage *I1, int c1, GrayImage *I2, int c2);
void PrintComparison (GrayImage *I1, int c1, GrayImage *I2, int c2);
//**************************************************************************
int main (int argc, char *argv[])
{
GrayImage CombinedImage, I[4];
char nCombinedImage[] = "images/3things.pgm";
char *nI[] = {"images/calculator.pgm", 
		"images/racquetball.pgm",
		"images/soapdish.pgm",
		"images/postit.pgm"};

ProcessImage( &CombinedImage, nCombinedImage);
for (int i = 0; i < 4; i++)
	ProcessImage( &I[i], nI[i]);

cout << endl;
for (int i = 1; i <= CombinedImage.numComponents; i++)
	for (int j = 0; j < 4; j++)
		{
		 double error = CompareMoments(&CombinedImage,i,&I[j],1);
		 printf("Avg error between component %d and %s = %.2f %%\n",
			i,nI[j],error*100.0);
		 if (error < 0.05)
			{
			 cout 
			  << "Component " << i << " of \"" << nCombinedImage 
			  << "\" <==> \"" << nI[j] << "\"" 
			  <<  endl;
			 PrintComparison(&CombinedImage,i,&I[j],1);
			}
		}

CombinedImage.WriteLabelsToFile("Combined.pgm");
for (int i = 0; i < 4; i++)
	{
	 char name[50];
	 sprintf(name,"I%d.pgm",i+1);
	 I[i].WriteLabelsToFile(name);
	}

cout << "Program done." << endl;
}
//**************************************************************************
void ProcessImage (GrayImage *image, char *filename)
{
image->ReadFromFile(filename);
image->Histogram( );
image->smoothenHistogram( );
image->calcHistogramPeaks( );

for (int i = 0; i < image->numMinHist-1; i++)
	{
	 GrayImage dummy;
	 dummy = *image;
	 int m1 = image->getHistMinima(i+1);
	 int m2 = image->getHistMinima(i+2);
	 dummy.Threshold(m1, m2);
	 dummy.ConvertToBinary( );
	 if ((dummy.Area(0) >= dummy.numpixels/2) && (dummy.p[0][0] == 0))
		{
		 dummy.ReverseBinary( );
		 dummy.LabelComponents( );
		 for (int k = 1; k <= dummy.numComponents; k++)
	 		 dummy.InvariantMoments(k);
		 *image = dummy;
	
		 cout << "Found background!!" << endl;
		 break;
		}
	}
}
//**************************************************************************
void modify (GrayImage *image)
{
for (int i = 0; i < image->width; i++)
	for (int j = 0; j < image->height; j++)
		image->p[i][j] = (unsigned char) 
			(image->p[i][j]*1.0*
			pow(tan(image->p[i][j]*1.0/255.0*3.14159),1));
}
//**************************************************************************
double CompareMoments (GrayImage *I1, int c1, GrayImage *I2, int c2)
{
double error = 0.0;
double max = 0.0;

for (int i = 1; i <= 7; i++)
	{
	 double err;
	 double r = I1->getInvariantMoment(c1,i)/I2->getInvariantMoment(c2,i);
	 err = fabs(r - 1.0);
	 error += err;
	 if (err > max) 
		max = err;
	}
error /= 7.0;
if (max > 0.1)
	error += 0.10;

return error;
}
//**************************************************************************
void PrintComparison (GrayImage *I1, int c1, GrayImage *I2, int c2)
{
printf("------------------------------------------------------------\n");
printf("Property   \t  Image 1 \t  Image 2 \t    Error\n");
printf("------------------------------------------------------------\n");
for (int i = 1; i <= 7; i++)
	{
	 double e1 = I1->getInvariantMoment(c1,i);
	 double e2 = I2->getInvariantMoment(c2,i);
	 printf("Moment %d   \t%10.4f\t%10.4f\t%8.2f %%\n",i,e1,e2,(e1-e2)/e2*100.0);
	}
int a1 = I1->Area(c1);
int a2 = I2->Area(c2);
int p1 = I1->Perimeter(c1);
int p2 = I2->Perimeter(c2);
double e1 = I1->Elongation(c1);
double e2 = I2->Elongation(c2);
double C1 = p1*p1*1.0/a1;
double C2 = p2*p2*1.0/a2;
printf("Area       \t%10d\t%10d\t%8.2f %%\n",a1,a2,(a1-a2)*100.0/a2);
printf("Perimeter  \t%10d\t%10d\t%8.2f %%\n",p1,p2,(p1-p2)*100.0/p2);
printf("Compactness\t%10.4f\t%10.4f\t%8.2f %%\n",C1,C2,(C1-C2)/C2*100.0);
printf("Elongation \t%10.4f\t%10.4f\t%8.2f %%\n",e1,e2,(e1-e2)/e2*100.0);
printf("------------------------------------------------------------\n");
}
//**************************************************************************