#include "stdafx.h"
#include "rectangle.h"
#include "linehough.h"
#include "findrectangle.h"
#include "highgui.h"


const float MINIMAL_LINE_LENGTH = 0.15;


int GetHoughLine(c_LineHoughTransform *LineDetect, double *R, double *Alpha)
{
   int x,y, Value;
     LineDetect->FindMax(x,y);
     Value = LineDetect->GetValue(x,y);
	 for (int i=x-LineDetect->ZeroWidth; i<x+LineDetect->ZeroWidth; i++)
      for (int j=y-LineDetect->ZeroHeight; j<y+LineDetect->ZeroHeight; j++)
      {
        if ((i>=0) && (i<LineDetect->XSize) && (j>=0) && (j<LineDetect->YSize))
          LineDetect->Array[i+j*LineDetect->XSize]=0;
      }
      *R = x-LineDetect->XSize/2.0;

      *Alpha = 180.0*y/LineDetect->YSize;
    return Value;
}

float FindRectangle(IplImage *grey, CvPoint2D32f *Points, int Low, int High)
{
  c_DetectRectangle FindRectangle;
  c_LineHoughTransform LineDetect;              // line detection class
  // new twice smaller image
  IplImage  *edge = cvCreateImage(cvGetSize(grey), IPL_DEPTH_8U, 1);
  //cvPyrDown(grey, edge, CV_GAUSSIAN_5x5);
  int xsize = edge->width;
  int ysize = edge->height;
  memset(Points,0,sizeof(CvPoint2D32f)*4);
 do 
 {
  cvCanny(grey, edge, Low, High, 3);
  // detekce car
  LineDetect.Init(xsize, ysize, AXIS_ALPHA_SIZE, 1);
  unsigned char *data = (unsigned char *)edge->imageData;
  for (int y=0; y<ysize; y++)
  {
    for (int x=0; x<xsize; x++)
    {
       if (*data>0)
         LineDetect.AddValue(x,y);
       data+=1;
    }
  }
  //  LineDetect.DrawArray((unsigned char*)edge->imageData, edge->width, edge->height,5);
  //  cvSaveImage("canny.jpg", edge);
  // extrakce car

  FindRectangle.Init(xsize, ysize);
  int x,y;
  double Max = LineDetect.FindMax(x,y), value = 0, R, Alpha;

  if (LineDetect.Count>0)
  do
  {
        value = GetHoughLine(&LineDetect, &R, &Alpha);
        if (value < MINIMAL_LINE_LENGTH*xsize) break;
        FindRectangle.PutLine(R, Alpha, value);
  } while (LineDetect.Count>0);
  FindRectangle.Sort();

  // not enough lines for rectangle
  if ((FindRectangle.VerticalPoints<2) || (FindRectangle.HorizontalPoints<2))
    return 0;
  // too much lines for processing
  Low += 20;  High += 20;

} while ((FindRectangle.VerticalPoints*FindRectangle.HorizontalPoints>1000) && (High<255));

  float result = FindRectangle.FindRectangle((unsigned char *)edge->imageData, xsize, ysize, Points);
  if (result == 0)
    return result;
  // size normalization regarding to the original image
  Points[0].x *= grey->width/xsize;   Points[0].y *= grey->height/ysize;
  Points[1].x *= grey->width/xsize;   Points[1].y *= grey->height/ysize;
  Points[2].x *= grey->width/xsize;   Points[2].y *= grey->height/ysize;
  Points[3].x *= grey->width/xsize;   Points[3].y *= grey->height/ysize;

  cvReleaseImage(&edge);
  return result;
}
 