views:

12728

answers:

4

Given an object on a plain white background, does anybody know if OpenCV provides functionality to easily detect an object from a captured frame?

I'm trying to locate the corner/center points of an object (rectangle). The way I'm currently doing it, is by brute force (scanning the image for the object) and not accurate. I'm wondering if there is functionality under the hood that i'm not aware of.

Edit Details: The size about the same as a small soda can. The camera is positioned above the object, to give it a 2D/Rectangle feel. The orientation/angle from from the camera is random, which is calculated from the corner points.

It's just a white background, with the object on it (black). The quality of the shot is about what you'd expect to see from a Logitech webcam.

Once I get the corner points, I calculate the center. The center point is then converted to centimeters.

It's refining just 'how' I get those 4 corners is what I'm trying to focus on. You can see my brute force method with this image: Image

+1  A: 

This is exactly what OpenCV is for!
There are different techniques depending on your setup - do you know the size, orientation etc, how noisy is the image, is the rectangle obscured?

Martin Beckett
A: 

It is usually called blob analysis in other machine vision libraries. I haven't used opencv yet.

kenny
+2  A: 

OpenCV has heaps of functions that can help you achieve this. Download Emgu.CV for a C#.NET wrapped to the library if you are programming in that language.

Some methods of getting what you want:

  1. Find the corners as before - e.g. "CornerHarris" OpenCV function

  2. Threshold the image and calculate the centre of gravity - see http://www.roborealm.com/help/Center%20of%20Gravity.php ... this is the method i would use. You can even perform the thresholding in the COG routine. i.e. cog_x += *imagePtr < 128 ? 255 : 0;

  3. Find the moments of the image to give rotation, center of gravity etc - e.g. "Moments" OpenCV function. (I haven't used this)

  4. (edit) The AForge.NET library has corner detection functions as well as an example project (MotionDetector) and libraries to connect to webcams. I think this would be the easiest way to go, assuming you are using Windows and .NET.

geometrikal
In reference to cvCornerHarris, can you elaborate on how it's used? From what I see, you create an image and run cvCornerHarris(image, cornerimg, blockSize(?), apertureSize(?)). And, how are you able to pull information from the corner image?
David McGraw
From what I can tell the way it works is for every pixel it runs a sobel edge detector of size 'apertureSize' over the surrounding 'blockSize' by 'blockSize' group of pixels. It then uses a formula to give a score to the edges detected in this area. A corner will have both horizontal and vertical.
geometrikal
The resulting image is the same size as the original, except the brightest pixels correspond. to strongest corners. Choose block size bigger than the corner to detect - try 5 or 7 for your image. Choose apertureSize and bit smaller - try 3. I haven't used this function myself, so say how it goes
geometrikal
+4  A: 

There's already an example of how to do rectangle detection in OpenCV (look in samples/squares.c), and it's quite simple, actually.

Here's the rough algorithm they use:

0. rectangles <- {}
1. image <- load image
2. for every channel:
2.1  image_canny <- apply canny edge detector to this channel
2.2  for threshold in bunch_of_increasing_thresholds:
2.2.1   image_thresholds[threshold] <- apply threshold to this channel
2.3  for each contour found in {image_canny} U image_thresholds:
2.3.1   Approximate contour with polygons
2.3.2   if the approximation has four corners and the angles are close to 90 degrees.
2.3.2.1    rectangles <- rectangles U {contour}

Not an exact transliteration of what they are doing, but it should help you.

Ismael C