Thread: Image Thinning

  1. #1
    Registered User
    Join Date
    Jan 2002
    Posts
    29

    Smile Image Thinning

    Hi Folks,
    I am still working on my degree project of fingerprint matching. I have changed the image of the print so far in the following ways; grey-scale, smooth, Binarized it and now I am thinning it i.e making it one pixel in width (skeleton). I will then be extracting the minutiae points and comparing them to the prints on file. However, I am having some trouble trying to get the results I need with thinning. I have some code to thin an image but instead of thinning it it appears to be making it larger?? I have stepped through it and believe it should work for me. If anyone has experience of thinning I would be grateful for any suggestions.
    Thanks in advance,
    -Colin.
    Code:
    void __fastcall TForm1::ThinningClick(TObject *Sender)
    {
      //THINNING
      int count,count2,row,col;
      int num_transitions ;
      int transitions ;
      int tempimage[297][353]={0};
      int row1,col1;
      for(row = 1; row < Image1->Height-1 ; row++)
        {
        for(col = 1; col < Image1->Width-1 ; col++)
          {
          count = 0;
          num_transitions = 0;
          // check  for N(p)
          if (Image1->Canvas->Pixels[col][row] == 0xFFFFFF)
            {
            if (Image1->Canvas->Pixels[col-1][row-1] != 0)
              count++;
            if (Image1->Canvas->Pixels[col][row-1] != 0)
              count++;
            if (Image1->Canvas->Pixels[col+1][row-1] != 0)
              count++;
            if (Image1->Canvas->Pixels[col+1][row] != 0)
              count++;
            if (Image1->Canvas->Pixels[col-1][row] != 0)
              count++;
            if (Image1->Canvas->Pixels[col+1][row+1] != 0)
              count++;
            if (Image1->Canvas->Pixels[col][row+1] != 0)
              count++;
            if (Image1->Canvas->Pixels[col-1][row+1] != 0)
              count++;
            if (count != 8)
              {
              // 2 <= N(p) <= 6
              if (count >= 2 && count <= 6)
                {
                if(Image1->Canvas->Pixels[col-1][row] == 0 &&
                  Image1->Canvas->Pixels[col-1][row+1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col-1][row+1] == 0 &&
                  Image1->Canvas->Pixels[col][row+1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col][row+1] == 0 &&
                  Image1->Canvas->Pixels[col+1][row+1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row+1] == 0 &&
                  Image1->Canvas->Pixels[col+1][row] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row] == 0 &&
                  Image1->Canvas->Pixels[col+1][row-1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row-1] == 0 &&
                  Image1->Canvas->Pixels[col][row-1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col][row-1] == 0 &&
                  Image1->Canvas->Pixels[col-1][row-1] == 0xFFFFFF)
                  num_transitions++ ;
                if(Image1->Canvas->Pixels[col-1][row-1] == 0 &&
                  Image1->Canvas->Pixels[col-1][row] == 0xFFFFFF)
                  num_transitions++ ;
                //S(p) = 1
                if (num_transitions == 1)
                  {
                  // if p2 * p4 * p6 = 0
                  if (Image1->Canvas->Pixels[col][row-1] == 0 ||  
                    Image1->Canvas->Pixels[col][row+1] == 0 ||
                    Image1->Canvas->Pixels[col+1][row] == 0)
                    {
                    // if p4 * p6 * p8 = 0
                    if(Image1->Canvas->Pixels[col][row+1] == 0 ||
                      Image1->Canvas->Pixels[col+1][row] == 0 ||
                      Image1->Canvas->Pixels[col][row-1] == 0)
                       tempimage[col][row] = 0;
                    else
                      tempimage[col][row] =  0xFFFFFF;
                      }
                  else
                    tempimage[col][row] = 0xFFFFFF;
                  }
                else
                  tempimage[col][row] =  0xFFFFFF;
                }
              else
                tempimage[col][row] =  0xFFFFFF;
              }
            else
              tempimage[col][row] =  0xFFFFFF;
            }
          else
            tempimage[col][row] =0;//0xFFFFFF;
          }
        }
       //copy thinned image back to original
    
        for(row = 0; row < Image1->Height ; row++)
          for(col = 0; col < Image1->Width; col++)
          Image1->Canvas->Pixels[col][row]=tempimage[col][row];
    
       // step 2 of the thinning algorithm
    
       for(row = 1; row < Image1->Height-1 ; row++)
        {
        for(col = 1; col < Image1->Width-1 ; col++)
          {
          count2 = 0;
          transitions = 0;
          if (Image1->Canvas->Pixels[col][row] == 0xFFFFFF)
            {
            if (Image1->Canvas->Pixels[col-1][row-1] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col][row-1] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col+1][row-1] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col+1][row] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col-1][row] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col+1][row+1] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col][row+1] != 0)
              count2++;
            if (Image1->Canvas->Pixels[col-1][row+1] != 0)
              count2++;
    
            if (count2 != 8)
              {
              if (count2 >= 2 && count2 <= 6)
                {
                if(Image1->Canvas->Pixels[col-1][row] == 0 &&
                  Image1->Canvas->Pixels[col-1][row+1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col-1][row+1] == 0 &&
                  Image1->Canvas->Pixels[col][row+1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col][row+1] == 0 &&
                  Image1->Canvas->Pixels[col+1][row+1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row+1] == 0 &&
                  Image1->Canvas->Pixels[col+1][row] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row] == 0 &&
                  Image1->Canvas->Pixels[col+1][row-1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col+1][row-1] == 0 &&
                  Image1->Canvas->Pixels[col][row-1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col][row-1] == 0 &&
                  Image1->Canvas->Pixels[col-1][row-1] == 0xFFFFFF)
                  transitions++ ;
                if(Image1->Canvas->Pixels[col-1][row-1] == 0 &&
                  Image1->Canvas->Pixels[col-1][row] == 0xFFFFFF)
                  transitions++ ;
    
                if (transitions == 1)
                  {
                  // if p2 * p4 * p8 = 0
                  if(Image1->Canvas->Pixels[col][row-1] == 0 ||
                    Image1->Canvas->Pixels[col][row+1] == 0 ||
                    Image1->Canvas->Pixels[col][row-1] == 0)
                    {
                    // if p2 * p4 * p6
                    if(Image1->Canvas->Pixels[col-1][row] == 0 ||
                      Image1->Canvas->Pixels[col+1][row] == 0 ||
                      Image1->Canvas->Pixels[col][row-1] == 0)
                      tempimage[col][row] = 0;
                    else
                      tempimage[col][row] =  0xFFFFFF;
                    }
                  else
                    tempimage[col][row] =  0xFFFFFF;
                  }
                else
                  tempimage[col][row] = 0xFFFFFF;
                }
              else
                tempimage[col][row] =  0xFFFFFF;
              }
            else
              tempimage[col][row] = 0xFFFFFF;
            }
          else
            tempimage[col][row] = 0;
          }
     }
    
       for(row = 0; row < Image1->Height ; row++)
        for(col = 0; col < Image1->Width; col++)
          Image1->Canvas->Pixels[col][row]=tempimage[col][row];
    
    
    }

  2. #2
    C > C++ duders ggs's Avatar
    Join Date
    Aug 2001
    Posts
    435
    It's difficult to look through all that code and find the problem, but I think I understand what you're trying to do, and here's an alternative approach:

    Code:
    loop y from 0 to image y {
    x is 0
    while x < image x {
       if(image[x] == 0xfffffff) {
          runsize is 0
          while(image[x] == 0xffffffff) {
             ++runsize; ++x;
          }
          clear runsize pixels, turn on single pixel in center of run
       }
    }
    Good luck with your project
    .sect signature

  3. #3
    Registered User
    Join Date
    Jan 2002
    Posts
    29

    Smile Image Thinning

    Thanks ggs for your reply.
    I have been working on your suggestion but am having trouble still. Can you explain "runsize" in your code to me in more detail.
    Thanks again for you time,
    -Colin

  4. #4
    wutman
    Guest
    runsize just means the number of pixels in a row that are turned on. you'd use this to find out where the middle pixel is, how many pixels to turn off...

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Problem reading tiff image files?
    By compz in forum C++ Programming
    Replies: 9
    Last Post: 10-30-2009, 04:17 AM
  2. Replies: 1
    Last Post: 05-27-2009, 12:46 PM
  3. Simple Image Processing
    By ejohns85 in forum C++ Programming
    Replies: 4
    Last Post: 03-19-2009, 12:10 PM
  4. image thinning
    By quack in forum C++ Programming
    Replies: 4
    Last Post: 11-06-2003, 10:26 PM
  5. Replies: 4
    Last Post: 03-02-2003, 09:12 AM