#include "stdafx.h"
#include <cv.h>
#include <highgui.h>
#include <math.h>
using namespace std;
#include "stdafx.h"
#include <cv.h>
#include <highgui.h>

int main(int argc, char** argv)
{

	if( argc < 5 )
    {
       printf(" %s", "Please pass video file name, output video file name,area size, skipped frames rate\n");
        return -1;
    }
     //load the video file to the memory
     CvCapture *capture =     cvCaptureFromAVI(argv[1]);
		 int frame_width=(int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);     //get the width of frame
		 int frame_height=(int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);   //get the height of frame
		 int fps = ( int )cvGetCaptureProperty( capture, CV_CAP_PROP_FPS );  //get the frames per second

   //creating video writer structure
  CvVideoWriter *writer = 0;
  writer=cvCreateVideoWriter(argv[2],CV_FOURCC('M', 'P', '4', '2'),fps,cvSize(frame_width,frame_height),1);
	
  int pix;
	pix=atoi(argv[3]);
	// frame counter
	int brojac=0;
	//frame skip counter
 int skipfr;
 skipfr=atoi(argv[4]);

     if( !capture ) return 1;

   
    //create a window with the title "Video"
    cvNamedWindow("Video");

    while(true) {
             //grab and retrieve each frames of the video sequencially 
             IplImage* frame = cvQueryFrame( capture );
			 brojac=brojac+1;
			 printf("%d/n",brojac);
			 if (brojac%skipfr==0){
			 double area=0;
 double rez=0;
  double minarea = 100.0;  
   double tmparea = 0.0;  
 //  uchar *pp;  
 CvRect rect; 
 CvBox2D box;
  IplImage* img =  cvCloneImage(frame);

  // IplImage* img_Clone=cvCloneImage(img);  
  
 //show the original image
 cvNamedWindow("Raw");
 cvShowImage("Raw",img);

  //converting the original image into grayscale
 IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1); 
 cvCvtColor(img,imgGrayScale,CV_BGR2GRAY);
 IplImage* Iat = cvCreateImage(cvGetSize(img), 8, 1); 
 //IplImage* canny = cvCreateImage(cvGetSize(img), 8, 1); 

 //laplace
  /*IplImage* laplaceImg = cvCreateImage(cvGetSize(img), 8, 1); 
 cvLaplace(imgGrayScale, laplaceImg, 3);*/
 ////show the modified image
 //cvNamedWindow("mod122");
 //cvShowImage("mod122",laplaceImg);
  cvSmooth(imgGrayScale, imgGrayScale, CV_MEDIAN,3);

  //adaptive tresholding
 cvAdaptiveThreshold(imgGrayScale, Iat, 255, CV_ADAPTIVE_THRESH_MEAN_C,
CV_THRESH_BINARY, 71, 15);
 //cvDilate(Iat,Iat,NULL,1);
 cvErode(Iat,Iat,NULL,2);
  cvDilate(Iat,Iat,NULL,2);
 // cvErode(Iat,Iat,NULL,1);
 // cvCanny(Iat,canny,50,150,3);
 //     //show the modified image
 //cvNamedWindow("canny");
 //cvShowImage("canny",canny);



  //thresholding the grayscale image to get better results
 cvThreshold(imgGrayScale,imgGrayScale,128,255,CV_THRESH_BINARY);  

    //show the modified image
 //cvNamedWindow("mod12");
 //cvShowImage("mod12",Iat);
 
   //show the modified image
/* cvNamedWindow("mod");
 cvShowImage("mod",imgGrayScale)*/;

 CvSeq* contours;  //hold the pointer to a contour in the memory block
 CvSeq* result;   //hold sequence of points of a contour
 CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
 
 
 //finding all contours in the image
 cvFindContours(Iat, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
  
// //iterating through each contour
// CvSeq* it_contours = contours;
//int count = 0;
//for( ; it_contours != 0; it_contours = it_contours->h_next )
//{
//		CvMoments mom;
//		cvMoments( it_contours, &mom); 
//		//printf("%d/n",mom.m00);
//		if (mom.m00 < 5)
//		cvSeqRemove( contours, count);
//		else
//		count++; 
//}
//printf("%d/n",count);
  CvMoments Moments;

 while(contours)
 {

	 area = cvContourArea( contours, CV_WHOLE_SEQ );
	 box=cvMinAreaRect2 (contours,0);
	// printf("%f/n",area);
	 cvContourMoments(Iat, &Moments);
	 double m00;
        m00 = cvGetCentralMoment(&Moments, 1,1);
		//printf("%d/n",m00);

     //obtain a sequence of points of contour, pointed by the variable 'contour'
     result = cvApproxPoly(contours, sizeof(CvContour), storage, CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0);
	
       
 if( fabs( area ) > pix && fabs( area ) < 10000 && cvCheckContourConvexity(result)) { 
     //if there are 3  vertices  in the contour(It should be a triangle)

	 // remove small areas
	  // tmparea = fabs(cvContourArea(contours));  
	  // printf("%d/n",tmparea);
        
		//cvSaveImage("C:/Users/roko romic/Desktop/fish2.png",img_Clone);  
    if(result->total==3 )
     {
         //iterating through each point
         CvPoint *pt[3];
         for(int i=0;i<3;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
		 //printf("%d/n",*pt[0]);
		
		

         //drawing lines around the triangle
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[0], cvScalar(0,255,0),4);
       
     }

      //if there are 4 vertices in the contour(It should be a quadrilateral)
     else if(result->total==4 )
     {
         //iterating through each point
         CvPoint *pt[4];
         for(int i=0;i<4;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
   
         //drawing lines around the quadrilateral
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
         cvLine(img, *pt[3], *pt[0], cvScalar(0,255,0),4);   
	}
	 else if(result->total==5 )
     {
         //iterating through each point
         CvPoint *pt[5];
         for(int i=0;i<5;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
   
         //drawing lines around the quadrilateral
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
		    cvLine(img, *pt[3], *pt[4], cvScalar(0,255,0),4);
         cvLine(img, *pt[4], *pt[0], cvScalar(0,255,0),4);   
     }

	 else if(result->total==6 )
     {
         //iterating through each point
         CvPoint *pt[6];
         for(int i=0;i<6;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
   
         //drawing lines around the quadrilateral
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
		    cvLine(img, *pt[3], *pt[4], cvScalar(0,255,0),4);
			cvLine(img, *pt[4], *pt[5], cvScalar(0,255,0),4);
         cvLine(img, *pt[5], *pt[0], cvScalar(0,255,0),4);   
     }

   //if there are 7  vertices  in the contour(It should be a heptagon)
     else if(result->total ==7  )
     {
         //iterating through each point
         CvPoint *pt[7];
         for(int i=0;i<7;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
   
         //drawing lines around the heptagon
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
         cvLine(img, *pt[3], *pt[4], cvScalar(0,255,0),4);
         cvLine(img, *pt[4], *pt[5], cvScalar(0,255,0),4);
         cvLine(img, *pt[5], *pt[6], cvScalar(0,255,0),4);
         cvLine(img, *pt[6], *pt[0], cvScalar(0,255,0),4);
     }
	    else if(result->total ==8  )
     {
         //iterating through each point
         CvPoint *pt[8];
         for(int i=0;i<8;i++){
             pt[i] = (CvPoint*)cvGetSeqElem(result, i);
         }
   
         //drawing lines around the heptagon
         cvLine(img, *pt[0], *pt[1], cvScalar(0,255,0),4);
         cvLine(img, *pt[1], *pt[2], cvScalar(0,255,0),4);
         cvLine(img, *pt[2], *pt[3], cvScalar(0,255,0),4);
         cvLine(img, *pt[3], *pt[4], cvScalar(0,255,0),4);
         cvLine(img, *pt[4], *pt[5], cvScalar(0,255,0),4);
         cvLine(img, *pt[5], *pt[6], cvScalar(0,255,0),4);
		  cvLine(img, *pt[6], *pt[7], cvScalar(0,255,0),4);
         cvLine(img, *pt[7], *pt[0], cvScalar(0,255,0),4);
     }
	 }
      //obtain the next contour
     contours = contours->h_next; 
 }
 //}


  //show the image in which identified shapes are marked   
 cvNamedWindow("Tracked");
 cvShowImage("Tracked",img);
 cvSaveImage("C:/Users/roko romic/Desktop/cage3.png",img);  
  cvWriteFrame(writer,img);
   
// cvWaitKey(0); //wait for a key press

  //cleaning up
 //cvDestroyAllWindows(); 
 cvReleaseMemStorage(&storage);
 cvReleaseImage(&img);
 cvReleaseImage(&imgGrayScale);
 cvReleaseImage(&Iat);


             if( !frame ) break;

             //show the retrieved frame in the "Video" window
             cvShowImage( "Video", frame );

             int c; 


             if(fps!=0){  

                     //wait for 1000/fps milliseconds
                     c = cvWaitKey(1000/fps);
            }else{
                     //wait for 40 milliseconds
                      c = cvWaitKey(40);
            } 



          //exit the loop if user press "Esc" key  (ASCII value of "Esc" is 27) 
            if((char)c==27 ) break;
   }
   }
   //destroy the opened window
   cvDestroyWindow("Video");   
   //release memory
   cvDestroyAllWindows(); 
   cvReleaseCapture( &capture );
       cvReleaseVideoWriter(&writer);
    return 0;
//	}
}


