title: OpenCV image segmentation in C++ using Watershed
body: <p>Hi i'm currently writing a basic C++ application using the OpenCV library to segment the subject of the image from its background. The application reads in an image file and uses the watershed algorithm to generate a mask based on data it finds around the edges and data it finds in the centre of the image.</p>
  
  <p>(To start I created an image object that has an overall value of -1. Then I created a border around an empty image which has a value of 1. Then I created a rectangle roughly in the centre of the image which has a value of 2. The border and the rectangle are not touching.)</p>
  
  <p>I attempt to remove data from the image using the generated mask using a bitwise AND between the original image and the auto-generated mask.</p>
  
  <p>I have written this in C++ and would be very grateful if someone could take a quick look at my code. The only similar example I could find was using the native OpenCV bindings for Python.</p>
  
  <p>Sample Mask: <a href="http://i.imgur.com/a0SUwy3.png" rel="nofollow">http://i.imgur.com/a0SUwy3.png</a></p>
  
  <p>Sample Image: <a href="http://i.imgur.com/FQywu6P.png" rel="nofollow">http://i.imgur.com/FQywu6P.png</a></p>
  
  <pre><code>// Usage: ./app input.jpg
  #include "opencv2/opencv.hpp"
  #include &lt;string&gt;
  
  using namespace cv;
  using namespace std;
  
  class WatershedSegmenter{
  private:
      cv::Mat markers;
  public:
      void setMarkers(cv::Mat&amp; markerImage)
      {
          markerImage.convertTo(markers, CV_32S);
      }
  
      cv::Mat process(cv::Mat &amp;image)
      {
          cv::watershed(image, markers);
          markers.convertTo(markers,CV_8U);
          return markers;
      }
  };
  
  
  int main(int argc, char* argv[])
  {
      cv::Mat image = cv::imread(argv[1]);
      cv::Mat blank(image.size(),CV_8U,cv::Scalar(0xFF));
      cv::Mat dest(image.size(),CV_8U,cv::Scalar(0xFF));
      imshow("originalimage", image);
  
      // Create markers image
      cv::Mat markers(image.size(),CV_8U,cv::Scalar(-1));
      //Rect(topleftcornerX, topleftcornerY, width, height);
      //top rectangle
      markers(Rect(0,0,image.cols, 5)) = Scalar::all(1);
      //bottom rectangle
      markers(Rect(0,image.cols-5,image.cols, 5)) = Scalar::all(1);
      //left rectangle
      markers(Rect(0,0,5,image.rows)) = Scalar::all(1);
      //right rectangle
      markers(Rect(image.cols-5,0,5,image.rows)) = Scalar::all(1);
      //centre rectangle
      markers(Rect(image.cols/2,image.rows/2,50, 50)) = Scalar::all(2);
  
  
      //Create watershed segmentation object
      WatershedSegmenter segmenter;
      segmenter.setMarkers(markers);
      cv::Mat result = segmenter.process(image);
      result.convertTo(result,CV_8U);
  
      bitwise_and(image, blank, dest, result);
      imshow("final_result", dest);
  
      cv::waitKey(0);
  
      return 0;
  }
  </code></pre>