segmenterFelzenszwalb.cpp

Go to the documentation of this file.
00001 
00015 #include <dlrComputerVision/segmenterFelzenszwalb.h>
00016 
00017 namespace dlr {
00018 
00019   namespace computerVision {
00020 
00021     SegmenterFelzenszwalb::
00022     SegmenterFelzenszwalb(float k, float sigma, size_t minSegmentSize)
00023       : m_imageSize(0, 0),
00024         m_k(k),
00025         m_minimumSegmentSize(minSegmentSize),
00026         m_segmentation(),
00027         m_sigma(sigma),
00028         m_smoothSize(static_cast<size_t>(std::fabs(6 * sigma + 1)))
00029     {
00030       // Empty.
00031     }
00032 
00033     
00034     Array2D<UnsignedInt32>
00035     SegmenterFelzenszwalb::
00036     getLabelArray()
00037     {
00038       Array2D<UnsignedInt32> labelArray(
00039         m_imageSize.getRow(), m_imageSize.getColumn());
00040 
00041       numeric::Array1D<Segment>::iterator setIter = m_segmentation.begin();
00042       Array2D<UnsignedInt32>::iterator labelIter = labelArray.begin();
00043       while(setIter != m_segmentation.end()) {
00044         Segment& head = setIter->find();
00045 
00046         // Warning(xxx): Assuming we know something about how both
00047         // vectors and DisjointSets are implemented.
00048         UnsignedInt32 labelIndex = static_cast<UnsignedInt32>(
00049           &head - &(m_segmentation[0]));
00050         *labelIter = labelIndex;
00051 
00052         ++labelIter;
00053         ++setIter;
00054       }
00055 
00056       return labelArray;
00057     }
00058 
00059       
00060     Array2D<UnsignedInt32>
00061     SegmenterFelzenszwalb::
00062     getLabelArray(UnsignedInt32& numberOfSegments,
00063                   std::vector<size_t>& segmentSizes)
00064     {
00065       Array2D<UnsignedInt32> labelArray(
00066         m_imageSize.getRow(), m_imageSize.getColumn());
00067       std::vector<UnsignedInt32> labelMap(
00068         m_segmentation.size(), std::numeric_limits<UnsignedInt32>::max());
00069       UnsignedInt32 currentLabel = 0;
00070       segmentSizes.clear();
00071       
00072       // Iterate over each pixel.
00073       numeric::Array1D<Segment>::iterator setIter = m_segmentation.begin();
00074       Array2D<UnsignedInt32>::iterator labelIter = labelArray.begin();
00075       while(setIter != m_segmentation.end()) {
00076 
00077         // Figure out to which segment the current pixel belongs.
00078         // 
00079         // Warning(xxx): Assuming we know something about how both
00080         // vectors and DisjointSets are implemented.
00081         Segment& head = setIter->find();
00082         UnsignedInt32 labelIndex = static_cast<UnsignedInt32>(
00083           &head - &(m_segmentation[0]));
00084 
00085         // Have we labeled this segment yet?
00086         if(labelMap[labelIndex] > currentLabel) {
00087           // No.  Label it now and remember how big the segment is.
00088           labelMap[labelIndex] = currentLabel;
00089           segmentSizes.push_back(head.getSize());
00090           ++currentLabel;
00091         }
00092         // Record the label in our output label image.
00093         *labelIter = labelMap[labelIndex];
00094 
00095         // Move on to next pixel.
00096         ++labelIter;
00097         ++setIter;
00098       }
00099 
00100       numberOfSegments = currentLabel;
00101       return labelArray;
00102     }
00103 
00104 
00105     std::vector<SegmenterFelzenszwalb::Edge>
00106     SegmenterFelzenszwalb::
00107     getEdges(const Image<GRAY_FLOAT32>& inImage)
00108     {
00109       // 8-connected means 4 undirected edges per pixel.
00110       size_t numEdges = 4 * inImage.size();
00111 
00112       // Except that some point off the side of the image.
00113       numEdges -= 3 * inImage.rows();
00114 
00115       // And some point off the bottom/top of the image.
00116       numEdges -= 3 * inImage.columns();
00117 
00118       // Oops! We counted the bottom-right and bottom-left corners twice.
00119       numEdges += 2;
00120 
00121       std::vector<Edge> edges(numEdges);
00122       size_t interiorRows = inImage.rows() - 1;
00123       size_t interiorColumns = inImage.columns() - 1;
00124       size_t edgeNumber = 0;
00125       size_t pixelIndex0 = 0;
00126       size_t pixelIndex1;
00127       for(size_t row = 0; row < interiorRows; ++row) {
00128         // Get the first pixel of the row;
00129         pixelIndex1 = pixelIndex0 + 1;
00130         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00131       
00132         pixelIndex1 += inImage.columns();
00133         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00134 
00135         pixelIndex1 -= 1;
00136         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00137         ++pixelIndex0;
00138       
00139         // Get the interior pixels of the row.
00140         for(size_t column = 1; column < interiorColumns; ++column) {
00141           pixelIndex1 = pixelIndex0 + 1;
00142           this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00143 
00144           pixelIndex1 += inImage.columns();
00145           this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00146 
00147           pixelIndex1 -= 1;
00148           this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00149 
00150           pixelIndex1 -= 1;
00151           this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00152           ++pixelIndex0;
00153         }
00154 
00155         // Get the last pixel of the row.
00156         pixelIndex1 = pixelIndex0 + inImage.columns();
00157         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00158 
00159         pixelIndex1 -= 1;
00160         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00161         ++pixelIndex0;
00162       }
00163 
00164       // Sanity check.
00165       if(pixelIndex0 != (inImage.rows() - 1) * inImage.columns()) {
00166         DLR_THROW(LogicException, "SegmenterFelzenszwalb::getEdges()",
00167                   "Indexing error.");
00168       }
00169     
00170       // Get the last row of pixels;
00171       for(size_t column = 0; column < interiorColumns; ++column) {
00172         pixelIndex1 = pixelIndex0 + 1;
00173         this->setEdge(edges[edgeNumber++], pixelIndex0, pixelIndex1, inImage);
00174         ++pixelIndex0;
00175       }
00176 
00177       // Sanity check.
00178       if(edgeNumber != numEdges) {
00179         DLR_THROW(LogicException, "SegmenterFelzenszwalb::getEdges()",
00180                   "Edge counting error.");
00181       }
00182       return edges;
00183     }
00184 
00185   } // namespace computerVision
00186   
00187 } // namespace dlr

Generated on Wed Jun 25 14:34:10 2008 for dlrComputerVision Utility Library by  doxygen 1.5.5