    
    #include <opencv/highgui.h>
    #include <opencv/cv.h>
    #include <stdio.h>
    #include <math.h>

    #define ventana "Ventana1"

    #define ventana1 "Ventana2"

    CvPoint2D32f srcQuad[4], dstQuad[4];
    IplImage *src, *dst;
    CvMat* warp_matrix;
    int count =0;

    double pointDist(CvPoint2D32f *p0, CvPoint2D32f *p1)
    {
           return sqrt(pow(p0->x-p1->x,2)+pow(p0->y-p1->y,2));
    }

void rotate(float angle, float centreX, float centreY){
   
   CvPoint2D32f centre;
   CvMat *translate = cvCreateMat(2, 3, CV_32FC1);
   cvSetZero(translate);
   centre.x = centreX;
   centre.y = centreY;
   cv2DRotationMatrix(centre, angle, 1.0, translate);
   cvWarpAffine(src, dst, translate, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));
   cvReleaseMat(&translate);

}

    void click(int event, int x, int y, int flags, void* param) {
		 if (event == CV_EVENT_FLAG_LBUTTON) {
		 CvPoint v, v2, h, h2;
		 v.x = dst->width / 4;
		 v.y = 0;
		 v2.x = dst->width / 4;
		 v2.y = dst->height;

		 h.x = 0;
		 h.y = dst->height / 4;
		 h2.x = dst->width;
		 h2.y = dst->height / 4;

	 printf("Rotate...\n");
//	rotate(30.0f, src->width/2, src->height/2);
	cvSetImageROI(src,cvRect(x-(src->width/4),y-(src->height/4),src->width/2,src->height/2)); 
//	cvShowImage(ventana1,dst);
	cvReleaseImage(&dst);
	dst = cvCloneImage(src);
	cvLine( dst, v, v2, CV_RGB(0,0,0), 1, CV_AA, 0);
	cvLine( dst, h, h2, CV_RGB(0,0,0), 1, CV_AA, 0);

	cvShowImage(ventana1, dst);


	cvResetImageROI(src);
}
	return;

    if (event == CV_EVENT_FLAG_LBUTTON)
    {
    printf("Corner: %d\n",count);
    srcQuad[count].x = x;
    srcQuad[count++].y = y;
    if (count == 4)
	count = 0;
    }
 

	if (event == CV_EVENT_FLAG_LBUTTON || event == CV_EVENT_FLAG_RBUTTON) {
		/* http://blog.weisu.org/2007/12/opencv-image-rotate-and-zoom-rotation.html */
		float m[6];
		int angle = 0;
		double factor;
		double width = dst->width;
		double height = dst->height;
		CvMat M = cvMat(2, 3, CV_32F, m);
		factor = 3.0f;
		//(cos(angle*CV_PI/180.) + 1.05) * 2;
	        m[0] = (float)(factor*cos(-angle*2*CV_PI/180.));
	        m[1] = (float)(factor*sin(-angle*2*CV_PI/180.));
	        m[3] = -m[1];
	        m[4] = m[0];
	        m[2] = width*0.5f;  
	        m[5] = height*0.5f;  

		//int shift = 1;

		//double width = pointDist(&srcQuad[0], &srcQuad[1]);
		//double height = pointDist(&srcQuad[3], &srcQuad[0]);

		printf("%f %f\n", width, height);

/*	        dstQuad[0] = cvPoint2D32f(0,0);
	        dstQuad[1] = cvPoint2D32f(width-1,0);
	        dstQuad[2]= cvPoint2D32f(width-1,height-1);
	        dstQuad[3] = cvPoint2D32f(0,height-1);*/

		double feature = width / 10;
/*	        dstQuad[0] = cvPoint2D32f(0,0);
	        dstQuad[1] = cvPoint2D32f(feature-1,0);
	        dstQuad[2]= cvPoint2D32f(feature-1,feature-1);
	        dstQuad[3] = cvPoint2D32f(0,feature-1);*/

	        dstQuad[0] = cvPoint2D32f(srcQuad[0].x,srcQuad[0].y);
	        dstQuad[1] = cvPoint2D32f(srcQuad[0].x+feature-1,srcQuad[0].y);
	        dstQuad[2]= cvPoint2D32f(srcQuad[0].x+feature-1,srcQuad[0].y+feature-1);
	        dstQuad[3] = cvPoint2D32f(srcQuad[0].x,srcQuad[0].y+feature-1);

		printf("src: ");
		int i,j;
		for (i=0; i<4; ++i)
			printf("(%f,%f) ",srcQuad[i].x, srcQuad[i].y);
		printf("\n dst: ");
		for (j=0; j<4; ++j)
			printf("(%f,%f) ",dstQuad[j].x, dstQuad[j].y);
		printf("\n");

    		cvZero(dst);
		cvGetPerspectiveTransform(srcQuad, dstQuad, warp_matrix);
	        cvWarpPerspective(src,dst,warp_matrix,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));;
    		cvShowImage(ventana1,dst);
/*
		IplImage* inter = cvCloneImage( dst );
		cvZero(dst);
		cvGetQuadrangleSubPix( inter, dst, &M);
		cvReleaseImage(&inter);

    		cvShowImage(ventana1,dst);
*/
	}
    }

    int main(int argc, char* argv[])

    {
	
    warp_matrix = cvCreateMat(3, 3, CV_32FC1);

    char* filename = argc >= 2 ? argv[1] : (char*)"img_0846.jpg";

    src = cvLoadImage(filename,1);
    dst = cvCloneImage(src);
    dst->origin = src->origin;
    cvZero(dst);

    srcQuad[0].x = 0;
    srcQuad[0].y = 0;
    srcQuad[1].x = src->width - 1;
    srcQuad[1].y = 0;
    srcQuad[2].x = 0;
    srcQuad[2].y = src->height -1;
    srcQuad[3].x = src->width - 1;
    srcQuad[3].y = src->height -1;

    dstQuad[0].x = src->width*0.1;
    dstQuad[0].y = src->height*0.1;
    dstQuad[1].x = src->width*0.9;
    dstQuad[1].y = src->height*0.1;
    dstQuad[2].x = src->width*0.3;
    dstQuad[2].y = src->height*0.9;
    dstQuad[3].x = src->width*0.7;
    dstQuad[3].y = src->height*0.9;

    cvGetPerspectiveTransform(srcQuad, dstQuad, warp_matrix);
    cvWarpPerspective(src,dst,warp_matrix,CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS, cvScalarAll(0));

    cvNamedWindow(ventana,0);

    cvNamedWindow(ventana1,0);

    //Mostramos la imagen en la ventana

    cvShowImage(ventana,src);

    cvShowImage(ventana1,dst);

    cvSetMouseCallback(ventana, click, NULL );

    for(;;)

    {
    int key;

    key = cvWaitKey(0);

    if( key == 27 || key == 'q' || key == 'Q' ) // 'ESC', q o Q
    break;

    }

    cvReleaseImage(&dst);
    cvReleaseMat(&warp_matrix);
    cvDestroyAllWindows();//Destruimos todas las ventanas

    return 0;

    }

