2012-08-24 10 views
9

Actualmente estoy desarrollando proyectos de procesamiento de imágenes y estoy usando javacv para desarrollar componentes de procesamiento de imágenes. Pude extraer algunas partes interesantes de una imagen y ahora necesito leer las coordenadas xey de esos objetos. Esta es la imagen que me haveextracted¿Cómo obtener las coordenadas x, y de los objetos extraídos en javacv?

enter image description here

y necesito para identificar esos objetos y dibujar cuadrados en torno a esos objetos. Revisé algunos tutoriales e intenté identificar objetos usando el siguiente código.

IplImage img="sourceimage"; 
    CvSize sz = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(sz, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 250, CV_THRESH_BINARY); 


    CvMemStorage mem = CvMemStorage.create(); 
    CvSeq contours = new CvSeq(); 
    CvSeq ptr = new CvSeq(); 
    cvFindContours(gry, mem, contours, Loader.sizeof(CvContour.class) , CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0)); 

    CvRect boundbox; 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 
     boundbox = cvBoundingRect(ptr, 0); 
     if(boundbox.height()>10||boundbox.height()>10){ 
      cvRectangle(gry, cvPoint(boundbox.x(), boundbox.y()), cvPoint(boundbox.x() + boundbox.width(), boundbox.y() + boundbox.height()),CvScalar.BLUE, 0, 0, 0); 
      System.out.println(boundbox.x()+", "+boundbox.y()); 
     } 
    } 
    cvShowImage("contures", gry); 
    cvWaitKey(0); 

Pero no dibuja como un rectángulo alrededor de los objetos. Me gustaría saber si puedo usar el método cvFindContours para identificar esos objetos. ¿Puede alguien explicar cómo archivar mi objetivo usando javacv/opencv?

+0

Así que cuando se dibuja estos rectángulos ¿cómo son en relación con los objetos que tienes? – MahdeTo

+0

¿Por qué ignoran las respuestas a su pregunta? – ArtemStorozhuk

+0

@MahdeTo Necesito saber cómo dibujar un rectángulo alrededor de estos objetos. –

Respuesta

11

Trate de seguir el siguiente código y le dará respuesta a su pregunta.

IplImage img=cvLoadImage("pathtosourceimage"); 
    CvSize cvSize = cvSize(img.width(), img.height()); 
    IplImage gry=cvCreateImage(cvSize, img.depth(), 1); 
    cvCvtColor(img, gry, CV_BGR2GRAY); 
    cvThreshold(gry, gry, 200, 255, CV_THRESH_BINARY); 
    cvAdaptiveThreshold(gry, gry, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY_INV, 11, 5); 

    CvMemStorage storage = CvMemStorage.create(); 
    CvSeq contours = new CvContour(null); 

    int noOfContors = cvFindContours(gry, storage, contours, Loader.sizeof(CvContour.class), CV_RETR_CCOMP, CV_CHAIN_APPROX_NONE, new CvPoint(0,0)); 

    CvSeq ptr = new CvSeq(); 

    int count =1; 
    CvPoint p1 = new CvPoint(0,0),p2 = new CvPoint(0,0); 

    for (ptr = contours; ptr != null; ptr = ptr.h_next()) { 

     CvScalar color = CvScalar.BLUE; 
     CvRect sq = cvBoundingRect(ptr, 0); 

      System.out.println("Contour No ="+count); 
      System.out.println("X ="+ sq.x()+" Y="+ sq.y()); 
      System.out.println("Height ="+sq.height()+" Width ="+sq.width()); 
      System.out.println(""); 

      p1.x(sq.x()); 
      p2.x(sq.x()+sq.width()); 
      p1.y(sq.y()); 
      p2.y(sq.y()+sq.height()); 
      cvRectangle(img, p1,p2, CV_RGB(255, 0, 0), 2, 8, 0); 
      cvDrawContours(img, ptr, color, CV_RGB(0,0,0), -1, CV_FILLED, 8, cvPoint(0,0)); 
      count++; 

    } 

    cvShowImage("contures",img); 
    cvWaitKey(0); 

Este es el resultado que obtuve para su imagen dada.

enter image description here

4

cvFindContours es la solución correcta a su problema.
Y he verificado que funciona en sus imágenes.
Here is my experiment

Tiene System.out.println dentro, ¿cuál es la salida?

cvFindContours podría ser difícil de usar, lo he envuelto en un more general C++ function. También utilizo un class called vBlob para describir un objeto cvFindContours detecta. Por lo que veo en tu código java, la versión java API es muy similar a la versión C/C++. Entonces no será difícil reescribirlo.

ps. Astor dio la respuesta correcta.

4

Sabía usted que findContours función encuentra blancos contornos en negro fondo?

Simplemente haga bitwise_not (o análogo en JavaCV) a su imagen y después de esto aplique findContours. Esto es realmente una solución a su problema.

4

¡No necesita bibliotecas de terceros! Lo que se busca se puede lograr en OpenCV usando una técnica conocida como bounding box:

enter image description here

El truco es usar cvFindContours() para recuperar los contornos y luego cvApproxPoly() para mejorar el resultado. Observe que tendrá que invertir los colores de la imagen de entrada usando cvNot() porque cvFindContours() busca contornos blancos.

  • Hay una buena introducción a los contornos en this post.
  • Hay un Java demo que implementa una versión del cuadro delimitador para detectar matrículas de automóviles.

Por cierto cvMinEnclosingCircle() devuelve el centro del círculo como CvPoint2D32f.

+0

¿Leíste un código de la pregunta y, de hecho, la pregunta en sí? Él ya sabe cómo encontrar el cuadro delimitador. ¿Y cómo mejora 'approxPoly' en esta situación? El problema es que topicstarter no entiende por qué obtiene 1 rectángulo en lugar de 4. Y ya expliqué por qué. – ArtemStorozhuk

+1

@Astor, no debes discutir con karlphillip, al menos por cortesía, si no por una razón mejor. Ya sabes, siempre debes respetar a tus mayores. Y él es el mayor aquí, en la etiqueta opencv;) Es como decirle a Jon Skeet que su código no compila – Sam

2

Estoy usando C++ api pero creo que también debería haber alguna función en javacv llamada drawContours o cvDrawContours que use la salida de findContours.

+0

Pero la salida de findContours es una imagen completa. – ArtemStorozhuk

Cuestiones relacionadas