2008-11-10 17 views
32

Dado un objeto sobre un fondo blanco, ¿alguien sabe si OpenCV ofrece funcionalidad para detectar fácilmente un objeto de un fotograma capturado?Detección de objetos OpenCV - Punto central

Estoy tratando de ubicar los puntos de esquina/centro de un objeto (rectángulo). La forma en que lo estoy haciendo actualmente es mediante la fuerza bruta (escaneando la imagen para el objeto) y no es precisa. Me pregunto si hay una funcionalidad debajo del capó que no conozco.

Editar detalles: El tamaño es aproximadamente el mismo que una pequeña lata de refresco. La cámara se coloca encima del objeto, para darle una sensación 2D/Rectangular. La orientación/ángulo desde la cámara es aleatoria, que se calcula a partir de los puntos de esquina.

Es solo un fondo blanco, con el objeto en él (negro). La calidad de la toma es más o menos lo que esperaría ver desde una cámara web Logitech.

Una vez que obtengo los puntos de las esquinas, calculo el centro. El punto central se convierte a centímetros.

Lo que intento enfocar es refinar simplemente 'cómo' obtengo esas 4 esquinas. Puede ver mi método de fuerza bruta con esta imagen: Image

Respuesta

25

Ya hay un ejemplo de cómo hacer la detección rectángulo en OpenCV (busque en muestras/squares.c), y es bastante simple, en realidad.

Aquí es el algoritmo que utilizan áspera:

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} 
No

una transcripción exacta de lo que están haciendo, pero debería ayudarle.

+0

Estoy haciendo un proyecto similar. Soy nuevo en OpenCV, ¿podría publicar el código fuente para seguir estos pasos? – cduck

+1

Creo que el archivo que está buscando ahora es [OpenCV_proj_dir] /samples/cpp/squares.cpp. –

0

Por lo general, se denomina análisis de blobs en otras bibliotecas de visión artificial. No he usado opencv todavía.

4

OpenCV tiene un montón de funciones que pueden ayudarlo a lograrlo. Descarga Emgu.CV para obtener un C# .NET envuelto en la biblioteca si estás programando en ese idioma.

Algunos métodos de conseguir lo que quieren:

  1. Encuentra las esquinas como antes - por ejemplo, "CornerHarris" función OpenCV

  2. Umbral de la imagen y calcular el centro de gravedad - ver http://www.roborealm.com/help/Center%20of%20Gravity.php ... este es el método que utilizaría. Incluso puede realizar el umbral en la rutina COG. es decir, cog_x + = * imagePtr < 128? 255: 0;

  3. Encuentra los momentos de la imagen para dar rotación, centro de gravedad, etc. Función "Moments" OpenCV. (No he usado esto)

  4. (editar) La biblioteca AForge.NET tiene funciones de detección de esquina, así como un proyecto de ejemplo (MotionDetector) y bibliotecas para conectarse a cámaras web. Creo que esta sería la forma más fácil de hacerlo, suponiendo que esté usando Windows y .NET.

+0

En referencia a cvCornerHarris, ¿puede dar más detalles sobre cómo se usa? Por lo que veo, creas una imagen y ejecutas cvCornerHarris (image, cornerimg, blockSize (?), ApertureSize (?)). Y, ¿cómo puedes obtener información de la imagen de la esquina? –

+0

Por lo que puedo decir, la forma en que funciona es que para cada píxel se ejecuta un detector de borde sobel del tamaño 'diafragmaTamaño' sobre el grupo de píxeles 'blockSize' circundante. A continuación, utiliza una fórmula para dar una puntuación a los bordes detectados en esta área. Una esquina tendrá tanto horizontal como vertical. – geometrikal

+0

La imagen resultante es del mismo tamaño que el original, excepto que corresponden los píxeles más brillantes. a las esquinas más fuertes. Elija tamaño de bloque más grande que la esquina para detectar: ​​intente con 5 o 7 para su imagen. Elija apertureSize y bit smaller - pruebe 3. No he usado esta función yo mismo, así que diga cómo va – geometrikal

7

Espero que esto ayude, utiliza el método de momento para obtener el centroide de una imagen en blanco y negro.

cv::Point getCentroid(cv::Mat img) 
{ 
    cv::Point Coord; 
    cv::Moments mm = cv::moments(img,false); 
    double moment10 = mm.m10; 
    double moment01 = mm.m01; 
    double moment00 = mm.m00; 
    Coord.x = int(moment10/moment00); 
    Coord.y = int(moment01/moment00); 
    return Coord; 
} 
Cuestiones relacionadas