/*****************************************************************************/
/*                       Image processing functions                          */
/*  Source file : hough transform for direction detection                    */
/*  Designed by Igor Potucek (potucek@fit.vutbr.cz)                          */
/*  created 2005                                                             */
/*****************************************************************************/
#include "hough.h"
#include <math.h>

#define max(a,b) ((a)>(b))?(a):(b)


// coeficient for min value of the cell in hough space for LSM
const float HOUGH_THRESHOLD = 0.0002;     // result = XSize * YSize * HOUGH_THRESHOLD

void c_HoughTransform::Init(int xsize, int ysize, float ratio)
// initialization accumulator array
{

   if ((Array!=NULL) && ((xsize!=XSize) || (ysize!=YSize)))
   {
     delete [] Array;  Array=NULL;
   }
   if ((XVal!=NULL) && ((xsize!=XSize) || (ysize!=YSize)))
   {
     delete [] XVal;  XVal=NULL;
   }
   if ((YVal!=NULL) && ((xsize!=XSize) || (ysize!=YSize)))
   {
     delete [] YVal;  YVal=NULL;
   }
   Ratio = ratio;
   XSize = xsize*Ratio+0.5;
   YSize = ysize*Ratio+0.5;
   CentX = XSize/2;
   CentY = YSize/2;
   Count=0;
   if (Array==NULL)
   {
     Array = new int[XSize*YSize];
   }
   if (XVal==NULL)
   {
     XVal = new long[XSize*YSize];
   }
   if (YVal==NULL)
   {
     YVal = new long[XSize*YSize];
   }
   memset(Array, 0, XSize*YSize*sizeof(int));
   memset(XVal, 0, XSize*YSize*sizeof(long));
   memset(YVal, 0, XSize*YSize*sizeof(long));
}

bool c_HoughTransform::AddValue(float offsetx, float offsety)
{  // transform position in image into position in hough space
  Count++;
  int x = offsetx*Ratio+0.5+CentX;
  int y = offsety*Ratio+0.5+CentY;
  if ((x<0) || (y<0) || (y>=YSize) || (x>=XSize))
  {
     return false;
  }
    Array[x+y*XSize]++;
    XVal[x+y*XSize]+=offsetx;
    YVal[x+y*XSize]+=offsety;
  return true;
}


 int c_HoughTransform::GetValue(int x, int y, float &avgx, float &avgy)
 {
   if ((x>=0) && (x<XSize) && (y>=0) && (y<YSize))
   {
      if (Array[x+y*XSize]>0) avgx = XVal[x+y*XSize]/(float)Array[x+y*XSize];
      else avgx = 0;
      if (Array[x+y*XSize]>0) avgy = YVal[x+y*XSize]/(float)Array[x+y*XSize];
      else avgy = 0;
      return 0;
   }
   else
   {
     avgx = 0; avgy = 0;
     return -1;
   }
 }
 int c_HoughTransform::FindMax(int &x, int &y)
 {  // normalize by maximal value
    int great=1;
    // search maximum
    for (int j=0; j<YSize; j++)
      for (int i=0; i<XSize; i++)
      {
         if (great<Array[j*XSize+i])
         {
            great=Array[j*XSize+i];
            x = i;  y = j;
         }
      }
      return great;
 }
  bool c_HoughTransform::ResetValue(int x, int y)
  {
     if ((x>=0) && (x<XSize) && (y>=0) && (y<YSize))
     {
       Array[x+y*XSize] = 0;
       return true;
     }
     else
       return false;
  }

unsigned char* c_HoughTransform::NormalizedHoughArray()
{
  unsigned char *hough=new unsigned char[XSize*YSize];
  int great=1;
  for (int i=0; i<XSize; i++)
    for (int j=0; j<YSize; j++)
    {
       great=max(great,Array[j*XSize+i]);
    }
  for (int i=0; i<XSize; i++)
    for (int j=0; j<YSize; j++)
    {
         int value=255*Array[j*XSize+i]/great;
         hough[j*XSize+i]=value;
    }
  return hough;
}

#ifdef DIGILIB
//------------------------------------------------------------------------------
 long c_HoughTransform::DrawArray(ImageStruct *Image)
 {  // normalize by maximal value
    int great=1;
    // search maximum
    for (int j=0; j<YSize; j++)
      for (int i=0; i<XSize; i++)
      {
         great=max(great,Array[j*XSize+i]);
      }
    for (int j=0; j<YSize; j++)
      for (int i=0; i<XSize; i++)
      {
         int value=255*Array[j*XSize+i]/great;
         SetImage8Pixel(Image,i,j,value);
      }
    return great;
 }
#endif


