2011-08-31 51 views
19

Estoy tratando de encontrar las esquinas en una imagen, no necesito los contornos, solo las 4 esquinas. Cambiaré la perspectiva usando 4 esquinas.Cómo encontrar esquinas en una imagen usando OpenCv

Estoy usando Opencv, pero necesito saber los pasos para encontrar las esquinas y qué función usaré.

Mis imágenes serán así: (sin puntos rojos, voy a pintar los puntos después) enter image description here

Editado:

Después de los pasos sugeridos, que writed el código: (Nota: Estoy no usando OpenCv puro, estoy usando javaCV, pero la lógica es la misma).

// Load two images and allocate other structures (I´m using other image) 
    IplImage colored = cvLoadImage(
      "res/scanteste.jpg", 
      CV_LOAD_IMAGE_UNCHANGED); 

enter image description here

IplImage gray = cvCreateImage(cvGetSize(colored), IPL_DEPTH_8U, 1); 
    IplImage smooth = cvCreateImage(cvGetSize(colored), IPL_DEPTH_8U, 1); 

    //Step 1 - Convert from RGB to grayscale (cvCvtColor) 
    cvCvtColor(colored, gray, CV_RGB2GRAY); 

enter image description here

//2 Smooth (cvSmooth) 
    cvSmooth(gray, smooth, CV_BLUR, 9, 9, 2, 2); 

enter image description here

//3 - cvThreshold - What values? 
    cvThreshold(gray,gray, 155, 255, CV_THRESH_BINARY); 

enter image description here

//4 - Detect edges (cvCanny) -What values? 
    int N = 7; 
    int aperature_size = N; 
    double lowThresh = 20; 
    double highThresh = 40;  
    cvCanny(gray, gray, lowThresh*N*N, highThresh*N*N, aperature_size); 

enter image description here

//5 - Find contours (cvFindContours) 
    int total = 0; 
    CvSeq contour2 = new CvSeq(null); 
    CvMemStorage storage2 = cvCreateMemStorage(0); 
    CvMemStorage storageHull = cvCreateMemStorage(0); 
    total = cvFindContours(gray, storage2, contour2, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE); 
    if(total > 1){ 
      while (contour2 != null && !contour2.isNull()) { 
       if (contour2.elem_size() > 0) { 
       //6 - Approximate contours with linear features (cvApproxPoly) 
        CvSeq points = cvApproxPoly(contour2,Loader.sizeof(CvContour.class), storage2, CV_POLY_APPROX_DP,cvContourPerimeter(contour2)*0.005, 0); 
        cvDrawContours(gray, points,CvScalar.BLUE, CvScalar.BLUE, -1, 1, CV_AA); 

       } 
       contour2 = contour2.h_next(); 
      } 

    } 

enter image description here

lo tanto, quiero encontrar los cornes, pero yo no sé cómo usar esquinas funcionan como cvCornerHarris y otros.

+3

de OpenCV "esquina" funciones no se encuentran en las esquinas de la manera que está pensando - En términos generales, encuentran áreas con una variación horizontal y vertical significativa. El objetivo de las funciones de esquina en OpenCV es encontrar partes distintivas de la imagen que serán útiles para el seguimiento visual, que no es necesariamente lo que comúnmente consideramos como esquinas. –

+0

El código exacto en http://stackoverflow.com/a/14368605/1832154 (excepto la parte de redimensionamiento, ya que su imagen ya es lo suficientemente pequeña) da http://i.imgur.com/hMdAlHX.png – mmgp

Respuesta

22

En primer lugar, echa un vistazo a /samples/c/squares.c en su distribución OpenCV. Este ejemplo proporciona un detector cuadrado, y debería ser un buen comienzo para la detección de características de esquina. Luego, eche un vistazo a las funciones orientadas a funciones de OpenCV como cvCornerHarris() y cvGoodFeaturesToTrack().

Los métodos anteriores pueden devolver muchas características de esquina - la mayoría no serán las "esquinas verdaderas" que está buscando. En mi aplicación, tuve que detectar cuadrados que habían sido rotados o sesgados (debido a la perspectiva). Mi tubería de detección consistió en:

  1. Convertir de RGB a escala de grises (cvCvtColor)
  2. liso (cvSmooth)
  3. Umbral (cvThreshold)
  4. bordes detectar (cvCanny)
  5. Encuentra contornos (cvFindContours)
  6. Contornos aproximados con características lineales (cvApproxPoly)
  7. Encuentra "rectángulos" que eran estructuras que: tenían contornos poligonalizados canta 4 puntos, tenían suficiente área, tenían bordes adyacentes eran ~ 90 grados, la distancia entre vértices "opuestos" era de tamaño suficiente, etc.

El paso 7 fue necesario porque una imagen ligeramente ruidosa puede producir muchas estructuras que parecen rectangulares después de la poligonalización. En mi aplicación, también tuve que lidiar con estructuras cuadradas que aparecían dentro o superponían el cuadrado deseado. Encontré la propiedad del área del contorno y el centro de gravedad útiles para discernir el rectángulo adecuado.

+0

Necesito un poco de ayuda con el paso 7, cómo usar cvCornerHarris, con mi ejemplo, vea la publicación editada, ¿me puede ayudar? – Ricardo

+1

¿Es cvSmooth algo así como un desenfoque gaussiano? ¿Dilatas el resultado de cvCanny? Cómo se aproximan los contornos con, digamos 5 esquinas (cuadrados deformados debido a las sombras, etc.) o suqares con una pequeña cresta. Su enfoque es más o menos lo que quiero hacer, pero estoy luchando muy duro. ¿Puedes proporcionar algunos ejemplos de código? Sería muy útil. – sschrass

7
+0

Como seguimiento -up, y para rehacer ligeramente el blog de sudoku grab: Intente encontrar las esquinas a través de encontrar los bordes. Comience con su imagen de umbral, encuentre líneas rectas destacadas (hough) y busque dónde se cruzan. Ahí es donde están tus rincones. –

0

Aplicar houghlines a la imagen astuto - obtendrá una lista de puntos aplicar casco convexo a este conjunto de puntos

Cuestiones relacionadas