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

📄 skeleton.c

📁 This is code tutorial for image processing include:histogram,sketon....
💻 C
📖 第 1 页 / 共 3 页
字号:

       /**********************************************
       *
       *       file skeleton.c
       *
       *       Functions: This file contains
       *          thinning
       *          can_thin
       *          dilate_not_join
       *          can_dilate
       *          little_label_and_check
       *          special_closing
       *          special_opening
       *          edm
       *          distanc_8
       *          mat
       *          mat_d
       *
       *       Purpose:
       *          These functions thin objects in
       *          an image, dilate objects, and
       *          perform opening and closing
       *          without removing or joining
       *          objects.
       *
       *       External Calls:
       *          none
       *
       *
       *       Modifications:
       *          7 March 1993 - created
       *         21 August 1998 - modified to work on entire
       *              images at once.
       *
       ************************************************/

#include "cips.h"





     /*******************************************
     *
     *   special_opening(...
     *
     *   Opening is erosion followed by dilation.
     *   This routine will use the thinning
     *   erosion routine.  This will not allow
     *   an object to erode to nothing.
     *
     *   The number parameter specifies how
     *   erosions to perform before doing one
     *   dilation.
     *
     *******************************************/

special_opening(the_image, out_image, 
                value, threshold, number,
                rows, cols) 
   int    number;
   short  **the_image,
          **out_image,
          threshold, value;
   long   cols, rows;
{
   int    a, b, count, i, j, k;

   thinning(the_image, out_image, 
            value, threshold, 1, 
            rows, cols);

   if(number > 1){
      count = 1;
      while(count < number){
         count++;
         thinning(the_image, out_image, 
                  value, threshold, 1,
                  rows, cols);
      }  /* ends while */
   }  /* ends if number > 1 */

   dilation(the_image, out_image, 
            value, threshold,
            rows, cols);

}  /* ends special_opening */






     /*******************************************
     *
     *   thinning(...
     *
     *   Use a variation of the grass fire
     *   wave front approach.
     *
     *   Raster scan the image left to right
     *   and examine and thin the left edge pixels
     *   (a 0 to value transition).  Process them
     *   normally and "save" the result.  Next,
     *   raster scan the image right to left and
     *   save.  Raster scan top to bottom and save.
     *   Raster scan bottom to top and save.
     *
     *   That is one complete pass.
     *
     *   Keep track of pixels thinned for a
     *   pass and quit when you make a complete
     *   pass without thinning any pixels.
     *
     *******************************************/


thinning(the_image, out_image,
         value, threshold, once_only,
         rows, cols)
   int    once_only;
   short  **the_image,
          **out_image,
          threshold, value;
   long   cols, rows;
{
   int    a, b, big_count, count, i, j, k,
          not_finished;

   for(i=0; i<rows; i++)
      for(j=0; j<cols; j++)
         out_image[i][j] = the_image[i][j];

   not_finished = 1;
   while(not_finished){

      if(once_only == 1)
        not_finished = 0;
      big_count = 0;

         /***************************
         *
         *   Scan left to right
         *   Look for 0-value transition
         *
         ****************************/

      printf("\n");
      for(i=1; i<rows-1; i++){
         if( (i%10) == 0) printf("%3d", i);
         for(j=1; j<cols-1; j++){
            if(the_image[i][j-1] == 0   &&
               the_image[i][j]   == value){
               count = 0;
               for(a=-1; a<=1; a++){
                   for(b=-1; b<=1; b++){
                         if(the_image[i+a][j+b] == 0)
                            count++;
                   }  /*  ends loop over b */
               }  /* ends loop over a */
               if(count > threshold){
                  if(can_thin(the_image, i, j, value)){
                     out_image[i][j] = 0;
                     big_count++;
                  }  /* ends if can_thin */
               }  /* ends if count > threshold */
            }  /* ends if the_image == value */
         }  /* ends loop over j */
      }  /* ends loop over i */

         /**************************************
         *
         *   Copy the output back to the input.
         *
         **************************************/

      for(i=0; i<rows; i++)
         for(j=0; j<cols; j++)
            the_image[i][j] = out_image[i][j];


         /***************************
         *
         *   Scan right to left
         *   Do this by scanning left
         *   to right and look for
         *   value-0 transition.
         *
         ****************************/

      printf("\n");
      for(i=1; i<rows-1; i++){
         if( (i%10) == 0) printf("%3d", i);
         for(j=1; j<cols-1; j++){
            if(the_image[i][j+1] == 0   &&
               the_image[i][j]   == value){
               count = 0;
               for(a=-1; a<=1; a++){
                   for(b=-1; b<=1; b++){
                         if(the_image[i+a][j+b] == 0)
                            count++;
                   }  /*  ends loop over b */
               }  /* ends loop over a */
               if(count > threshold){
                  if(can_thin(the_image, i, j, value)){
                     out_image[i][j] = 0;
                     big_count++;
                  }  /* ends if can_thin */
               }  /* ends if count > threshold */
            }  /* ends if the_image == value */
         }  /* ends loop over j */
      }  /* ends loop over i */

         /**************************************
         *
         *   Copy the output back to the input.
         *
         **************************************/

      for(i=0; i<rows; i++)
         for(j=0; j<cols; j++)
            the_image[i][j] = out_image[i][j];


         /***************************
         *
         *   Scan top to bottom
         *   Look for 0-value transition
         *
         ****************************/

      printf("\n");
      for(j=1; j<cols-1; j++){
         if( (j%10) == 0) printf("%3d", j);
         for(i=1; i<rows-1; i++){
            if(the_image[i-1][j] == 0   &&
               the_image[i][j]   == value){
               count = 0;
               for(a=-1; a<=1; a++){
                   for(b=-1; b<=1; b++){
                         if(the_image[i+a][j+b] == 0)
                            count++;
                   }  /*  ends loop over b */
               }  /* ends loop over a */
               if(count > threshold){
                  if(can_thin(the_image, i, j, value)){
                     out_image[i][j] = 0;
                     big_count++;
                  }  /* ends if can_thin */
               }  /* ends if count > threshold */
            }  /* ends if the_image == value */
         }  /* ends loop over i */
      }  /* ends loop over j */

         /**************************************
         *
         *   Copy the output back to the input.
         *
         **************************************/

      for(i=0; i<rows; i++)
         for(j=0; j<cols; j++)
            the_image[i][j] = out_image[i][j];



         /***************************
         *
         *   Scan bottom to top
         *   Do this by scanning top
         *   to bottom and look for
         *   value-0 transition.
         *
         ****************************/

      printf("\n");
      for(j=1; j<cols-1; j++){
         if( (j%10) == 0) printf("%3d", j);
         for(i=1; i<rows-1; i++){
            if(the_image[i+1][j] == 0   &&
               the_image[i][j]   == value){
               count = 0;
               for(a=-1; a<=1; a++){
                   for(b=-1; b<=1; b++){
                         if(the_image[i+a][j+b] == 0)
                            count++;
                   }  /*  ends loop over b */
               }  /* ends loop over a */
               if(count > threshold){
                  if(can_thin(the_image, i, j, value)){
                     out_image[i][j] = 0;
                     big_count++;
                  }  /* ends if can_thin */
               }  /* ends if count > threshold */
            }  /* ends if the_image == value */
         }  /* ends loop over i */
      }  /* ends loop over j */

         /**************************************
         *
         *   Copy the output back to the input.
         *
         **************************************/

      for(i=0; i<rows; i++)
         for(j=0; j<cols; j++)
            the_image[i][j] = out_image[i][j];

         /**************************************
         *
         *   Now look at the result of this big
         *   pass through the image.
         *
         ***************************************/

      printf("\n\nThinned %d pixels", big_count);
      if(big_count == 0)
         not_finished = 0;
      else{
         for(i=0; i<rows; i++)
            for(j=0; j<cols; j++)
               the_image[i][j] = out_image[i][j];
      }  /* ends else */

   }  /* ends while not_finished */

   /****
   fix_edges(out_image, 3, rows, cols);
   *****/

}  /* ends thinning */





     /*******************************************
     *
     *   can_thin(...
     *
     *   Look at the neighbors of the center pixel.
     *   If a neighbor == value, then it must
     *   have a neighbor == value other than the
     *   center pixel.
     *
     *   Procedure:
     *   . Copy the 3x3 area surrounding pixel
     *     i,j to a temp array.
     *   . Set the center pixel to zero.
     *   . Look at each non-zero pixel in temp.
     *      . If you cannot find a non-zero
     *        neighbor.
     *      . Then you cannot thin.
     *
     *******************************************/

can_thin(the_image, i, j, value)
   int   i, j;
   short **the_image, value;
{
   int   a, b, c, d, count,
         no_neighbor, one=1, zero=0;
   short temp[3][3];

       /**************************************
       *
       *   Copy the center pixel and its
       *   neighbors to the temp array.
       *
       ***************************************/

   for(a=-1; a<2; a++)
      for(b=-1; b<2; b++)
         temp[a+1][b+1] = the_image[i+a][b+j];

       /**************************************
       *
       *   Set the center of temp to 0.
       *
       ***************************************/

   temp[1][1] = 0;

       /**************************************
       *
       *   Check the non-zero pixels in temp.
       *
       ***************************************/

   for(a=0; a<3; a++){
      for(b=0; b<3; b++){
         if(temp[a][b] == value){
            temp[a][b] = 0;

                /*********************************
                *
                *   Check the neighbors of this pixel
                *   If there is a single non-zero
                *   neighbor, set no_neighbor = 0.
                *
                **********************************/

            no_neighbor = 1;
            for(c=-1; c<2; c++){
               for(d=-1; d<2; d++){
                  if( ((a+c) >= 0)   &&
                      ((a+c) <= 2)   &&
                      ((b+d) >= 0)   &&
                      ((b+d) <= 2)){
                     if(temp[a+c][b+d] == value){
                        no_neighbor = 0;
                     }  /* ends if temp == value */
                  }  /* ends if part of temp array */
               }  /* ends loop over d */
            }  /* ends loop over c */
            temp[a][b] = value;

                /*********************************
                *
                *   If the non-zero pixel did not
                *   have any non-zero neighbors,
                *   no_neighbor still equals 1,
                *   and we cannot thin, so return
                *   zero.
                *
                **********************************/

            if(no_neighbor){
               return(zero);
            }
         }  /* ends if temp[a][b] == value */
      }  /* ends loop over b */
   }  /* ends loop over a */

       /**************************************
       *
       *   First, ensure the object is more
       *   than two wide.  If it is two wide,
       *   you will thin out the entire object.
       *   Check in all eight directions.
       *   If the distance to a zero is 0 or
       *   >= 2, then ok you can thin so go
       *   on to the remainder of this routine.
       *   If not, you cannot thin so return
       *   zero.
       *
       ***************************************/

   return(one);

}  /* ends can_thin */




     /*******************************************
     *
     *   special_closing(...
     *
     *   Closing is dilation followed by erosion.
     *   This routine will use the dilate_not_join
     *   dilation routine.  This will not allow
     *   two separate objects to join.
     *
     *   The number parameter specifies how

⌨️ 快捷键说明

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