Connected Components



 
 

Color Convention
 Blue  Comments 
 Red  Generic Terms
 Yelow  Reserved  words and Commands 
 Brown  Defines
  Link  Link to other functions

 

#include "VsipTypes.h"

/****************************************************************************
 *
 *  Function    : VsipConnectedComponents
 *
 *  Description : Labels an Image. The labels are ordered, begining in zero.
 *                It accepts two different kinds of neighbourhood, 4 (north,
 *                east, south and west) and 8.
 *
 *  Parameters  : src - input image object
 *                rule - kind of neighbourhood (0- 4 neig, 1- 8 neig)
 *
 *  Returns     : Label image
 *
 ****************************************************************************/
$generic

   $VsipConnectedComponents = 'VsipConnectedComponentsBit',  $InType = 'uint1',
        $OutType = 'int32', $Test = '';
   $VsipConnectedComponents = 'VsipConnectedComponentsByte', $InType = 'uint8',
        $OutType = 'int32', $Test = '';
   $VsipConnectedComponents = 'VsipConnectedComponentsByte8', $InType = 'uint8',
        $OutType = 'uint8',
   $Test = 'assert((n > 256),"ERROR: Number of labels exceeds output type.\n");';

$in

$OutType [:,:] $VsipConnectedComponents($InType src[:,:], uint1 rule)
{
 
  // ***** recover the src size *****
  VsipIndexesType r, VsipIndexesType c = extents(src);
 
  // ***** test the sizes of the image  *****
  assert(((r > 0) && (c > 0)),
         "ERROR: Image can not have zero dimention. (",r,"x",c,")\n");

  // ***** Gives an different label for each pixel *****
  int32 aux[:,:] =
       for elem in src at (VsipIndexesType i, VsipIndexesType j)
       return(array(i* c + j));

  // ***** Computes the max label *****
  int32 maxlabel = r * c;

  // ***** Creates the perimeter around the image *****
  int32 aux1[:,:] = src;
  int32 srcper[:,:] = AuxPerimeterInt(aux1, 1, 1, 1, 1, -1);

  // ***** Creates the change variable (necessary for the next command) *****
  bool change = true;

  // ***** Makes pixels that are in the same region to have the same  *****
  // ***** label. That is done by comparing the 4 or 8 neighbourhood  *****
  // ***** In this fase each region finish with the smallest label    *****
  // ***** previosly given for one of its pixels                      *****
  int32 labelimage[:,:] =
       while (change)
            { next change , next aux =
                   for window win[3,3] in srcper at (VsipIndexesType i,
                                       VsipIndexesType j)
                        { int32 labelp = aux[i,j];
                          int32 labeln =
                               if (win[1,1] == win[0,1])
                                    return(aux[i-1,j])
                               else
                                    return(maxlabel);
                          int32 labelw =
                               if (win[1,1] == win[1,0])
                                    return(aux[i,j-1])
                               else
                                    return(maxlabel);
                          int32 labels =
                               if (win[1,1] == win[2,1])
                                    return(aux[i+1,j])
                               else
                                    return(maxlabel);
                          int32 labele =
                               if (win[1,1] == win[1,2])
                                    return(aux[i,j+1])
                               else
                                    return(maxlabel);
                          int32 labelnw =
                               if ((rule == 1) && (win[1,1] == win[0,0]))
                                    return(aux[i-1,j-1])
                               else
                                    return(maxlabel);
                          int32 labelne =
                               if ((rule == 1) && (win[1,1] == win[0,2]))
                                    return(aux[i-1,j+1])
                               else
                                    return(maxlabel);
                          int32 labelsw =
                               if ((rule == 1) && (win[1,1] == win[2,0]))
                                    return(aux[i+1,j-1])
                               else
                                    return(maxlabel);
                          int32 labelse =
                               if ((rule == 1) && (win[1,1] == win[2,2]))
                                    return(aux[i+1,j+1])
                               else
                                    return(maxlabel);
                          int32 label =
                              AuxMin(AuxMin(AuxMin4(labeln,labelw,labels,labele),
                                            AuxMin4(labelnw,labelne,labelsw,labelse)),
                                     labelp);
                          bool b = (labelp == label ? false : true);
 
                        }
                   return(or(b),array(label));
            }
       return(final(aux));
 

  // ***** Histogram the label image so we know which labels are still *****
  // ***** present.                                                    *****
  int32 hist[:] = array_histogram(labelimage,maxlabel);

  // ***** Create auxiliary variables (necessary for next command) *****
  int32 n = 0;
  int32 l = 0;

  // ***** Create a list of labels where the label is 0 if it has no *****
  // ***** elements in the histogram, or and ordered value if it has *****
  int32 list[:] , int32 num =
       for elem in hist
            { next l = (elem > 0 ? n : 0);
              next n = (elem > 0 ? n+1 : n);
            }
       return(array(l), final(n));

   $Test

   // ***** Relabel the image using the ordered list of labels *****
   $OutType result[:,:] =
       for elem in labelimage
       return(array(list[elem]));

} return (result);

$end_generic