42

I'm trying to detect a shape (a cross) in my input video stream with the help of OpenCV. Currently I'm thresholding to get a binary image of my cross which works pretty good. Unfortunately my algorithm to decide whether the extracted blob is a cross or not doesn't perform very good. As you can see in the image below, not all corners are detected under certain perspectives.

Enter image description here

I'm using findContours() and approxPolyDP() to get an approximation of my contour. If I'm detecting 12 corners / vertices in this approximated curve, the blob is assumed to be a cross.

Is there any better way to solve this problem? I thought about SIFT, but the algorithm has to perform in real-time and I read that SIFT is not really suitable for real-time.

Ilmari Karonen
  • 49,047
  • 9
  • 93
  • 153
Tobi
  • 473
  • 4
  • 9
  • 1
    have you tried [Hough](http://docs.opencv.org/doc/tutorials/imgproc/imgtrans/hough_lines/hough_lines.html) line transform? Instead of identifying corners you can identify the lines and after a simple check of their orientations you can determine if it's a cross or not. – George Aprilis Feb 02 '13 at 10:59

2 Answers2

9

I have a couple of suggestions that might provide some interesting results although I am not certain about either.

If the cross is always near the center of your image and always lies on a planar surface you could try to find a homography between the camera and the plane upon which the cross lies. This would enable you to transform a sample image of the cross (at a selection of different in plane rotations) to the coordinate system of the visualized cross. You could then generate templates which you could match to the image. You could do some simple pixel agreement tests to determine if you have a match.

Alternatively you could try to train a Haar-based classifier to recognize the cross. This type of classifier is often used in face detection and detects oriented edges in images, classifying faces by the relative positions of several oriented edges. It has good classification accuracy on faces and is extremely fast. Although I cannot vouch for its accuracy in this particular situation it might provide some good results for simple shapes such as a cross.

Max Allan
  • 2,375
  • 1
  • 17
  • 18
  • Thanks for your fast answer. Sorry for my imprecise question, but unfortunately the cross can be everywhere in the image (but I could use a ROI where it's centered?). It can be really small (about 20px diameter) or really big (filling the whole image) and can be seen from different perspectives. Would a Haar Classifier fulfill these constraints? In summary I need a method which is independent of scale and perspective. – Tobi Jan 30 '13 at 20:37
  • @Tobi I think constructing a bounding box for the cross and then using an ROI could work. It has been a while since I've used the opencv implementation of a boosted Haar classifier but I believe you give it a training set of images and it will automatically create samples of different scales and perspectives by warping (but you should check the docs to be sure). – Max Allan Jan 30 '13 at 21:21
  • I tried a lot of different training sets but finally found a pretty good one. The advantages compared with the convexity defects are especially noticeable in low resolution images. – Tobi Feb 14 '13 at 07:36
8

Computing the convex hull and then taking advantage of the convexity defects might work.

All crosses should have four convexity defects, making up four sets of two points, or four vectors. Furthermore, if your shape was a cross then these four vectors will have two pairs of supplementary angles.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
David Wurtz
  • 4,218
  • 1
  • 13
  • 7
  • This approach is spot on, just take care with spurious vertices on the convex hull that are unimportant for the corners in the cross. – mmgp Feb 09 '13 at 19:41