2012-05-01 10 views
8

Estoy tratando de detectar el centro de blancos de puntos negros/blancos, como en esta imagen. He intentado usar el método cv2.HoughCircles pero 1, solo puedo detectar de 2 a 3 objetivos, y 2, cuando trazo los círculos encontrados nuevamente en la imagen, siempre están ligeramente desplazados.Detección de objetivo de punto OpenCV que no encuentra todos los destinos, y los círculos encontrados están desplazados

¿Estoy utilizando el método incorrecto? ¿Debería usar FindContours o algo completamente diferente?

Aquí está mi código:

import cv2 
from cv2 import cv 
import os 
import numpy as np 

def showme(pic): 
    cv2.imshow('window',pic) 
    cv2.waitKey() 
    cv2.destroyAllWindows() 


im=cv2.imread('small_test.jpg') 

gray=cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 

#I've tried blur,bw,tr... all give me poor results. 

blur = cv2.GaussianBlur(gray,(3,3),0) 
n,bw = cv2.threshold(blur,120,255,cv2.THRESH_BINARY) 
tr=cv2.adaptiveThreshold(blur,255,0,1,11,2) 

circles = cv2.HoughCircles(gray, cv.CV_HOUGH_GRADIENT, 3, 100, None, 200, 100, 5, 16) 

try: 
    n = np.shape(circles) 
    circles=np.reshape(circles,(n[1],n[2])) 
    print circles 
    for circle in circles: 
     cv2.circle(im,(circle[0],circle[1]),circle[2],(0,0,255)) 
    showme(im) 
except: 
    print "no cicles found" 

y este es mi corriente de salida:

+0

Me encantaría ver su salida actual. Puede que le interese comprobar este hilo: http://stackoverflow.com/q/10313602/176769 – karlphillip

+0

aquí está el resultado del código anterior. ! [Resultados de mi código] [1] [1]: http://i.stack.imgur.com/nd2Hr.jpg – hokiebird

+0

Tal vez sea hora de revisar sus otras preguntas y aceptar las respuestas que las resolvieron (si hay hay alguno). Hay una pequeña casilla de verificación cerca de cada respuesta, haga clic en ella para seleccionar la respuesta oficial a su pregunta. – karlphillip

Respuesta

8

Jugar el código que he escrito en another post, yo era capaz de lograr un resultado ligeramente mejor:

Se trata de los parámetros. Siempre lo es.

Hay 3 funciones importantes que se llaman en este programa con las que debe experimentar: cvSmooth(), cvCanny() y cvHoughCircles(). Cada uno de ellos tiene el potencial de cambiar el resultado drásticamente.

Y aquí es el código C:

IplImage* img = NULL; 
if ((img = cvLoadImage(argv[1]))== 0) 
{ 
    printf("cvLoadImage failed\n"); 
} 

IplImage* gray = cvCreateImage(cvGetSize(img), IPL_DEPTH_8U, 1); 
CvMemStorage* storage = cvCreateMemStorage(0); 

cvCvtColor(img, gray, CV_BGR2GRAY); 

// This is done so as to prevent a lot of false circles from being detected 
cvSmooth(gray, gray, CV_GAUSSIAN, 7, 9); 

IplImage* canny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1); 
IplImage* rgbcanny = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,3); 
cvCanny(gray, canny, 40, 240, 3); 

CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/8, 120, 10, 2, 25); 
cvCvtColor(canny, rgbcanny, CV_GRAY2BGR); 

for (size_t i = 0; i < circles->total; i++) 
{ 
    // round the floats to an int 
    float* p = (float*)cvGetSeqElem(circles, i); 
    cv::Point center(cvRound(p[0]), cvRound(p[1])); 
    int radius = cvRound(p[2]); 

    // draw the circle center 
    cvCircle(rgbcanny, center, 3, CV_RGB(0,255,0), -1, 8, 0); 

    // draw the circle outline 
    cvCircle(rgbcanny, center, radius+1, CV_RGB(0,0,255), 2, 8, 0); 

    printf("x: %d y: %d r: %d\n",center.x,center.y, radius); 
} 

cvNamedWindow("circles", 1); 
cvShowImage("circles", rgbcanny); 

cvSaveImage("out.png", rgbcanny); 
cvWaitKey(0); 

confiar en usted tiene las capacidades de este puerto a Python.

+0

gracias por la ayuda. Trabajaré en portarlo sobre Python. Voy a utilizar estos objetivos (ya conozco las posiciones 3d, usando un sistema TRITOP [link] http://www.capture3d.com/products-TRITOP.html) para calcular la posición/orientación de la pieza. Después de usar este método para encontrar los círculos, ¿hay algún otro método que recomiende que calcule con mucha precisión los centros de los objetivos? Gracias de nuevo – hokiebird

+0

Este programa completo podría convertirse en una función única que se ejecuta un par de veces (con diferentes parámetros), y después de cada iteración se comparan los círculos encontrados con una iteración previa para asegurarse de que todos los círculos son buenos. Este enfoque podría posiblemente decirle que el círculo más grande a la derecha no es un buen círculo. – karlphillip

+0

¿Estás usando 'canny' y' rgbcanny' en la detección de tu círculo? parece que no, pero quiero asegurarme de que – mga

0

Dado que el modelo del círculo es fijo y así distingue del objeto, la coincidencia simple de la plantilla debería funcionar razonablemente bien, echa un vistazo a cvMatchTemplate. Para condiciones más complejas (deformación debido a la forma del objeto o la geometría de la vista), puede probar funciones más sólidas como SIFT o SURF (cvExtractSURF).

Cuestiones relacionadas