HOUGH.C
Upload User: gzsenex
Upload Date: 2013-02-24
Package Size: 25984k
Code Size: 3k
Category:

Graph program

Development Platform:

C/C++

  1. /* Estimate the skew angle: Hough transform of low resolution smoothed image */
  2. #define MAX
  3. #include "lib.h"
  4. #define OBJECT 1
  5. #define BACK 0
  6. struct lrec {
  7. int rs, re, cs, ce;
  8. } LINE[400];
  9. int Nlines = -1;
  10. int Space = 1;
  11. int Meanwidth = 0;
  12. typedef unsigned char ** GIMAGE;
  13. struct grec { /* Information concerning a glyph */
  14. char value;
  15. short int nr, nc;
  16. GIMAGE ptr;
  17. struct grec * next;
  18. };
  19. typedef struct grec * GPTR;
  20. GPTR database[256];
  21. void FDisplay (float ** x, int nr, int nc);
  22. void hough (IMAGE x, float *theta);
  23. void main (int argc, char *argv[])
  24. {
  25. IMAGE im;
  26. char text[128];
  27. int i, j;
  28. FILE *f;
  29. float theta;
  30. im = newimage (64, 64);
  31. for (i=0; i<64; i++)
  32.   for (j=0; j<64; j++)
  33. im->data[i][j] = BACK;
  34. im->data[2][2] = OBJECT;
  35. im->data[22][22] = OBJECT;
  36. im->data[55][55] = OBJECT;
  37. hough (im, &theta);
  38. printf ("Approximate skew angle is %10.5fn", theta-90);
  39. }
  40. void hough (IMAGE x, float *theta)
  41. {
  42. float **z;
  43. int center_x, center_y, r, omega, i, j, rmax, tmax;
  44. double conv;
  45. double sin(), cos(), sqrt();
  46. float tmval;
  47. conv = 3.1415926535/180.0;
  48. center_x = x->info->nc/2; center_y = x->info->nr/2;
  49. rmax = 
  50.  (int)(sqrt((double)(x->info->nc*x->info->nc+x->info->nr*x->info->nr))/2.0);
  51. /* Create an image for the Hough space - choose your own sampling */
  52. z = f2d (180, 2*rmax+1);
  53. for (r = 0; r < 2 * rmax+1; r++)
  54.    for (omega = 0; omega < 180; omega++)
  55.     z[omega][r] = 0;
  56. tmax = 0; tmval = 0;
  57. for (i = 0; i < x->info->nr; i++)
  58.   for (j = 0; j < x->info->nc; j++)
  59. if (x->data[i][j])
  60.    for (omega = 0; omega < 180; ++omega) 
  61.    {
  62.     r = (i - center_y) * sin((double)(omega*conv)) 
  63.    + (j - center_x) * cos((double)(omega*conv));
  64. /* if (r == 0) continue;  */
  65.     z[omega][rmax+r] += 1;
  66.    }
  67. for (i=0; i<180; i++)
  68.   for (j=0; j<2*rmax+1; j++)
  69.     if (z[i][j] > tmval)
  70.     {
  71. tmval = z[i][j];
  72. tmax = i;
  73.     }
  74. *theta = tmax;
  75. FDisplay (z, 180, 2*rmax+1);
  76. free (z[0]); free (z);
  77. }
  78. void FDisplay (float ** x, int nr, int nc)
  79. {
  80. float xmax, xmin, z, rng;
  81. int count=0, k=0;
  82. int i,j;
  83. FILE *f;
  84. xmax = xmin = x[0][0];
  85. for (i=0; i<nr; i++)
  86.   for (j=0; j<nc; j++)
  87.   {
  88.     if (xmax < x[i][j]) xmax = x[i][j];
  89.     if (xmin > x[i][j]) xmin = x[i][j];
  90.   }
  91. fprintf (stderr, "DISPLAY: xmax = %f xmin = %fn", xmax, xmin);
  92. rng = xmax - xmin;
  93. f = fopen ("/tmp/z", "w");
  94. fprintf (f, "P2n%d %dn255n", nc, nr);
  95. for (i=0; i<nr; i++)
  96.   for (j=0; j<nc; j++)
  97.   {
  98.     z = x[i][j];
  99.     k = (unsigned char) ((z-xmin)/rng * 255);
  100.     fprintf (f, "%3d ", k);
  101.     count++;
  102.     if (count > 30)
  103.     {
  104. count = 0;
  105. fprintf (f, "n");
  106.     }
  107.   }
  108. fclose (f);
  109. system ("xv /tmp/z");
  110. }