9
votes

Algorithme de suivi BLOB

J'essaie de créer un suivi de blob simple à l'aide d'OpenCV. J'ai détecté les blobs à l'aide de FindContours. Je voudrais donner à ces blobs un identifiant constant.

J'ai collecté une liste de blobs dans la trame précédente et le cadre actuel. Ensuite, j'ai pris la distance entre chaque blob dans la trame précédente et le cadre actuel. Je voudrais savoir quoi d'autre est nécessaire pour suivre les blobs et leur donner un identifiant. Je viens de prendre la distance entre les blobs de cadre antérieurs et actuels, mais comment puis-je affecter le blob d'un identifiant cohérent à l'aide de la distance mesurée entre les blobs?


1 commentaires

Pouvez-vous illustrer votre question s'il vous plaît?


3 Réponses :


9
votes

Dans la première image, vous pouvez attribuer id aucune façon, 1 pour la première que vous trouverez, 2 pour le deuxième ... ou simplement donner leur ID en fonction de leur position dans la collection.

Ensuite, sur le cadre suivant, vous devrez utiliser meilleur match. Trouvez les blobs, calculer toutes les distances entre les blobs en cours et tous les blobs de l'image précédente et attribuer à chaque ID précédent à la blob le plus proche. Blobs qui entrent dans le champ juste auront de nouveaux ID.

Maintenant, vous avez deux cadres, vous pouvez faire la prédiction de mouvement pour le prochain. Il suffit de calculer deltaX et deltaY entre la position précédente et actuelle du blob. Vous pouvez utiliser ces informations pour deviner la position future. Match contre cette position future.

Cela devrait fonctionner si vous avez pas beaucoup de blobs qui se chevauchent, et si le mouvement ne soit pas trop rapide et erratique entre chaque trame.

Il est possible d'être plus précis à l'aide d'un système de pointage creux plusieurs images:
Obtenez des positions pour les 3 ou 5 images. Pour toute goutte d'une trame, rechercher le plus proche sur le châssis 2, calculer la vitesse (deltaX deltaY), rechercher le plus proche de la position prédite pour la trame 3, 4, 5 ... Somme toutes distances entre positon prédite et les plus proches de blob il sera le score. Faites la même chose en utilisant la 2ème plus proche sur le châssis 2 (il cherchera dans une autre direction). Plus le score le plus probable de son bon blob.

Si vous avez beaucoup de blobs, vous devez utiliser un quadtree pour traiter speedup. Comparer la distance au carré; il évitera beaucoup de calculs sqrt.

Il est important de savoir comment votre blob déplacer pour régler votre typiquement algotrithm.


1 commentaires

Merci, voudriez-vous me donner plus d'explication par des exemples et des calculs ou des images? Je serais très heureux de comprendre ce processus. Ou vous pouvez me montrer une référence pour ça



3
votes

Voici un échantillon de code OPENCV de Blob Suivi:

#include "stdafx.h"

#include <opencv2\opencv.hpp>

IplImage* GetThresholdedImage(IplImage* img)
{
    // Convert the image into an HSV image
    IplImage* imgHSV = cvCreateImage(cvGetSize(img), 8, 3);
    cvCvtColor(img, imgHSV, CV_BGR2HSV);

    IplImage* imgThreshed = cvCreateImage(cvGetSize(img), 8, 1);

    // Values 20,100,100 to 30,255,255 working perfect for yellow at around 6pm
    cvInRangeS(imgHSV, cvScalar(112, 100, 100), cvScalar(124, 255, 255), imgThreshed);

    cvReleaseImage(&imgHSV);

    return imgThreshed;
}

int main()
{
    // Initialize capturing live feed from the camera
    CvCapture* capture = 0;
    capture = cvCaptureFromCAM(0);  

    // Couldn't get a device? Throw an error and quit
    if(!capture)
    {
        printf("Could not initialize capturing...\n");
        return -1;
    }

    // The two windows we'll be using
    cvNamedWindow("video");
    cvNamedWindow("thresh");

    // This image holds the "scribble" data...
    // the tracked positions of the ball
    IplImage* imgScribble = NULL;

    // An infinite loop
    while(true)
    {
        // Will hold a frame captured from the camera
        IplImage* frame = 0;
        frame = cvQueryFrame(capture);

        // If we couldn't grab a frame... quit
        if(!frame)
            break;

        // If this is the first frame, we need to initialize it
        if(imgScribble == NULL)
        {
            imgScribble = cvCreateImage(cvGetSize(frame), 8, 3);
        }

        // Holds the yellow thresholded image (yellow = white, rest = black)
        IplImage* imgYellowThresh = GetThresholdedImage(frame);

        // Calculate the moments to estimate the position of the ball
        CvMoments *moments = (CvMoments*)malloc(sizeof(CvMoments));
        cvMoments(imgYellowThresh, moments, 1);

        // The actual moment values
        double moment10 = cvGetSpatialMoment(moments, 1, 0);
        double moment01 = cvGetSpatialMoment(moments, 0, 1);
        double area = cvGetCentralMoment(moments, 0, 0);

        // Holding the last and current ball positions
        static int posX = 0;
        static int posY = 0;

        int lastX = posX;
        int lastY = posY;

        posX = moment10/area;
        posY = moment01/area;

        // Print it out for debugging purposes
        printf("position (%d,%d)\n", posX, posY);

        // We want to draw a line only if its a valid position
        if(lastX>0 && lastY>0 && posX>0 && posY>0)
        {
            // Draw a yellow line from the previous point to the current point
            cvLine(imgScribble, cvPoint(posX, posY), cvPoint(lastX, lastY), cvScalar(0,255,255), 5);
        }

        // Add the scribbling image and the frame... and we get a combination of the two
        cvAdd(frame, imgScribble, frame);
        cvShowImage("thresh", imgYellowThresh);
        cvShowImage("video", frame);

        // Wait for a keypress
        int c = cvWaitKey(10);
        if(c!=-1)
        {
            // If pressed, break out of the loop
            break;
        }

        // Release the thresholded image... we need no memory leaks.. please
        cvReleaseImage(&imgYellowThresh);

        delete moments;
    }

    // We're done using the camera. Other applications can now use it
    cvReleaseCapture(&capture);
    return 0;
}


0 commentaires

1
votes

u Peut utiliser CVBLOBSLIB bibliothèque pour la détection de blob ...

  1. Si votre mouvement BLOB inter-cadre est inférieur à la distance inter-blob..That est un déplacement de blob est inférieur à la distance inter blob, vous pouvez créer une liste et continuer à ajouter le blob dans chaque cadre actuel qui tombe dans le quartier des blobs dans la trame précédente ...
  2. Si vos blobs ont des fonctions constantes telles que l'ellipticité ... Ratio de format (après avoir monté une boîte de sélection), vous pouvez regrouper les blobs avec ces fonctionnalités dans une liste ..

0 commentaires