Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to detect simple geometric shapes using OpenCV

Tags:

opencv

I have this project where I need (on iOS) to detect simple geometric shapes inside an image.

enter image description here

After searching the internet I have concluded that the best tool for this is OpenCV. The thing is that up until two hours ago I had no idea what OpenCV is and I have never even remotely did anything involving image processing. My main experience is JS/HTML,C#,SQL,Objective-C...

Where do I start with this?

I have found this answer that I was able to digest and by reading already other stuff, I understand that OpenCV should return an Array of shapes with the points/corners, is this true? Also how will it represent a circle or a half circle? Also what about the shape orientation?

Do you know of any Demo iOS project that can demonstrate a similar functionality?

like image 697
Registered User Avatar asked Jul 11 '12 00:07

Registered User


People also ask

What function is used to detect polygons OpenCV?

Contours – convex contours and the Douglas-Peucker algorithm The first facility OpenCV offers to calculate the approximate bounding polygon of a shape is cv2. approxPolyDP. This function takes three parameters: A contour.

What objects can OpenCV detect?

OpenCV has a bunch of pre-trained classifiers that can be used to identify objects such as trees, number plates, faces, eyes, etc. We can use any of these classifiers to detect the object as per our need.


2 Answers

If you have only these regular shapes, there is a simple procedure as follows :

  1. Find Contours in the image ( image should be binary as given in your question)
  2. Approximate each contour using approxPolyDP function.
  3. First, check number of elements in the approximated contours of all the shapes. It is to recognize the shape. For eg, square will have 4, pentagon will have 5. Circles will have more, i don't know, so we find it. ( I got 16 for circle and 9 for half-circle.)
  4. Now assign the color, run the code for your test image, check its number, fill it with corresponding colors.

Below is my example in Python:

import numpy as np import cv2  img = cv2.imread('shapes.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  ret,thresh = cv2.threshold(gray,127,255,1)  contours,h = cv2.findContours(thresh,1,2)  for cnt in contours:     approx = cv2.approxPolyDP(cnt,0.01*cv2.arcLength(cnt,True),True)     print len(approx)     if len(approx)==5:         print "pentagon"         cv2.drawContours(img,[cnt],0,255,-1)     elif len(approx)==3:         print "triangle"         cv2.drawContours(img,[cnt],0,(0,255,0),-1)     elif len(approx)==4:         print "square"         cv2.drawContours(img,[cnt],0,(0,0,255),-1)     elif len(approx) == 9:         print "half-circle"         cv2.drawContours(img,[cnt],0,(255,255,0),-1)     elif len(approx) > 15:         print "circle"         cv2.drawContours(img,[cnt],0,(0,255,255),-1)  cv2.imshow('img',img) cv2.waitKey(0) cv2.destroyAllWindows() 

Below is the output:

enter image description here

Remember, it works only for regular shapes.

Alternatively to find circles, you can use houghcircles. You can find a tutorial here.

Regarding iOS, OpenCV devs are developing some iOS samples this summer, So visit their site : www.code.opencv.org and contact them.

You can find slides of their tutorial here : http://code.opencv.org/svn/gsoc2012/ios/trunk/doc/CVPR2012_OpenCV4IOS_Tutorial.pdf

like image 75
Abid Rahman K Avatar answered Sep 26 '22 18:09

Abid Rahman K


The answer depends on the presence of other shapes, level of noise if any and invariance you want to provide for (e.g. rotation, scaling, etc). These requirements will define not only the algorithm but also required pre-procesing stages to extract features.

Template matching that was suggested above works well when shapes aren't rotated or scaled and when there are no similar shapes around; in other words, it finds a best translation in the image where template is located:

double minVal, maxVal; Point minLoc, maxLoc; Mat image, template, result; // template is your shape matchTemplate(image, template, result, CV_TM_CCOEFF_NORMED); minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc); // maxLoc is answer 

Geometric hashing is a good method to get invariance in terms of rotation and scaling; this method would require extraction of some contour points.

Generalized Hough transform can take care of invariance, noise and would have minimal pre-processing but it is a bit harder to implement than other methods. OpenCV has such transforms for lines and circles.

In the case when number of shapes is limited calculating moments or counting convex hull vertices may be the easiest solution: openCV structural analysis

like image 43
Vlad Avatar answered Sep 24 '22 18:09

Vlad