
#include <cv.h>
#include <highgui.h>
#include <iostream>

/*
Test program showing usage of the template matching functions in OpenCV.
@author: Gavin Page, gsp8334@cs.rit.edu
@date: 07 December 2005
*/

int main( int argc, char** argv ) {

	//the name of the image being loaded
	char* imageName = "BruneauCanyon0006.jpg"; 

	//Load the image and make sure that it loads correctly
	IplImage* im = cvLoadImage( imageName, -1);
	if( im == 0 ) {
		//Drop out if the image isn't found
		std::cerr << "Failed to load: " << imageName << std::endl;
		return 1;
	}

	IplImage* imG = cvCreateImage(cvSize(im->width, im->height), 8, 1);
	cvCvtColor(im, imG, CV_BGR2GRAY);


	//define the starting point and size of rectangle
	int xVal = 1145;
	int yVal = 890;
	int neighLength = 25;
	CvRect rect = cvRect(xVal,yVal,neighLength,neighLength);

	//create the template and extract it from the source image
	CvMat* tplate = cvCreateMat(neighLength, neighLength, CV_8UC1);
	cvGetSubRect(imG, tplate, rect );

	
	//specify the size needed by the match function
	int resultW = imG->width - tplate->width + 1;
	int resultH = imG->height - tplate->height +1;

	//create each of the result images
	IplImage* result0 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
	IplImage* result1 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
	IplImage* result2 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
	IplImage* result3 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
	IplImage* result4 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);
	IplImage* result5 = cvCreateImage(cvSize(resultW, resultH), IPL_DEPTH_32F, 1);


	
	//apply each of the matching techniques
	cvMatchTemplate(imG, tplate, result0, CV_TM_SQDIFF);
	cvMatchTemplate(imG, tplate, result1, CV_TM_SQDIFF_NORMED);
	cvMatchTemplate(imG, tplate, result2, CV_TM_CCORR);
	cvMatchTemplate(imG, tplate, result3, CV_TM_CCORR_NORMED);
	cvMatchTemplate(imG, tplate, result4, CV_TM_CCOEFF);
	cvMatchTemplate(imG, tplate, result5, CV_TM_CCOEFF_NORMED);

	//show the results of the matching
	cvNamedWindow("SQDIFF", 0 );
	cvNamedWindow("SQDIFF_NORMED",0);
	cvNamedWindow("CCORR",0);
	cvNamedWindow("CCORR_NORMED",0);
	cvNamedWindow("CCOEFF",0);
	cvNamedWindow("CCOEEFF_NORMED",0);

	cvShowImage("SQDIFF", result0);
	cvShowImage("SQDIFF_NORMED", result1);
	cvShowImage("CCORR", result2);
	cvShowImage("CCORR_NORMED", result3);
	cvShowImage("CCOEFF", result4);
	cvShowImage("CCOEEFF_NORMED", result5);

	//mark the area where the template was extracted
	cvRectangle(imG, cvPoint(xVal,yVal), cvPoint(xVal+neighLength,yVal+neighLength),
		CV_RGB(255,0,255),2 , 8, 0);

	//show the image and template
	cvNamedWindow("Image",0);
	cvNamedWindow("Template",0);
	cvShowImage("Image", imG);
	cvShowImage("Template", tplate);

	
	//hold the images until a key is pressed
	cvWaitKey(0);

	cvReleaseImage(&imG);
	cvReleaseMat(&tplate);
	cvReleaseImage(&result0);
	cvReleaseImage(&result1);
	cvReleaseImage(&result2);
	cvReleaseImage(&result3);
	cvReleaseImage(&result4);
	cvReleaseImage(&result5);
	cvDestroyAllWindows();

	return 0;

}
