37 #ifndef VIGRA_LABELIMAGE_HXX 
   38 #define VIGRA_LABELIMAGE_HXX 
   43 #include "stdimage.hxx" 
   44 #include "union_find.hxx" 
   45 #include "sized_int.hxx" 
   46 #include "multi_shape.hxx" 
  187 template <
class SrcIterator, 
class SrcAccessor,
 
  188           class DestIterator, 
class DestAccessor,
 
  189           class EqualityFunctor>
 
  190 unsigned int labelImage(SrcIterator upperlefts,
 
  191                         SrcIterator lowerrights, SrcAccessor sa,
 
  192                         DestIterator upperleftd, DestAccessor da,
 
  193                         bool eight_neighbors, EqualityFunctor equal)
 
  195     typedef typename DestAccessor::value_type LabelType;
 
  197     int w = lowerrights.x - upperlefts.x;
 
  198     int h = lowerrights.y - upperlefts.y;
 
  201     const Diff2D neighbor[] = {
 
  208     const int left = 0,  top = 2, topright = 3;
 
  209     int step = eight_neighbors ? 1 : 2;
 
  211     SrcIterator ys = upperlefts;
 
  212     DestIterator yd = upperleftd;
 
  214     UnionFindArray<LabelType>  label;
 
  231     for(y = 0; y != h; ++y, ++ys.y, ++yd.y)
 
  234         DestIterator xd = yd;
 
  236         int endNeighbor = (y == 0) ? left : (eight_neighbors ? topright : top);
 
  238         for(x = 0; x != w; ++x, ++xs.x, ++xd.x)
 
  240             int beginNeighbor = (x == 0) ? top : left;
 
  241             if(x == w-1 && endNeighbor == topright) endNeighbor = top;
 
  243             for(i=beginNeighbor; i<=endNeighbor; i+=step)
 
  245                 if(equal(sa(xs), sa(xs, neighbor[i])))
 
  247                     LabelType neighborIndex = label.findIndex(da(xd,neighbor[i]));
 
  249                     for(
int j=i+2; j<=endNeighbor; j+=step)
 
  251                         if(equal(sa(xs), sa(xs, neighbor[j])))
 
  253                             neighborIndex = label.makeUnion(da(xd, neighbor[j]), neighborIndex);
 
  257                     da.set(neighborIndex, xd);
 
  264                 da.set(label.makeNewIndex(), xd);
 
  271     unsigned int count = label.makeContiguous();
 
  274     for(y=0; y != h; ++y, ++yd.y)
 
  276         typename DestIterator::row_iterator xd = yd.rowIterator();
 
  277         for(x = 0; x != w; ++x, ++xd)
 
  279             da.set(label.findLabel(da(xd)), xd);
 
  285 template <
class SrcIterator, 
class SrcAccessor,
 
  286           class DestIterator, 
class DestAccessor>
 
  288 unsigned int labelImage(SrcIterator upperlefts,
 
  289                         SrcIterator lowerrights, SrcAccessor sa,
 
  290                         DestIterator upperleftd, DestAccessor da,
 
  291                         bool eight_neighbors)
 
  293     return labelImage(upperlefts, lowerrights, sa,
 
  294                  upperleftd, da, eight_neighbors,
 
  295                  std::equal_to<typename SrcAccessor::value_type>());
 
  298 template <
class SrcIterator, 
class SrcAccessor,
 
  299           class DestIterator, 
class DestAccessor,
 
  300           class EqualityFunctor>
 
  302 labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
 
  303            pair<DestIterator, DestAccessor> dest,
 
  304            bool eight_neighbors, EqualityFunctor equal)
 
  306     return labelImage(src.first, src.second, src.third,
 
  307                       dest.first, dest.second, eight_neighbors, equal);
 
  310 template <
class SrcIterator, 
class SrcAccessor,
 
  311           class DestIterator, 
class DestAccessor>
 
  313 labelImage(triple<SrcIterator, SrcIterator, SrcAccessor> src,
 
  314            pair<DestIterator, DestAccessor> dest,
 
  315            bool eight_neighbors)
 
  317     return labelImage(src.first, src.second, src.third,
 
  318                       dest.first, dest.second, eight_neighbors,
 
  319                       std::equal_to<typename SrcAccessor::value_type>());
 
  322 template <
class T1, 
class S1,
 
  324           class EqualityFunctor>
 
  326 labelImage(MultiArrayView<2, T1, S1> 
const & src,
 
  327            MultiArrayView<2, T2, S2> dest,
 
  328            bool eight_neighbors, EqualityFunctor equal)
 
  330     vigra_precondition(src.shape() == dest.shape(),
 
  331         "labelImage(): shape mismatch between input and output.");
 
  333                       destImage(dest), eight_neighbors, equal);
 
  336 template <
class T1, 
class S1,
 
  339 labelImage(MultiArrayView<2, T1, S1> 
const & src,
 
  340            MultiArrayView<2, T2, S2> dest,
 
  341            bool eight_neighbors)
 
  344                       destImage(dest), eight_neighbors,
 
  345                       std::equal_to<T1>());
 
  488 template <
class SrcIterator, 
class SrcAccessor,
 
  489           class DestIterator, 
class DestAccessor,
 
  490           class ValueType, 
class EqualityFunctor>
 
  492     SrcIterator upperlefts,
 
  493     SrcIterator lowerrights, SrcAccessor sa,
 
  494     DestIterator upperleftd, DestAccessor da,
 
  495     bool eight_neighbors,
 
  496     ValueType background_value, EqualityFunctor equal)
 
  498     int w = lowerrights.x - upperlefts.x;
 
  499     int h = lowerrights.y - upperlefts.y;
 
  502     const Diff2D neighbor[] = {
 
  509     const int left = 0,  top = 2, topright = 3;
 
  510     int step = eight_neighbors ? 1 : 2;
 
  512     SrcIterator ys(upperlefts);
 
  516     typedef BasicImage<IntBiggest> TmpImage;
 
  517     TmpImage labelimage(w, h);
 
  518     TmpImage::ScanOrderIterator label = labelimage.begin();
 
  519     TmpImage::Iterator yt = labelimage.upperLeft();
 
  520     TmpImage::Iterator  xt(yt);
 
  525     for(y = 0; y != h; ++y, ++ys.y, ++yt.y)
 
  530         int endNeighbor = (y == 0) ? left : (eight_neighbors ? topright : top);
 
  532         for(x = 0; x != w; ++x, ++xs.x, ++xt.x)
 
  534             if(equal(sa(xs), background_value))
 
  540                 int beginNeighbor = (x == 0) ? top : left;
 
  541                 if(x == w-1 && endNeighbor == topright) endNeighbor = top;
 
  543                 for(i=beginNeighbor; i<=endNeighbor; i+=step)
 
  545                     if(equal(sa(xs), sa(xs, neighbor[i])))
 
  549                         for(
int j=i+2; j<=endNeighbor; j+=step)
 
  551                             if(equal(sa(xs), sa(xs, neighbor[j])))
 
  555                                 if(neighborIndex != neighborLabel1)
 
  558                                     while(neighborIndex != label[neighborIndex])
 
  560                                         neighborIndex = label[neighborIndex];
 
  562                                     while(neighborLabel1 != label[neighborLabel1])
 
  564                                         neighborLabel1 = label[neighborLabel1];
 
  568                                     if(neighborLabel1 < neighborIndex)
 
  570                                         label[neighborIndex] = neighborLabel1;
 
  571                                         neighborIndex = neighborLabel1;
 
  573                                     else if(neighborIndex < neighborLabel1)
 
  575                                         label[neighborLabel1] = neighborIndex;
 
  599     DestIterator yd(upperleftd);
 
  603     for(y=0; y != h; ++y, ++yd.y)
 
  606         for(x = 0; x != w; ++x, ++xd.x, ++i)
 
  608             if(label[i] == -1) 
continue;
 
  616                 label[i] = label[label[i]];
 
  618             da.set(label[i]+1, xd);
 
  625 template <
class SrcIterator, 
class SrcAccessor,
 
  626           class DestIterator, 
class DestAccessor,
 
  630     SrcIterator upperlefts,
 
  631     SrcIterator lowerrights, SrcAccessor sa,
 
  632     DestIterator upperleftd, DestAccessor da,
 
  633     bool eight_neighbors,
 
  634     ValueType background_value)
 
  638                             eight_neighbors, background_value,
 
  639                             std::equal_to<typename SrcAccessor::value_type>());
 
  642 template <
class SrcIterator, 
class SrcAccessor,
 
  643           class DestIterator, 
class DestAccessor,
 
  644           class ValueType, 
class EqualityFunctor>
 
  647                          pair<DestIterator, DestAccessor> dest,
 
  648                          bool eight_neighbors,
 
  649                          ValueType background_value, EqualityFunctor equal)
 
  652                                     dest.first, dest.second,
 
  653                                     eight_neighbors, background_value, equal);
 
  656 template <
class SrcIterator, 
class SrcAccessor,
 
  657           class DestIterator, 
class DestAccessor,
 
  661                          pair<DestIterator, DestAccessor> dest,
 
  662                          bool eight_neighbors,
 
  663                          ValueType background_value)
 
  666                                     dest.first, dest.second,
 
  667                                     eight_neighbors, background_value,
 
  668                                     std::equal_to<typename SrcAccessor::value_type>());
 
  671 template <
class T1, 
class S1,
 
  673           class ValueType, 
class EqualityFunctor>
 
  676                          MultiArrayView<2, T2, S2> dest,
 
  677                          bool eight_neighbors,
 
  678                          ValueType background_value, EqualityFunctor equal)
 
  680     vigra_precondition(src.shape() == dest.shape(),
 
  681         "labelImageWithBackground(): shape mismatch between input and output.");
 
  684                                     eight_neighbors, background_value, equal);
 
  687 template <
class T1, 
class S1,
 
  692                          MultiArrayView<2, T2, S2> dest,
 
  693                          bool eight_neighbors,
 
  694                          ValueType background_value)
 
  696     vigra_precondition(src.shape() == dest.shape(),
 
  697         "labelImageWithBackground(): shape mismatch between input and output.");
 
  700                                     eight_neighbors, background_value,
 
  701                                     std::equal_to<T1>());
 
  711 enum EdgeImageLabelPolicy { CopyRegionLabels, EdgeOverlayOnly };
 
  865 template <
class SrcIterator, 
class SrcAccessor,
 
  866           class DestIterator, 
class DestAccessor, 
class DestValue>
 
  868                SrcIterator sul, SrcIterator slr, SrcAccessor sa,
 
  869                DestIterator dul, DestAccessor da,
 
  870                DestValue edge_marker,
 
  871                EdgeImageLabelPolicy labelPolicy = CopyRegionLabels)
 
  873     int w = slr.x - sul.x;
 
  874     int h = slr.y - sul.y;
 
  877     const Diff2D right(1,0);
 
  878     const Diff2D left(-1,0);
 
  879     const Diff2D bottomright(1,1);
 
  880     const Diff2D bottom(0,1);
 
  881     const Diff2D top(0,-1);
 
  883     SrcIterator iy = sul;
 
  884     DestIterator dy = dul;
 
  886     for(y=0; y<h-1; ++y, ++iy.y, dy.y+=2)
 
  889         DestIterator dx = dy;
 
  891         for(x=0; x<w-1; ++x, ++ix.x, dx.x+=2)
 
  893             if(labelPolicy == CopyRegionLabels)
 
  896                 da.set(sa(ix), dx, bottomright);
 
  899             if(sa(ix, right) != sa(ix))
 
  901                 da.set(edge_marker, dx, right);
 
  903             else if(labelPolicy == CopyRegionLabels)
 
  905                 da.set(sa(ix), dx, right);
 
  907             if(sa(ix, bottom) != sa(ix))
 
  909                 da.set(edge_marker, dx, bottom);
 
  911             else if(labelPolicy == CopyRegionLabels)
 
  913                 da.set(sa(ix), dx, bottom);
 
  918         if(labelPolicy == CopyRegionLabels)
 
  922         if(sa(ix, bottom) != sa(ix))
 
  924             da.set(edge_marker, dx, bottom);
 
  926         else if(labelPolicy == CopyRegionLabels)
 
  928             da.set(sa(ix), dx, bottom);
 
  933     DestIterator dx = dy;
 
  935     for(x=0; x<w-1; ++x, ++ix.x, dx.x+=2)
 
  937         if(labelPolicy == CopyRegionLabels)
 
  941         if(sa(ix, right) != sa(ix))
 
  943             da.set(edge_marker, dx, right);
 
  945         else if(labelPolicy == CopyRegionLabels)
 
  947             da.set(sa(ix), dx, right);
 
  950     if(labelPolicy == CopyRegionLabels)
 
  954     dy = dul + Diff2D(1,1);
 
  956     const Diff2D dist[] = {right, top, left, bottom };
 
  958     for(y=0; y<h-1; ++y, dy.y+=2)
 
  960         DestIterator dx = dy;
 
  962         for(x=0; x<w-1; ++x, dx.x+=2)
 
  967                 if(da(dx, dist[i]) == edge_marker) 
break;
 
  970             if(i < 4) da.set(edge_marker, dx);
 
  975 template <
class SrcIterator, 
class SrcAccessor,
 
  976           class DestIterator, 
class DestAccessor, 
class DestValue>
 
  979                             pair<DestIterator, DestAccessor> dest,
 
  980                             DestValue edge_marker,
 
  981                             EdgeImageLabelPolicy labelPolicy = CopyRegionLabels)
 
  984                                 dest.first, dest.second,
 
  985                                 edge_marker, labelPolicy);
 
  988 template <
class T1, 
class S1,
 
  989           class T2, 
class S2, 
class DestValue>
 
  992                             MultiArrayView<2, T2, S2> dest,
 
  993                             DestValue edge_marker,
 
  994                             EdgeImageLabelPolicy labelPolicy = CopyRegionLabels)
 
  996     vigra_precondition(2*src.shape()-Shape2(1) == dest.shape(),
 
  997         "regionImageToCrackEdgeImage(): shape mismatch between input and output.");
 
 1127 template <
class SrcIterator, 
class SrcAccessor,
 
 1128           class DestIterator, 
class DestAccessor, 
class DestValue>
 
 1130                SrcIterator sul, SrcIterator slr, SrcAccessor sa,
 
 1131                DestIterator dul, DestAccessor da,
 
 1132                DestValue edge_marker)
 
 1134     int w = slr.x - sul.x;
 
 1135     int h = slr.y - sul.y;
 
 1138     const Diff2D right(1,0);
 
 1139     const Diff2D left(-1,0);
 
 1140     const Diff2D bottomright(1,1);
 
 1141     const Diff2D bottom(0,1);
 
 1142     const Diff2D top(0,-1);
 
 1144     SrcIterator iy = sul;
 
 1145     DestIterator dy = dul;
 
 1147     for(y=0; y<h-1; ++y, ++iy.y, ++dy.y)
 
 1149         SrcIterator ix = iy;
 
 1150         DestIterator dx = dy;
 
 1152         for(x=0; x<w-1; ++x, ++ix.x, ++dx.x)
 
 1154             if(sa(ix, right) != sa(ix))
 
 1156                 da.set(edge_marker, dx);
 
 1158             if(sa(ix, bottom) != sa(ix))
 
 1160                 da.set(edge_marker, dx);
 
 1164         if(sa(ix, bottom) != sa(ix))
 
 1166             da.set(edge_marker, dx);
 
 1170     SrcIterator ix = iy;
 
 1171     DestIterator dx = dy;
 
 1173     for(x=0; x<w-1; ++x, ++ix.x, ++dx.x)
 
 1175         if(sa(ix, right) != sa(ix))
 
 1177             da.set(edge_marker, dx);
 
 1182 template <
class SrcIterator, 
class SrcAccessor,
 
 1183           class DestIterator, 
class DestAccessor, 
class DestValue>
 
 1186                        pair<DestIterator, DestAccessor> dest,
 
 1187                        DestValue edge_marker)
 
 1190                            dest.first, dest.second,
 
 1194 template <
class T1, 
class S1,
 
 1195           class T2, 
class S2, 
class DestValue>
 
 1198                        MultiArrayView<2, T2, S2> dest,
 
 1199                        DestValue edge_marker)
 
 1201     vigra_precondition(src.shape() == dest.shape(),
 
 1202         "regionImageToEdgeImage(): shape mismatch between input and output.");
 
 1212 #endif // VIGRA_LABELIMAGE_HXX 
unsigned int labelImage(...)
Find the connected components of a segmented image. 
unsigned int labelImageWithBackground(...)
Find the connected components of a segmented image, excluding the background from labeling...
void regionImageToEdgeImage(...)
Transform a labeled image into an edge image. 
doxygen_overloaded_function(template<...> void separableConvolveBlockwise) template< unsigned int N
Separated convolution on ChunkedArrays. 
void regionImageToCrackEdgeImage(...)
Transform a labeled image into a crack edge (interpixel edge) image. 
detail::SelectBiggestIntegerType< detail::SignedIntTypes >::type IntBiggest
the biggest signed integer type of the system 
Definition: sized_int.hxx:188