title: Basic Shape recognition (openCV C++)
body: <p>I have a project that I need to make for classes and I chose task that is a bit out of my skills.
  Target is to count result of dice rolls.
  For now, I'am trying to make it work on a sample pic:</p>
  
  <p><a href="https://i.stack.imgur.com/920Co.jpg" rel="nofollow noreferrer">sample pic of dices</a></p>
  
  <p><a href="https://i.stack.imgur.com/pJ3ma.jpg" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/pJ3ma.jpg" alt="enter image description here"></a></p>
  
  <p>and my current code is added below:</p>
  
  <pre><code>#include "opencv2/core/core.hpp"
  #include "opencv2/highgui/highgui.hpp"
  #include "opencv2/imgproc/imgproc.hpp"
  #include "iostream"
  
  using namespace cv;
  using namespace std;
  
  Mat KostkaFunkcja(Mat image, Mat in, Scalar low, Scalar high);
  int getMaxAreaContourId(vector &lt;vector&lt;cv::Point&gt;&gt; contours);
  vector&lt;Point&gt; contoursConvexHull(vector&lt;vector&lt;Point&gt; &gt; contours, int index);
  Mat ZnakiFunkcja(Mat image, Mat in, Scalar low, Scalar high);
  
  
  int main(int argc, char** argv)
  {
      Mat image;
      image = imread("kostki.jpg", CV_LOAD_IMAGE_COLOR);
  
      if (!image.data)
      {
          cout &lt;&lt; "Could not open or find the image" &lt;&lt; std::endl;
          return -1;
      }
  
      Mat imgHSV;
      Mat workimage = image;
  
      cvtColor(workimage, imgHSV, COLOR_BGR2HSV); //Convert the captured frame from BGR to HSV
      //red dice
      workimage = KostkaFunkcja(workimage, imgHSV, Scalar(146, 0, 31), Scalar(179, 255, 255));
      //green dice
      workimage = KostkaFunkcja(workimage, imgHSV, Scalar(25, 147, 0), Scalar(98, 255, 154));
      //yellow dice
      workimage = KostkaFunkcja(workimage, imgHSV, Scalar(22, 45, 161), Scalar(91, 255, 255));
      //black dice
      workimage = KostkaFunkcja(workimage, imgHSV, Scalar(98, 0, 0), Scalar(179, 232, 107));
      //white symbols
      workimage = ZnakiFunkcja(workimage, imgHSV, Scalar(58, 0, 183), Scalar(179, 145, 255));
      namedWindow("Kostki_kontur", CV_WINDOW_AUTOSIZE);
      imshow("Kostki_kontur", workimage);
      waitKey(0);
  
      return 0;
  
  }
  
  Mat KostkaFunkcja(Mat image, Mat in, Scalar low, Scalar high)
  {
      Mat temp;
      inRange(in, low, high, temp);
      erode(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      dilate(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      dilate(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      erode(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
  
      Mat srcBlur, srcCanny;
      blur(temp, srcBlur, Size(3, 3));
  
      Canny(srcBlur, srcCanny, 0, 100, 3, true);
      vector&lt;vector&lt;Point&gt; &gt; contours;
      findContours(srcCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
  
      int largest_contour_index = getMaxAreaContourId(contours);
  
      Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);
  
      for (int i = 0; i&lt; contours.size(); i++)
      {
          Scalar color = Scalar(255, 255, 255);
          drawContours(drawing, contours, i, color, 2);
      }
  
      vector&lt;Point&gt; ConvexHullPoints = contoursConvexHull(contours, largest_contour_index);
      polylines(image, ConvexHullPoints, true, Scalar(0, 0, 255), 2);
      return image;
  }
  
  vector&lt;Point&gt; contoursConvexHull(vector&lt;vector&lt;Point&gt; &gt; contours, int index)
  {
      vector&lt;Point&gt; result;
      vector&lt;Point&gt; pts;
      for (size_t j = 0; j&lt; contours[index].size(); j++)
          pts.push_back(contours[index][j]);
      convexHull(pts, result);
      return result;
  }
  
  int getMaxAreaContourId(vector &lt;vector&lt;cv::Point&gt;&gt; contours)
  {
      double maxArea = 0;
      int maxAreaContourId = -1;
      for (int j = 0; j &lt; contours.size(); j++) {
          double newArea = cv::contourArea(contours.at(j));
          if (newArea &gt; maxArea) {
              maxArea = newArea;
              maxAreaContourId = j;
          }
          return maxAreaContourId;
      }
  }
  Mat ZnakiFunkcja(Mat image, Mat in, Scalar low, Scalar high)
  {
      Mat temp;
      inRange(in, low, high, temp);
      erode(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      dilate(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      dilate(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
      erode(temp, temp, getStructuringElement(MORPH_ELLIPSE, Size(5, 5)));
  
      Mat srcBlur, srcCanny;
      blur(temp, srcBlur, Size(3, 3));
  
      Canny(srcBlur, srcCanny, 0, 100, 3, true);
      vector&lt;vector&lt;Point&gt; &gt; contours;
      findContours(srcCanny, contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);
      Mat drawing = Mat::zeros(srcCanny.size(), CV_8UC3);
      for (int i = 0; i&lt; contours.size(); i++)
      {
          Scalar color = Scalar(255, 255, 255);
          drawContours(drawing, contours, i, color, 2);
          polylines(image, contours, true, Scalar(0, 0, 255), 2);
          return image;
      }
  
  }
  </code></pre>
  
  <p>Yet I have no idea how to count different shapes (hearts, lightnings, shields, numbers).</p>
  
  <p>I will be greatfull if anybody would give me a tip or solution of how to do the job.</p>
  
  <p>1) sorry for bad english
  2) we had no openCV in classes [only basic  c++]
  3) tryed to found anything usefull on internet, but even if I found anything, I could't understand what was happening in the code</p>