title: How to run findContours() on meanShiftSegmentation() output?
body: <p>I'm trying to rewrite my very slow naive segmentation using floodFill to something faster. I ruled out meanShiftFiltering a year ago because of the difficulty in labelling the colours and then finding their contours.</p>
  <p>The current version of opencv seems to have a fast new function that labels segments using mean shift: gpu::meanShiftSegmentation(). It produces images like the following:</p>
  <p><a href="https://i.stack.imgur.com/hx5S1.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/hx5S1.png" alt="meanShiftSegmentation() output" /></a><br />
  <sub>(source: <a href="http://www.ekran.org/tmp/segments.png" rel="nofollow noreferrer">ekran.org</a>)</sub></p>
  <p>So this looks to me pretty close to being able to generating contours. How can I run findContours to generate segments?</p>
  <p>Seems to me, this would be done by extracting the labelled colours from the image, and then testing which pixel values in the image match each label colour to make a boolean image suitable for findContours. This is what I have done in the following (but its a bit slow and strikes me there should be a better way):</p>
  <pre><code>Mat image = imread(&quot;test.png&quot;);
  
  ...
  // gpu operations on image resulting in gpuOpen
  ...
  
  // Mean shift
  TermCriteria iterations = TermCriteria(CV_TERMCRIT_ITER, 2, 0);
  gpu::meanShiftSegmentation(gpuOpen, segments, 10, 20, 300, iterations);
  
  // convert to greyscale (HSV image)
  vector&lt;Mat&gt; channels;
  split(segments, channels);
  
  // get labels from histogram of image.
  int size = 256;
  labels = Mat(256, 1, CV_32SC1);
  calcHist(&amp;channels.at(2), 1, 0, Mat(), labels, 1, &amp;size, 0);
  
  // Loop through hist bins
  for (int i=0; i&lt;256; i++) {
      float count = labels.at&lt;float&gt;(i);
  
      // Does this bin represent a label in the image?
      if (count &gt; 0) {
          // find areas of the image that match this label and findContours on the result.
          Mat label = Mat(channels.at(2).rows, channels.at(2).cols, CV_8UC1, Scalar::all(i)); // image filled with label colour.
          Mat boolImage = (channels.at(2) == label); // which pixels in labeled image are identical to this label?
          vector&lt;vector&lt;Point&gt;&gt; labelContours;
          findContours(boolImage, labelContours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
          // Loop through contours.
          for (int idx = 0; idx &lt; labelContours.size(); idx++) {
              // get bounds for this contour.
              bounds = boundingRect(labelContours[idx]);
  
              // create ROI for bounds to extract this region
              Mat patchROI = image(bounds);
              Mat maskROI = boolImage(bounds);
          }
      }
  }
  </code></pre>
  <p>Is this the best approach or is there a better way to get the label colours? Seems it would be logical for meanShiftSegmentation to provide this information? (vector of colour values, or vector of masks for each label, etc.)</p>
  <p>Thank you.</p>