⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 geosubs.c

📁 This is code tutorial for image processing include:histogram,sketon....
💻 C
字号:

    /********************************************
    *
    *    file geosubs.c
    *
    *    Functions: This file contains
    *       geometry
    *       arotate
    *       bilinear_interpolate
    *
    *    Purpose:
    *       These functions performs different
    *       geometric operations.
    *
    *    External Calls:
    *       none
    *
    *    Modifications:
    *       20 October 1993- created
    *       27 August 1998 - modified to work on 
    *            entire images at once.
    *
    ********************************************/

#include "cips.h"

#define FILL 150





     /*******************************************
     *
     *   geometry(..
     *
     *   This routine performs geometric
     *   transformations on the pixels in an
     *   image array.  It performs basic
     *   displacement, stretching, and rotation.
     *
     *   The basic equations are:
     *
     *   new x = x.cos(a) + y.sin(a) + x_displace
     *           + x.x_stretch +x.y.x_cross
     *
     *   new y = y.cos(a) - x.sin(a) + y_displace
     *           + y.y_stretch +x.y.y_cross
     *
     *******************************************/

geometry(the_image, out_image,
        x_angle,
        x_stretch, y_stretch,
        x_displace, y_displace,
        x_cross, y_cross,
        bilinear,
        rows,
        cols)

   float  x_angle, x_stretch, y_stretch,
          x_cross, y_cross;
   int    bilinear;
   long   cols, rows;
   short  **the_image,
          **out_image,
          x_displace, y_displace;
{
   double cosa, sina, radian_angle, tmpx, tmpy;
   float  fi, fj, x_div, y_div, x_num, y_num;
   int    i, j, new_i, new_j;


      /******************************
      *
      *   Load the terms array with
      *   the correct parameters.
      *
      *******************************/

      /* the following magic number is from
         180 degrees divided by pi */
   radian_angle = x_angle/57.29577951;
   cosa  = cos(radian_angle);
   sina  = sin(radian_angle);

      /************************************
      *
      *   NOTE: You divide by the
      *   stretching factors. Therefore, if
      *   they are zero, you divide by 1.
      *   You do this with the x_div y_div
      *   variables. You also need a
      *   numerator term to create a zero
      *   product.  You do this with the
      *   x_num and y_num variables.
      *
      *************************************/

   if(x_stretch < 0.00001){
      x_div = 1.0;
      x_num = 0.0;
   }
   else{
      x_div = x_stretch;
      x_num = 1.0;
   }

   if(y_stretch < 0.00001){
      y_div = 1.0;
      y_num = 0.0;
   }
   else{
      y_div = y_stretch;
      y_num = 1.0;
   }

      /**************************
      *
      *   Loop over image array
      *
      **************************/

   printf("\n");
   for(i=0; i<rows; i++){
      if( (i%10) == 0) printf("%d ", i);
      for(j=0; j<cols; j++){

         fi = i;
         fj = j;

         tmpx = (double)(j)*cosa         +
                (double)(i)*sina         +
                (double)(x_displace)     +
                (double)(x_num*fj/x_div) +
                (double)(x_cross*i*j);

         tmpy = (double)(i)*cosa         -
                (double)(j)*sina         +
                (double)(y_displace)     +
                (double)(y_num*fi/y_div) +
                (double)(y_cross*i*j);

         if(x_stretch != 0.0)
            tmpx = tmpx - (double)(fj*cosa + fi*sina);
         if(y_stretch != 0.0)
            tmpy = tmpy - (double)(fi*cosa - fj*sina);

         new_j = tmpx;
         new_i = tmpy;

         if(bilinear == 0){
            if(new_j < 0       ||
               new_j >= cols   ||
               new_i < 0       ||
               new_i >= rows)
               out_image[i][j] = FILL;
            else
               out_image[i][j] =
                the_image[new_i][new_j];
         }  /* ends if bilinear */
         else{
            out_image[i][j] = 
               bilinear_interpolate(the_image,
                                    tmpx, tmpy,
                                    rows, cols);
         }  /* ends bilinear if */

      }  /* ends loop over j */
   }  /* ends loop over i */

}  /* ends geometry */




     /*******************************************
     *
     *   arotate(..
     *
     *   This routine performs rotation about
     *   any point m,n.
     *
     *   The basic equations are:
     *
     *   new x = x.cos(a) - y.sin(a)
     *           -m.cos(a) + m + n.sin(a)
     *
     *   new y = y.cos(a) + x.sin(a)
     *           -m.sin(a) - n.cos(a) + n
     *
     *******************************************/

arotate(the_image, out_image,
        angle,
        m, n, bilinear,
        rows, cols)
   float  angle;
   int    bilinear;
   long   cols, rows;
   short  **the_image,
          **out_image,
          m, n;
{
   double cosa, sina, radian_angle, tmpx, tmpy;
   int    i, j, new_i, new_j;


      /* the following magic number is from
         180 degrees divided by pi */
   radian_angle = angle/57.29577951;
   cosa  = cos(radian_angle);
   sina  = sin(radian_angle);

      /**************************
      *
      *   Loop over image array
      *
      **************************/

   printf("\n");
   for(i=0; i<rows; i++){
      if( (i%10) == 0) printf("%d ", i);
      for(j=0; j<cols; j++){

     /******************************************
     *
     *   new x = x.cos(a) - y.sin(a)
     *           -m.cos(a) + m + n.sin(a)
     *
     *   new y = y.cos(a) + x.sin(a)
     *           -m.sin(a) - n.cos(a) + n
     *
     *******************************************/

         tmpx = (double)(j)*cosa    -
                (double)(i)*sina    -
                (double)(m)*cosa    +
                (double)(m)         +
                (double)(n)*sina;

         tmpy = (double)(i)*cosa    +
                (double)(j)*sina    -
                (double)(m)*sina    -
                (double)(n)*cosa    +
                (double)(n);

         new_j = tmpx;
         new_i = tmpy;

         if(bilinear == 0){
            if(new_j < 0       ||
               new_j >= cols   ||
               new_i < 0       ||
               new_i >= rows)
               out_image[i][j] = FILL;
            else
               out_image[i][j] =
                the_image[new_i][new_j];
         }  /* ends if bilinear */
         else{
            out_image[i][j] = 
               bilinear_interpolate(the_image,
                                    tmpx, tmpy,
                                    rows, cols);
         }  /* ends bilinear if */

      }  /* ends loop over j */
   }  /* ends loop over i */

}  /* ends arotate */





     /*******************************************
     *
     *   bilinear_interpolate(..
     *
     *   This routine performs bi-linear
     *   interpolation.
     *
     *   If x or y is out of range, i.e. less
     *   than zero or greater than rows or cols,
     *   this routine returns a zero.
     *
     *   If x and y are both in range, this
     *   routine interpolates in the horizontal
     *   and vertical directions and returns
     *   the proper gray level.
     *
     *******************************************/

bilinear_interpolate(the_image, x, y, rows, cols)
   double x, y;
   long   cols, rows;
   short  **the_image;
{
   double fraction_x, fraction_y,
          one_minus_x, one_minus_y,
          tmp_double;
   int    ceil_x, ceil_y, floor_x, floor_y;
   short  p1, p2, p3, result = FILL;

      /******************************
      *
      *   If x or y is out of range,
      *   return a FILL.
      *
      *******************************/

   if(x < 0.0               ||
      x >= (double)(cols-1)   ||
      y < 0.0               ||
      y >= (double)(rows-1))
      return(result);

   tmp_double = floor(x);
   floor_x    = tmp_double;
   tmp_double = floor(y);
   floor_y    = tmp_double;
   tmp_double = ceil(x);
   ceil_x     = tmp_double;
   tmp_double = ceil(y);
   ceil_y     = tmp_double;

   fraction_x = x - floor(x);
   fraction_y = y - floor(y);

   one_minus_x = 1.0 - fraction_x;
   one_minus_y = 1.0 - fraction_y;

   tmp_double = one_minus_x * 
          (double)(the_image[floor_y][floor_x]) +
          fraction_x * 
          (double)(the_image[floor_y][ceil_x]);
   p1         = tmp_double;

   tmp_double = one_minus_x * 
          (double)(the_image[ceil_y][floor_x]) +
          fraction_x * 
          (double)(the_image[ceil_y][ceil_x]);
   p2         = tmp_double;

   tmp_double = one_minus_y * (double)(p1) +
          fraction_y * (double)(p2);
   p3         = tmp_double;


   return(p3);

}  /* ends bilinear_interpolate */



#ifdef NEVER

     /*******************************************
     *
     *   get_geometry_options(..
     *
     *   This routine interacts with the user
     *   to obtain the parameters to call the
     *   geometry operations subroutines.
     *
     *******************************************/

get_geometry_options(operation, angle, 
                     x_displace, y_displace, 
                     x_stretch, y_stretch, 
                     x_cross,  y_cross, 
                     bilinear, m, n)
   char  operation[];
   int   *bilinear;
   short *m, *n, *x_displace, *y_displace;
   float *angle,
         *x_cross, *y_cross, 
         *x_stretch, *y_stretch;
{
   int not_finished, response;
   not_finished = 1;
   while(not_finished){

      printf("\nThe geomety options are:");
      printf("\n\t1. Operation is %s", operation);
      printf("\n\t2. Angle is %f", *angle);
      printf("\n\t3. x-displace=%d y-displace=%d",
         *x_displace, *y_displace);
      printf("\n\t4. x-stretch=%f y-stretch=%f",
         *x_stretch, *y_stretch);
      printf("\n\t5. x-cross=%f y-cross=%f",
         *x_cross, *y_cross);
      printf("\n\t6. bilinear = %d", *bilinear);
      printf("\n\t7. rotation points m=%d n=%d",
         *m, *n);
      printf("\n\nExamples:");
      printf("\ngeometry needs: angle");
      printf(" x-displace y-displace");
      printf(" x-stretch y-stretch");
      printf("\n                x-cross y-cross");
      printf(" bilinear (1 or 0)");
      printf("\nrotate needs: angle m n");
      printf(" bilinear (1 or 0)");
      printf("\n\nEnter choice (0 = no change) _\b");
      get_integer(&response);

      if(response == 0)
         not_finished = 0;

      if(response == 1){
         printf("\nEnter operation:");
         gets(operation);
      }  /* ends if 1 */

      if(response == 2){
         printf("\nEnter angle: ___\b\b\b");
         get_float(angle);
      }  /* ends if 2 */

      if(response == 3){
         printf("\nEnter x-displace: ___\b\b\b");
         get_integer(x_displace);
         printf("\nEnter y-displace: ___\b\b\b");
         get_integer(y_displace);
      }  /* ends if 3 */

      if(response == 4){
         printf("\nEnter x-stretch: ___\b\b\b");
         get_float(x_stretch);
         printf("\nEnter y-stretch: ___\b\b\b");
         get_float(y_stretch);
      }  /* ends if 4 */

      if(response == 5){
         printf("\nEnter x-cross: ___\b\b\b");
         get_float(x_cross);
         printf("\nEnter y-cross: ___\b\b\b");
         get_float(y_cross);
      }  /* ends if 5 */

      if(response == 6){
         printf("\nEnter bilinear: _\b");
         get_integer(bilinear);
      }  /* ends if 6 */

      if(response == 7){
         printf("\nEnter rotation point m: _\b");
         get_integer(m);
         printf("\nEnter rotation point n: _\b");
         get_integer(n);
      }  /* ends if 7 */


   }  /* ends while not_finished */

}  /* ends get_geometry_options */

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -