There is a great article just for your question, but it is on AForge.NET framework. Despite that, information here may lead you to a proper path or approach.
If I were you using OpenCV I would do these steps to solve this problem:
- At first, I would extract the shapes of different colors. There is a function for that called
InRange
(maybe some help about this you may find in the question and my answer HERE. Extracted shapes of different colors should be stored in differend Mat objects, f.e. shapes for yellow stored in one Mat, blue in another and so on. Seperating different color shapes by this extraction would be easier for the following processing.
- After that the contour finding should follow. It could be done either with
Canny
or findContours
functions, but the second one would be prefered because after InRange
your image will be binary (mask). Then, every shape should be stored in seperate Mat object, drawing them using drawContours
function. It should me a multidimentional array or so, because at first your shapes should be sorted by color.
- Then, easiest thing is finding the circles. This could be done simply with
houghCircles
function. This function may misunderstand pentagons with circles, but using proper parameters it should work perfectly. More info HERE. Now you know which shapes are circles and their color.
- At the end is finding the rest of the shapes and their types. This would not be easy. FIRST way (I'd try it first probably) would be simplifying your contours with
approxPolyDP
function. Then, for the sake of precision you could use convexHull
. After that, if needed, check each lines degree of angle with the following line, so you could find lines which together form a, lets say, ~182-178 degrees (almost a straight line). Those lines should be merged into one, because that is an error of contour simplifying. Check how many lines the shape (or simplified contour) has and that is the type of shape. SECOND method would be finding a houghLines
on contours. Then, checking the collisions of each line with another to find how many of them are here and forming a shape having this data. More information HERE.
As you understood from my text, this task will not be easy for sure. Using any approach it will not be easy, but this is possible for sure, it is quite a common task, much information can be found about this.