Detección de objetos sencilla mediante OpenCV y aprendizaje automático


Tengo que codificar un detector de objetos (en este caso, una bola) usando OpenCV. El problema es que cada búsqueda en Google me devuelve algo con DETECCIÓN DE ROSTROS. Así que necesito ayuda sobre por dónde empezar, qué usar, etc..

Algo de información:

  • La bola no tiene un color fijo, probablemente será blanca, pero podría cambiar.
  • TENGO que usar el aprendizaje automático, no tiene que ser complejo y confiable, la sugerencia es KNN (que es mucho más simple y sencillo).
  • Después de toda mi búsqueda, descubrí que calcular el histograma de las muestras de imágenes de solo bolas y enseñarlas al ML podría ser útil, pero mi principal preocupación aquí es que el tamaño de la bola puede y cambiará (más cerca y más lejos de la cámara) y no tengo idea de qué pasar al ML para clasificar por mí, quiero decir.. no puedo (o puedo?) simplemente pruebe cada píxel de la imagen para cada tamaño posible (desde, digamos, 5x5 a WxH) y espere encontrar un resultado positivo.
  • Podría ser un fondo no uniforme, como personas, tela detrás de la bola y etc..
  • Como dije, tengo que usar un algoritmo ML, eso significa que no hay algoritmos Haar o Viola.
  • Además, pensé en usar contornos para encontrar círculos en una imagen Canny'ed, solo tengo que encontrar una manera de transformar un contorno en una fila de datos para enseñar el KNN.

    So... sugerencias?

    Gracias de antemano. ;)

Author: karlphillip, 2011-06-20

1 answers

Bueno, básicamente necesitas detectar círculos. Has visto cvHoughCircles()? ¿Se le permite usarlo?

Esta página tiene buena información sobre cómo detectar cosas con OpenCV. Puede estar más interesado en sección 2.5.

Esta es una pequeña demostración que acabo de escribir para detectar monedas en esta imagen. Esperemos que pueda utilizar alguna parte del código para su ventaja.

Entrada : entrada img

Salidas: salida opencv img

// compiled with: g++ circles.cpp -o circles `pkg-config --cflags --libs opencv`
#include <stdio.h>
#include <cv.h>
#include <highgui.h>
#include <math.h>

int main(int argc, char** argv)
{
    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, 7);

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

    CvSeq* circles = cvHoughCircles(gray, storage, CV_HOUGH_GRADIENT, 1, gray->height/3, 250, 100);
    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);

    return 0;
}

La detección de la los círculos dependen mucho de los parámetros de cvHoughCircles(). Tenga en cuenta que en esta demo he utilizado Canny también.

 33
Author: karlphillip,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-06-20 20:24:32