#include <highgui.h>
#include <cv.h>
#include <cxcore.h>
#include <iostream>
#include <stdio.h>

#define FACTOR 2.25
#define MIN_CONT_SIZE 3500
#define RESIZE_SCALE 8

using namespace std;

int main(int argc, char** argv)
{
	if(argc<2)
	{
		cout << "You must give the name of the file containing the image!\n";
		return 1;
	}
	int k, nCont;
	int nDilations = 0;
	IplImage *origImg, *img, *cannyImg;
	CvMemStorage *storage;
	CvSeq *seq, *bigC;
	double cL, rL, aL;
	bool tryAgain = true;
	origImg = cvLoadImage(argv[1],0);
	double max = -1; //size of the biggest contour's bounding box
	img = cvCreateImage(cvSize(origImg->width/RESIZE_SCALE, origImg->height/RESIZE_SCALE),origImg->depth,1);
	cannyImg = cvCreateImage(cvSize(origImg->width/RESIZE_SCALE, origImg->height/RESIZE_SCALE),origImg->depth,1);
	cvResize(origImg, cannyImg);
	cvNot(cannyImg,cannyImg);
	cvCanny(cannyImg, cannyImg, 5,255/4);
	do
	{
		max = -1;

		storage = cvCreateMemStorage();
		
		cvMorphologyEx(cannyImg,img,0,0,CV_MOP_CLOSE,nDilations);
		nCont = cvFindContours(img, storage, &seq, sizeof(CvContour),CV_RETR_EXTERNAL);    

		for( CvSeq* c=seq; c!=NULL; c=c->h_next ) 
		{
			if(fabs(cvContourArea(c))>max)
			{
				max=fabs(cvContourArea(c));
				bigC = c;
			}
		}
		CvRect bbox = cvBoundingRect(bigC);
		rL = 2*bbox.width+2*bbox.height;
		cL = cvArcLength(bigC);
		aL = 2*img->width+2*img->height;

		if(cL<FACTOR*rL && rL > aL*0.2)
			tryAgain = false;
		else
		{
			nDilations++;
			cvReleaseMemStorage(&storage);
		}
	}while(tryAgain);
	IplImage* dummy2 = cvCreateImage(cvGetSize(img),img->depth,1);
	double ratio = img->height / 255.0;
	IplImage* resized = cvCreateImage(cvSize(img->width/ratio, 255),img->depth,1);
	cvZero(dummy2);
	cvDrawContours(dummy2,bigC,cvScalar(255,0,255),cvScalar(255,0,255),0,-1,8);		
	for( CvSeq* c=seq; c!=NULL; c=c->h_next ) 
	{
		if(fabs(cvContourArea(c))<max && fabs(cvContourArea(c)) > MIN_CONT_SIZE)
		{
			cvDrawContours(dummy2,c,cvScalar(255,0,255),cvScalar(255,0,255),0,-1,8);
		}
	}	 
	cvResize(dummy2,resized);
	char nameOut[256] = "out_c.png";
	if(argc>=3) //if there is another parameter, use it as file name for the output
	{
		sprintf(nameOut,"%s.png",argv[2]);
	}
	cvSaveImage(nameOut,resized);
	//save resized image
	cvResize(origImg,resized);
	sprintf(nameOut,"out.png");
	if(argc>=4) //if there is another parameter, use it as file name for the output
	{
		sprintf(nameOut,"%s.png",argv[3]);
	}
	cvSaveImage(nameOut,resized);
	return 0;
}
