web-dev-qa-db-fra.com

Détection d'objets simple à l'aide d'OpenCV et de l'apprentissage automatique

Je dois coder un détecteur d'objets (dans ce cas, une balle) en utilisant OpenCV. Le problème est que chaque recherche sur google me renvoie quelque chose avec DÉTECTION DU VISAGE. J'ai donc besoin d'aide pour savoir par où commencer, quoi utiliser, etc.

Quelques informations:

  • La balle n'a pas de couleur fixe, elle sera probablement blanche, mais elle pourrait changer.
  • JE DOIS utiliser l'apprentissage automatique, ne doit pas être complexe et fiable, la suggestion est KNN (qui est BEAUCOUP plus simple et plus facile).
  • Après toutes mes recherches, j'ai trouvé que calculer l'histogramme d'échantillons d'images de balle uniquement et l'enseigner au ML pourrait être utile, mais ma principale préoccupation ici est que la taille de la balle peut et va changer (de plus en plus loin de la caméra) et je n'ai aucune idée de ce qu'il faut passer au ML pour classer pour moi, je veux dire .. je ne peux pas (ou puis-je?) juste tester chaque pixel de l'image pour toutes les tailles possibles (de, disons, 5x5 à WxH ) et espérons trouver un résultat positif.
  • Il peut y avoir un arrière-plan non uniforme, comme des gens, du tissu derrière le ballon et etc.
  • Comme je l'ai dit, je dois utiliser un algorithme ML, ce qui signifie qu'il n'y a pas d'algorithme Haar ou Viola.
  • Aussi, j'ai pensé à utiliser des contours pour trouver des cercles sur une image Canny'ed, il suffit de trouver un moyen de transformer un contour en une ligne de données pour enseigner le KNN.

    Alors ... des suggestions?

    Merci d'avance. ;)

25
hfingler

Eh bien, fondamentalement, vous devez détecter les cercles . Avez-vous vu cvHoughCircles()? Êtes-vous autorisé à l'utiliser?

Cette page contient de bonnes informations sur la façon dont détection de choses avec OpenCV . Vous pourriez être plus intéressé par section 2.5 .

Ceci est une petite démo que je viens d'écrire pour détecter les pièces sur cette photo. J'espère que vous pourrez utiliser une partie du code à votre avantage.

Entrée input img

Sorties output 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 détection des cercles dépend beaucoup des paramètres de cvHoughCircles(). Notez que dans cette démo, j'ai également utilisé Canny.

36
karlphillip